如何从小型缓冲区读取单个字符?


12

当属于时defun

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

将提示用户输入单个字符;RET不需要。我该如何复制这种阅读行为而不需要interactive

Answers:


7

而不是read-char我推荐read-key。不同之处在于,它read-key遵循所有常规重映射,例如input-decode-mapfunction-key-map,因此它将在tty中正常工作。


另一个答案中的信息配对,这似乎是所问问题的最精确答案:) glucas的评论虽然提供了很好的功能:)read-char-choice
Sean Allred

5

除了读取诸如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)

2
还有read-char-choice一个读取给定字符集之一。
glucas 2014年

@glucas:啊,疯了,你是对的。好像我重新发明了轮子。

4

call-interactively是解释(interactive "cPROMPT")规范的内容,将c选项发送到read-char。因此,以下内容应在非交互式上下文中起作用:

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

3

这个问题早在很早以前就已经回答了,但是这个额外的答案可能会为其他搜索者提供一些帮助。

read-char-choice允许您指定选项列表。在用户选择这些有效选项之一之前,fn不会返回。

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

在简并的情况下,选项仅是Y或N(不区分大小写),则存在y-or-n-p

这两个read-char-choicey-or-n-p是刚性的,并坚持有效的答案。在前一种情况下,它必须是您指定的选项之一(例如在我的示例中为A,B或C),在后一种情况下,它必须是Y或N。如果用户按下Enter键或其他任何键,y-or-n-p它将再次询问。该read-char-choice会只是坐在那里,沉默不语。两者都没有提供仅返回默认值的方法。要获得这种行为,我认为您必须与read-char或建立自己的互动read-key

在我的经验,问题read-charread-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)))
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.