Answers:
除了读取诸如read-char
和的单个事件的内置方法之外read-char-exclusive
,这里还有一个读取单个字符的选项,还可以指定可接受的字符:
(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)))
因此,以下所有内容都将接受“ C”,“ A”或“ 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))
这是循环将正确输入输入response
变量的示例方法:
(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
一个读取给定字符集之一。
这个问题早在很早以前就已经回答了,但是这个额外的答案可能会为其他搜索者提供一些帮助。
read-char-choice
允许您指定选项列表。在用户选择这些有效选项之一之前,fn不会返回。
(read-char-choice "prompt here (A, B, or C)? " '(?A ?B ?C))
在简并的情况下,选项仅是Y或N(不区分大小写),则存在y-or-n-p
。
这两个read-char-choice
和 y-or-n-p
是刚性的,并坚持有效的答案。在前一种情况下,它必须是您指定的选项之一(例如在我的示例中为A,B或C),在后一种情况下,它必须是Y或N。如果用户按下Enter键或其他任何键,y-or-n-p
它将再次询问。该read-char-choice
会只是坐在那里,沉默不语。两者都没有提供仅返回默认值的方法。要获得这种行为,我认为您必须与read-char
或建立自己的互动read-key
。
在我的经验,问题read-char
和read-key
孤独,是,虽然他们显示提示在minibuffer,光标停留在主编辑缓冲区。这会使用户感到迷惑,也不同于的行为read-string
。
为避免这种情况,可以cursor-in-echo-area
在调用之前让变量在read-key
迷你缓冲区中显示光标。
(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