aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLars Ingebrigtsen2016-02-04 19:51:54 +1100
committerLars Ingebrigtsen2016-02-04 19:52:07 +1100
commit4531b03ec98b50fc61baad2b75f6faf439894583 (patch)
tree480bd9f181799d8cf9dba26860360b57131820b9
parentd95c7bb472cd259661dfed41ccfe534f9026c826 (diff)
downloademacs-4531b03ec98b50fc61baad2b75f6faf439894583.tar.gz
emacs-4531b03ec98b50fc61baad2b75f6faf439894583.zip
New function read-multiple-choice
* doc/lispref/commands.texi (Reading One Event): Document read-multiple-choice. * lisp/faces.el (read-multiple-choice-face): New face. * lisp/subr.el (read-multiple-choice): New function.
-rw-r--r--doc/lispref/commands.texi21
-rw-r--r--etc/NEWS4
-rw-r--r--lisp/faces.el6
-rw-r--r--lisp/subr.el114
4 files changed, 145 insertions, 0 deletions
diff --git a/doc/lispref/commands.texi b/doc/lispref/commands.texi
index 9c1df895161..1964ec8e3fe 100644
--- a/doc/lispref/commands.texi
+++ b/doc/lispref/commands.texi
@@ -2617,6 +2617,27 @@ causes it to evaluate @code{help-form} and display the result. It
2617then continues to wait for a valid input character, or keyboard-quit. 2617then continues to wait for a valid input character, or keyboard-quit.
2618@end defun 2618@end defun
2619 2619
2620@defun read-multiple-choice prompt choices
2621Ask user a multiple choice question. @var{prompt} should be a string
2622that will be displayed as the prompt.
2623
2624@var{choices} is an alist where the first element in each entry is a
2625character to be entered, the second element is a short name for the
2626entry to be displayed while prompting (if there's room, it might be
2627shortened), and the third, optional entry is a longer explanation that
2628will be displayed in a help buffer if the user requests more help.
2629
2630The return value is the matching value from @var{choices}.
2631
2632@lisp
2633(read-multiple-choice
2634 "Continue connecting?"
2635 '((?a "always" "Accept this certificate this session and for all future sessions.")
2636 (?s "session only" "Accept this certificate this session only.")
2637 (?n "no" "Refuse to use this certificate, and close the connection.")))
2638@end lisp
2639@end defun
2640
2620@node Event Mod 2641@node Event Mod
2621@subsection Modifying and Translating Input Events 2642@subsection Modifying and Translating Input Events
2622@cindex modifiers of events 2643@cindex modifiers of events
diff --git a/etc/NEWS b/etc/NEWS
index 1f4f9895315..3b520ec50b1 100644
--- a/etc/NEWS
+++ b/etc/NEWS
@@ -283,6 +283,10 @@ selected window is strongly dedicated to its buffer.
283`even-window-sizes' and now handles window widths as well. 283`even-window-sizes' and now handles window widths as well.
284 284
285+++ 285+++
286** New function `read-multiple-choice' use to prompt for
287multiple-choice questions, with a handy way to display help texts.
288
289+++
286** terpri gets an optional arg ENSURE to conditionally output a newline. 290** terpri gets an optional arg ENSURE to conditionally output a newline.
287 291
288+++ 292+++
diff --git a/lisp/faces.el b/lisp/faces.el
index 612bd1677bb..d80a557feb5 100644
--- a/lisp/faces.el
+++ b/lisp/faces.el
@@ -2670,6 +2670,12 @@ It is used for characters of no fonts too."
2670 :version "24.1" 2670 :version "24.1"
2671 :group 'basic-faces) 2671 :group 'basic-faces)
2672 2672
2673(defface read-multiple-choice-face
2674 '((t (:inherit bold)))
2675 "Face for the symbol name in Apropos output."
2676 :group 'basic-faces
2677 :version "25.2")
2678
2673;; Faces for TTY menus. 2679;; Faces for TTY menus.
2674(defface tty-menu-enabled-face 2680(defface tty-menu-enabled-face
2675 '((t 2681 '((t
diff --git a/lisp/subr.el b/lisp/subr.el
index c685f95f56f..db1baf09c43 100644
--- a/lisp/subr.el
+++ b/lisp/subr.el
@@ -2233,6 +2233,120 @@ keyboard-quit events while waiting for a valid input."
2233 (message "%s%s" prompt (char-to-string char)) 2233 (message "%s%s" prompt (char-to-string char))
2234 char)) 2234 char))
2235 2235
2236(defun read-multiple-choice (prompt choices)
2237 "Ask user a multiple choice question.
2238PROMPT should be a string that will be displayed as the prompt.
2239
2240CHOICES is an alist where the first element in each entry is a
2241character to be entered, the second element is a short name for
2242the entry to be displayed while prompting (if there's room, it
2243might be shortened), and the third, optional entry is a longer
2244explanation that will be displayed in a help buffer if the user
2245requests more help.
2246
2247The return value is the matching entry from the CHOICES list.
2248
2249Usage example:
2250
2251\(read-multiple-choice \"Continue connecting?\"
2252 '((?a \"always\")
2253 (?s \"session only\")
2254 (?n \"no\")))"
2255 (let* ((altered-names nil)
2256 (full-prompt
2257 (format
2258 "%s (%s, ?): "
2259 prompt
2260 (mapconcat
2261 (lambda (elem)
2262 (let* ((name (cadr elem))
2263 (pos (seq-position name (car elem)))
2264 (altered-name
2265 (cond
2266 ;; Not in the name string.
2267 ((not pos)
2268 (format "[%c] %s" (car elem) name))
2269 ;; The prompt character is in the name, so highlight
2270 ;; it on graphical terminals...
2271 ((display-graphic-p)
2272 (setq name (copy-sequence name))
2273 (put-text-property pos (1+ pos)
2274 'face 'read-multiple-choice-face
2275 name)
2276 name)
2277 ;; And put it in [bracket] on non-graphical terminals.
2278 (t
2279 (concat
2280 (substring name 0 pos)
2281 "["
2282 (upcase (substring name pos (1+ pos)))
2283 "]"
2284 (substring name (1+ pos)))))))
2285 (push (cons (car elem) altered-name)
2286 altered-names)
2287 altered-name))
2288 choices ", ")))
2289 tchar buf)
2290 (save-window-excursion
2291 (save-excursion
2292 (while (not tchar)
2293 (message "%s" full-prompt)
2294 (setq tchar (condition-case nil
2295 (read-char)
2296 (error nil)))
2297 ;; The user has entered an invalid choice, so display the
2298 ;; help messages.
2299 (when (not (assq tchar choices))
2300 (setq tchar nil)
2301 (with-help-window (setq buf (get-buffer-create
2302 "*Multiple Choice Help*"))
2303 (with-current-buffer buf
2304 (erase-buffer)
2305 (pop-to-buffer buf)
2306 (insert prompt "\n\n")
2307 (let* ((columns (/ (window-width) 25))
2308 (fill-column 21)
2309 (times 0)
2310 (start (point)))
2311 (dolist (elem choices)
2312 (goto-char start)
2313 (unless (zerop times)
2314 (if (zerop (mod times columns))
2315 ;; Go to the next "line".
2316 (goto-char (setq start (point-max)))
2317 ;; Add padding.
2318 (while (not (eobp))
2319 (end-of-line)
2320 (insert (make-string (- (* (mod times columns)
2321 (+ fill-column 4))
2322 (current-column))
2323 ?\s))
2324 (forward-line 1))))
2325 (setq times (1+ times))
2326 (let ((text
2327 (with-temp-buffer
2328 (insert (format
2329 "%c: %s\n"
2330 (car elem)
2331 (cdr (assq (car elem) altered-names))))
2332 (fill-region (point-min) (point-max))
2333 (when (nth 2 elem)
2334 (insert (nth 2 elem))
2335 (unless (bolp)
2336 (insert "\n"))
2337 (fill-region start (point-max)))
2338 (buffer-string))))
2339 (goto-char start)
2340 (dolist (line (split-string text "\n"))
2341 (end-of-line)
2342 (if (bolp)
2343 (insert line "\n")
2344 (insert line))
2345 (forward-line 1)))))))))))
2346 (when (buffer-live-p buf)
2347 (kill-buffer buf))
2348 (assq tchar choices)))
2349
2236(defun sit-for (seconds &optional nodisp obsolete) 2350(defun sit-for (seconds &optional nodisp obsolete)
2237 "Redisplay, then wait for SECONDS seconds. Stop when input is available. 2351 "Redisplay, then wait for SECONDS seconds. Stop when input is available.
2238SECONDS may be a floating-point value. 2352SECONDS may be a floating-point value.