Wenn ein Teil von defun,
(interactive "c(C)hoose (A)n (O)ption")
fordert den Benutzer zur Eingabe eines einzelnen Zeichens auf; RETist nicht nötig. Wie kann ich dieses Leseverhalten replizieren, ohne dass dies erforderlich ist interactive?
Wenn ein Teil von defun,
(interactive "c(C)hoose (A)n (O)ption")
fordert den Benutzer zur Eingabe eines einzelnen Zeichens auf; RETist nicht nötig. Wie kann ich dieses Leseverhalten replizieren, ohne dass dies erforderlich ist interactive?
Antworten:
Zusätzlich zu den integrierten Möglichkeiten zum Lesen einzelner Ereignisse wie read-charund read-char-exclusivekönnen Sie hier ein einzelnes Zeichen lesen, aber auch angeben, welche Zeichen als Eingabe zulässig sind:
(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)))
Alle folgenden Optionen akzeptieren entweder "C", "A" oder "O":
(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))
Und hier ist ein Beispiel für eine Schleife für die korrekte Eingabe in eine responseVariable:
(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)
read-char-choiceeinen, der einen bestimmten Zeichensatz liest.
Die Frage wurde vor langer Zeit beantwortet, aber diese zusätzliche Antwort kann anderen Suchenden helfen.
read-char-choiceMit dieser Option können Sie eine Liste mit Auswahlmöglichkeiten angeben. Das fn wird erst zurückgegeben, wenn der Benutzer eine dieser gültigen Optionen ausgewählt hat.
(read-char-choice "prompt here (A, B, or C)? " '(?A ?B ?C))
In dem entarteten Fall, in dem die Optionen einfach Y oder N sind (case insenstive), gibt es y-or-n-p.
Beide read-char-choiceund y-or-n-psind starr und bestehen auf einer gültigen Antwort. Im ersten Fall muss es eine der von Ihnen angegebenen Optionen sein (wie in meinem Beispiel A, B oder C), und im zweiten Fall muss es Y oder N sein. Wenn der Benutzer die Eingabetaste oder eine andere Taste drückt, y-or-n-pwird er erneut gefragt. Der read-char-choicewird einfach still da sitzen. Beides bietet keine Möglichkeit, nur einen Standardwert zurückzugeben. Ich denke, um dieses Verhalten zu erreichen, müssen Sie Ihre eigene Interaktion mit read-charoder aufbauen read-key.
Nach meiner Erfahrung besteht das Problem mit read-charund read-keyallein darin, dass der Cursor im Hauptbearbeitungspuffer verbleibt, während die Eingabeaufforderung im Minibuffer angezeigt wird. Dies ist für den Benutzer desorientiert und unterscheidet sich auch vom Verhalten von read-string.
Um dies zu vermeiden, können Sie die Variable cursor-in-echo-areavor dem Aufruf read-keyden Cursor im Minibuffer anzeigen lassen.
(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)))
read-char-choice