emacs-diffs
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

master 04ab674: Add CHARS arg to read-char-from-minibuffer compatible wi


From: Juri Linkov
Subject: master 04ab674: Add CHARS arg to read-char-from-minibuffer compatible with read-char-choice.
Date: Sat, 9 Nov 2019 17:21:34 -0500 (EST)

branch: master
commit 04ab67470706f1c66bdf08e4078ea3dffd79b41e
Author: Juri Linkov <address@hidden>
Commit: Juri Linkov <address@hidden>

    Add CHARS arg to read-char-from-minibuffer compatible with read-char-choice.
    
    * lisp/simple.el (read-char-history):
    Rename from read-char-from-minibuffer-history.  (Bug#38076)
    (read-char-from-minibuffer-insert-char):
    Rename from read-char-from-minibuffer-self-insert.
    (read-char-from-minibuffer-map-hash): New defconst.
    (read-char-from-minibuffer-insert-other): New command.
    (read-char-from-minibuffer): Add optional args CHARS and HISTORY.
    (zap-to-char): Use 'read-char-history as HISTORY arg of
    read-char-from-minibuffer.
    
    * lisp/emacs-lisp/map-ynp.el (read-answer): Use sit-for instead of 
sleep-for.
    Replace short answer history yes-or-no-p-history with read-char-history.
---
 lisp/emacs-lisp/map-ynp.el |  6 ++--
 lisp/simple.el             | 79 ++++++++++++++++++++++++++++++++++------------
 2 files changed, 61 insertions(+), 24 deletions(-)

diff --git a/lisp/emacs-lisp/map-ynp.el b/lisp/emacs-lisp/map-ynp.el
index a688330..5c0e28e 100644
--- a/lisp/emacs-lisp/map-ynp.el
+++ b/lisp/emacs-lisp/map-ynp.el
@@ -341,7 +341,7 @@ When `use-dialog-box' is t, pop up a dialog window to get 
user input."
                                (delete-minibuffer-contents)
                                (beep)
                                (message message)
-                               (sleep-for 2)))
+                               (sit-for 2)))
                            map)
                          read-answer-map--memoize))))
          answer)
@@ -361,7 +361,7 @@ When `use-dialog-box' is t, pop up a dialog window to get 
user input."
                                       (short
                                        (read-from-minibuffer
                                         prompt nil short-answer-map nil
-                                        'yes-or-no-p-history))
+                                        'read-char-history))
                                       (t
                                        (read-from-minibuffer
                                         prompt nil nil nil
@@ -381,7 +381,7 @@ When `use-dialog-box' is t, pop up a dialog window to get 
user input."
                       ".\n")))
         (beep)
         (message message)
-        (sleep-for 2)))
+        (sit-for 2)))
     answer))
 
 ;;; map-ynp.el ends here
diff --git a/lisp/simple.el b/lisp/simple.el
index 6677291..6dc4e56 100644
--- a/lisp/simple.el
+++ b/lisp/simple.el
@@ -5174,46 +5174,83 @@ and KILLP is t if a prefix arg was specified."
     ;; Avoid warning about delete-backward-char
     (with-no-warnings (delete-backward-char n killp))))
 
-(defvar read-char-from-minibuffer-history nil
+(defvar read-char-history nil
   "The default history for the `read-char-from-minibuffer' function.")
 
 (defvar read-char-from-minibuffer-map
   (let ((map (make-sparse-keymap)))
     (set-keymap-parent map minibuffer-local-map)
     (define-key map [remap self-insert-command]
-      'read-char-from-minibuffer-self-insert)
+      'read-char-from-minibuffer-insert-char)
     map)
   "Keymap for the `read-char-from-minibuffer' function.")
 
-(defun read-char-from-minibuffer-self-insert ()
-  "Insert the character you type in the minibuffer."
+(defconst read-char-from-minibuffer-map-hash
+  (make-hash-table :weakness 'key :test 'equal))
+
+(defun read-char-from-minibuffer-insert-char ()
+  "Insert the character you type in the minibuffer and exit.
+Discard all previous input before inserting and exiting the minibuffer."
   (interactive)
   (delete-minibuffer-contents)
-  (insert (event-basic-type last-command-event))
+  (insert last-command-event)
   (exit-minibuffer))
 
-(defun read-char-from-minibuffer (prompt)
-  "Read a character from the minibuffer, prompting with string PROMPT.
-Like `read-char', but allows navigating in a history.  The navigation
-commands are `M-p' and `M-n', with `RET' to select a character from
-history."
-  (let ((result
-         (read-from-minibuffer prompt nil
-                               read-char-from-minibuffer-map nil
-                               'read-char-from-minibuffer-history)))
-    (if (> (length result) 0)
-        ;; We have a string (with one character), so return the first one.
-        (elt result 0)
-      ;; The default value is RET.
-      (push "\r" read-char-from-minibuffer-history)
-      ?\r)))
+(defun read-char-from-minibuffer-insert-other ()
+  "Handle inserting of a character other than allowed.
+Display an error on trying to insert a disallowed character.
+Also discard all previous input in the minibuffer."
+  (interactive)
+  (delete-minibuffer-contents)
+  (ding)
+  (minibuffer-message "Wrong answer")
+  (sit-for 2))
+
+(defvar empty-history)
+
+(defun read-char-from-minibuffer (prompt &optional chars history)
+  "Read a character from the minibuffer, prompting for PROMPT.
+Like `read-char', but uses the minibuffer to read and return a character.
+When CHARS is non-nil, any input that is not one of CHARS is ignored.
+When HISTORY is a symbol, then allows navigating in a history.
+The navigation commands are `M-p' and `M-n', with `RET' to select
+a character from history."
+  (discard-input)
+  (let* ((empty-history '())
+         (map (if (consp chars)
+                  (or (gethash chars read-char-from-minibuffer-map-hash)
+                      (puthash chars
+                               (let ((map (make-sparse-keymap)))
+                                 (set-keymap-parent map 
read-char-from-minibuffer-map)
+                                 (dolist (char chars)
+                                   (define-key map (vector char)
+                                     'read-char-from-minibuffer-insert-char))
+                                 (define-key map [remap self-insert-command]
+                                   'read-char-from-minibuffer-insert-other)
+                                 map)
+                               read-char-from-minibuffer-map-hash))
+                read-char-from-minibuffer-map))
+         (result
+          (read-from-minibuffer prompt nil map nil
+                                (or history 'empty-history)))
+         (char
+          (if (> (length result) 0)
+              ;; We have a string (with one character), so return the first 
one.
+              (elt result 0)
+            ;; The default value is RET.
+            (when history (push "\r" (symbol-value history)))
+            ?\r)))
+    ;; Display the question with the answer.
+    (message "%s%s" prompt (char-to-string char))
+    char))
 
 (defun zap-to-char (arg char)
   "Kill up to and including ARGth occurrence of CHAR.
 Case is ignored if `case-fold-search' is non-nil in the current buffer.
 Goes backward if ARG is negative; error if CHAR not found."
   (interactive (list (prefix-numeric-value current-prefix-arg)
-                    (read-char-from-minibuffer "Zap to char: ")))
+                    (read-char-from-minibuffer "Zap to char: "
+                                               nil 'read-char-history)))
   ;; Avoid "obsolete" warnings for translation-table-for-input.
   (with-no-warnings
     (if (char-table-p translation-table-for-input)



reply via email to

[Prev in Thread] Current Thread [Next in Thread]