Minibuffer'dan tek bir karakteri nasıl okuyabilirim?


12

Bir parçası olduğunda defun,

(interactive "c(C)hoose (A)n (O)ption")

kullanıcıdan tek bir karakter girmesini ister; RETgerekli değil. Bu okuma davranışına ihtiyaç duymadan nasıl çoğaltabilirim interactive?

Yanıtlar:


7

read-charBen tavsiye yerine read-key. Fark olmasıdır read-keyitaat her zamanki gibi remappings input-decode-mapve function-key-mapbu uçbirimlerden düzgün çalışacaktır böylece.


Başka bir cevaptaki bilgilerle eşleştirildiğinde , bu sorulan soruya en kesin cevap gibi görünüyor :) glucas'ın yorumu olsa da iyi bir işlev sağlıyor :)read-char-choice
Sean Allred

5

Ek olarak dahili tek olayları okumak için yollar gibi read-charve read-char-exclusiveburada tek bir karakter okumak için bir seçenek, ama aynı zamanda kabul edilebilir girdi hangi karakterler belirtin:

(defun read-char-picky (prompt chars &optional inherit-input-method seconds)
  "Read characters like in `read-char-exclusive', but if input is
not one of CHARS, return nil.  CHARS may be a list of characters,
single-character strings, or a string of characters."
  (let ((chars (mapcar (lambda (x)
                         (if (characterp x) x (string-to-char x)))
                       (append chars nil)))
        (char  (read-char-exclusive prompt inherit-input-method seconds)))
    (when (memq char chars)
      char)))

Dolayısıyla, aşağıdakilerin tümü "C", "A" veya "O" kabul eder:

(read-char-picky "(C)hoose (A)n (O)ption: " "CAO")
(read-char-picky "(C)hoose (A)n (O)ption: " '("C" "A" "O"))
(read-char-picky "(C)hoose (A)n (O)ption: " '(?C ?A ?O))

Ve bir responsedeğişkene doğru girdi için döngü oluşturmanın örnek bir yolu :

(let (response)
  (while (null (setq response
                     (read-char-picky "(C)hoose (A)n (O)ption: " "CAO")))
    (message "Please pick one of \"C\", \"A\", or \"O\"!")
    (sit-for .5))
  response)

2
Ayrıca read-char-choicebelirli bir karakter kümesinden birini okuyanlar da vardır.
glucas

@glucas: ah, fındıklar, haklısın. Görünüşe göre tekerleği yeniden icat ettim.
Dan

4

call-interactively(interactive "cPROMPT")şartnameyi yorumlayan şey , cseçeneğe gönderilir read-char. Bu nedenle, aşağıdakiler etkileşimli olmayan bir bağlamda çalışmalıdır:

(read-char "(C)hoose (A)n (O)ption")

4

Soru uzun zaman önce cevaplandı, ancak bu ek cevap diğer araştırmacılara biraz yardım sağlayabilir.

read-char-choicebir seçenek listesi belirlemenizi sağlar. Fn, kullanıcı bu geçerli seçeneklerden birini seçinceye kadar geri dönmez.

(read-char-choice "prompt here (A, B, or C)? " '(?A ?B ?C))

Seçeneklerin sadece Y veya N (dezenfekte edici) olduğu dejenere durumda vardır y-or-n-p.

Hem read-char-choiceve y-or-n-psert olan ve geçerli bir cevap ısrar ediyorlar. Önceki durumda, belirttiğiniz seçeneklerden biri olmalıdır (örneğimde A, B veya C gibi) ve ikinci durumda Y veya N olmalıdır. Kullanıcı enter veya başka bir tuşa basarsa, y-or-n-ptekrar sorulur. read-char-choiceSadece sessiz, orada oturacak. İkisi de varsayılana dönmenin bir yolunu sunmaz. Bu davranışı elde etmek için, sanırım read-charveya ile kendi etkileşiminizi kurmalısınız read-key.

Benim tecrübelerime göre, read-charve read-keytek başına sorun , minibuffer'da istemi görüntülerken, imlecin ana düzenleme arabelleğinde kalmasıdır. Bu kullanıcı için yönünü şaşırtır ve aynı zamanda davranışlarından farklıdır read-string.

Bunu önlemek için, çağrmadan cursor-in-echo-areaönce değişkenin read-keyimleci minibuffer'da görüntülemesine izin verebilirsiniz .

(defun my-y-or-n-with-default (raw-prompt &optional default-yes)
  "displays PROMPT in the minibuffer, prompts for a y or n,
returns t or nil accordingly. If neither Y or N is entered, then
if DEFAULT-YES, returns t, else nil."
  (let* ((options-string (if default-yes "Y or n" "y or N"))
         (prompt (concat raw-prompt "(" options-string ")? "))
         (cursor-in-echo-area t)
         (key (read-key (propertize prompt 'face 'minibuffer-prompt)))
         (isyes (or (eq key ?y) (eq key ?Y)))
         (isno (or (eq key ?n) (eq key ?N))))
    (if (not (or isyes isno))
        default-yes
      isyes)))
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.