Lorsqu'elle fait partie d'un defun
,
(interactive "c(C)hoose (A)n (O)ption")
demandera à l'utilisateur un seul caractère; RET
n'est pas requis. Comment puis-je reproduire ce comportement de lecture sans avoir besoin de interactive
?
Lorsqu'elle fait partie d'un defun
,
(interactive "c(C)hoose (A)n (O)ption")
demandera à l'utilisateur un seul caractère; RET
n'est pas requis. Comment puis-je reproduire ce comportement de lecture sans avoir besoin de interactive
?
Réponses:
En plus des moyens intégrés de lire des événements uniques tels que read-char
et read-char-exclusive
, voici une option pour lire un seul caractère, mais spécifiez également quels caractères sont des entrées acceptables:
(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)))
Ainsi, tous les éléments suivants accepteront "C", "A" ou "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))
Et voici un exemple de boucle pour l'entrée correcte dans une response
variable:
(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-choice
qui lit l'un d'un ensemble de caractères donné.
La question a été répondue il y a longtemps, mais cette réponse supplémentaire peut fournir une aide aux autres chercheurs.
read-char-choice
vous permet de spécifier une liste de choix. Le fn ne reviendra que lorsque l'utilisateur aura sélectionné l'une de ces options valides.
(read-char-choice "prompt here (A, B, or C)? " '(?A ?B ?C))
Dans le cas dégénéré où les options sont simplement Y ou N (insensible à la casse), il y en a y-or-n-p
.
Les deux read-char-choice
et y-or-n-p
sont rigides, et d' insister sur une réponse valable. Dans le premier cas, il doit être l'une des options que vous spécifiez (comme A, B ou C dans mon exemple), et dans ce dernier cas, il doit être Y ou N. Si l'utilisateur appuie sur Entrée ou sur toute autre touche, le y-or-n-p
demande à nouveau. La read-char-choice
volonté restera assise là, silencieuse. Aucun des deux ne permet de renvoyer simplement une valeur par défaut. Pour obtenir ce comportement, je pense que vous devez créer votre propre interaction avec read-char
ou read-key
.
D'après mon expérience, le problème avec read-char
et read-key
seul, c'est que pendant qu'ils affichent l'invite dans le mini-tampon, le curseur reste dans le tampon d'édition principal. Cela désoriente l'utilisateur et est également différent du comportement de read-string
.
Pour éviter cela, vous pouvez laisser la variable cursor-in-echo-area
avant d'appeler read-key
pour afficher le curseur dans le mini-tampon.
(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