help-gnu-emacs
[Top][All Lists]
Advanced

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

Re: How to read an integer from the minibuffer


From: Gregory Heytings
Subject: Re: How to read an integer from the minibuffer
Date: Thu, 11 Nov 2021 14:30:11 +0000



Cool (honestly). But do show how to use that to read an integer and only an integer ...


You mean, how these two answers can be combined?

(defun restricted-read-from-minibuffer (prompt regexp &optional allowed-chars)
  "Read a string from the minibuffer, with additional constraints.
If the input does not match REGEXP, read a string again.
If ALLOWED-CHARS is a string, the only allowed characters are those in
that string."
  (let ((map nil)
        (string nil))
    (when (stringp allowed-chars)
      (let ((m (make-keymap)))
        (define-key m [t]
                    (lambda ()
                      (interactive)
                      (message "Character not allowed")))
        (define-key m (kbd "RET") #'exit-minibuffer)
        (define-key m (kbd "<return>") #'exit-minibuffer)
        (define-key m (kbd "C-j") #'exit-minibuffer)
        (define-key m (kbd "C-g") #'abort-minibuffers)
        (dolist (c (split-string allowed-chars "" t))
          (define-key m c #'self-insert-command))
        (setq map m)))
    (while (progn
             (setq string (read-from-minibuffer prompt nil map))
             (when regexp
               (unless (string-match regexp string nil t)
                 (message "Unexpected input.")
                 (sit-for 1)
                 t))))
    string))

With this,

(restricted-read-from-minibuffer "Integer? " "^[0-9][0-9]*$" "0123456789")

will read "an integer and only an integer". And you can wrap it into a string-to-number to get the integer itself.

(BTW, it seems that there's no way in Elisp to "expand" a regexp charset, e.g. "[0-9]" into "0123456789". That would make the ALLOWED-CHARS argument easier to type in.)



reply via email to

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