ミニバッファーから単一の文字を読み取るにはどうすればよいですか?


11

の一部である場合defun

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

ユーザーに単一の文字を要求します。RET必須ではありません。どのようにして、この読み取り動作を必要とせずに再現できinteractiveますか?

回答:


6

read-char私がお勧めするよりもread-key。違いは、and read-keyなどの通常の再マッピングすべてに従うため、ttyで適切に動作することです。input-decode-mapfunction-key-map


別の回答の情報と組み合わせると、これは尋ねられた質問に対する最も正確な回答のようです:) glucasのコメントは優れた機能を提供しますが:)read-char-choice
Sean Allred

5

andのような単一のイベントを読み取る組み込みの方法に加えて、単一の文字を読み取るオプションがありますが、どの文字が入力可能かを指定することもできます。read-charread-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特定の文字セットの1つを読み取るものもあります。
グルカ2014

@glucas:ああ、ナッツ、あなたは正しい。ホイールを再発明したようです。
ダン

4

call-interactively(interactive "cPROMPT")仕様を解釈するものであり、cオプションはにディスパッチされread-charます。したがって、以下は非インタラクティブなコンテキストで機能するはずです。

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

3

質問はずっと前に回答されましたが、この追加の回答は他の検索者に何らかの支援を提供する可能性があります。

read-char-choice選択肢のリストを指定できます。fnは、ユーザーがこれらの有効なオプションの1つを選択するまで戻りません。

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

オプションが単にYまたはN(大文字と小文字を区別しない)である縮退の場合、がありますy-or-n-p

read-char-choicey-or-n-pはどちらも厳格であり、有効な回答を要求します。前者の場合は、指定するオプションの1つ(この例ではA、B、またはCなど)である必要があり、後者の場合はYまたはNである必要があります。ユーザーがEnterキーまたはその他のキーを押すと、y-or-n-pは再度尋ねます。read-char-choiceただ静か、そこに座っます。どちらもデフォルトを返す方法を提供しません。その動作を得るために、私はあなたとあなた自身の相互作用を構築するために持っていると思いますread-charread-key

私の経験ではread-charread-key単独での問題は、ミニバッファーにプロンプ​​トが表示されている間、カーソルがメイン編集バッファーに残っていることです。これはユーザーの混乱を招き、またの動作とは異なり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)))
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.