diff options
author | Juri Linkov <juri@linkov.net> | 2022-07-06 20:39:41 +0300 |
---|---|---|
committer | Juri Linkov <juri@linkov.net> | 2022-07-06 20:39:41 +0300 |
commit | 0e99046d62e71fb874cb9010e60ecfee289f84e9 (patch) | |
tree | f949517518d9ebef48923c6ecc409f43c2db9fa5 | |
parent | 6a7bb1ddbc9837b2d2af60236be58723114855ac (diff) | |
download | emacs-0e99046d62e71fb874cb9010e60ecfee289f84e9.tar.gz |
Add new args MESSAGE and TIMEOUT to set-transient-map (bug#21634)
* lisp/subr.el (set-transient-map): Add new args MESSAGE and TIMEOUT.
(set-transient-map-timeout, set-transient-map-timer): New variables.
* lisp/international/emoji.el (emoji-zoom-increase):
* lisp/indent.el (indent-rigidly):
* lisp/face-remap.el (text-scale-adjust, global-text-scale-adjust):
Use the arg MESSAGE of set-transient-map.
* doc/lispref/keymaps.texi (Controlling Active Maps): Mention new args
MESSAGE and TIMEOUT of set-transient-map.
-rw-r--r-- | doc/lispref/keymaps.texi | 10 | ||||
-rw-r--r-- | etc/NEWS | 7 | ||||
-rw-r--r-- | lisp/face-remap.el | 17 | ||||
-rw-r--r-- | lisp/indent.el | 7 | ||||
-rw-r--r-- | lisp/international/emoji.el | 5 | ||||
-rw-r--r-- | lisp/subr.el | 52 |
6 files changed, 72 insertions, 26 deletions
diff --git a/doc/lispref/keymaps.texi b/doc/lispref/keymaps.texi index 9488c4d7b35..8df4b6f2b47 100644 --- a/doc/lispref/keymaps.texi +++ b/doc/lispref/keymaps.texi @@ -1063,6 +1063,16 @@ The optional argument @var{on-exit}, if non-@code{nil}, specifies a function that is called, with no arguments, after @var{keymap} is deactivated. +The optional argument @var{message}, if a string, specifies the format +string for the message to display after activating the transient map. +When the string contains the specifier @samp{%k}, it's replaced with +the list of keys from the transient map. + +The optional argument @var{timeout}, if a number, specifies the number +of seconds of idle time after which @var{keymap} is deactivated. The +value of the argument @var{timeout} can be overridden by the variable +@code{set-transient-map-timeout}. + This function works by adding and removing @var{keymap} from the variable @code{overriding-terminal-local-map}, which takes precedence over all other active keymaps (@pxref{Searching Keymaps}). @@ -2278,6 +2278,13 @@ patcomp.el, pc-mode.el, pc-select.el, s-region.el, and sregex.el. * Lisp Changes in Emacs 29.1 +++ +** New arguments MESSAGE and TIMEOUT of 'set-transient-map'. +MESSAGE specifies a string that lists available keys, +and TIMEOUT deactivates the transient map after the specified +number of seconds. The default timeout is defined by +the new variable 'set-transient-map-timeout'. + ++++ ** New function 'seq-split'. This returns a list of sub-sequences of the specified sequence. diff --git a/lisp/face-remap.el b/lisp/face-remap.el index 467ccbc2991..fd49c81ab3f 100644 --- a/lisp/face-remap.el +++ b/lisp/face-remap.el @@ -408,20 +408,15 @@ See also the related command `global-text-scale-adjust'." (?0 0) (_ inc)))) (text-scale-increase step) - ;; (unless (zerop step) - (message (substitute-command-keys - "Use \\`+',\\`-',\\`0' for further adjustment")) (set-transient-map (let ((map (make-sparse-keymap))) (dolist (mods '(() (control))) - (dolist (key '(?- ?+ ?= ?0)) ;; = is often unshifted +. + (dolist (key '(?+ ?= ?- ?0)) ;; = is often unshifted +. (define-key map (vector (append mods (list key))) (lambda () (interactive) (text-scale-adjust (abs inc)))))) map) - nil - ;; Clear the prompt after exiting. - (lambda () - (message "")))))) + nil nil + "Use %k for further adjustment")))) (defvar-local text-scale--pinch-start-scale 0 "The text scale at the start of a pinch sequence.") @@ -515,15 +510,15 @@ See also the related command `text-scale-adjust'." (not global-text-scale-adjust-resizes-frames))) (set-face-attribute 'default nil :height new))) (when (characterp key) - (message (substitute-command-keys - "Use \\`+',\\`-',\\`0' for further adjustment")) (set-transient-map (let ((map (make-sparse-keymap))) (dolist (mod '(() (control meta))) (dolist (key '(?+ ?= ?- ?0)) (define-key map (vector (append mod (list key))) 'global-text-scale-adjust))) - map)))))) + map) + nil nil + "Use %k for further adjustment"))))) ;; ---------------------------------------------------------------- diff --git a/lisp/indent.el b/lisp/indent.el index d6dee94016d..f52b729051d 100644 --- a/lisp/indent.el +++ b/lisp/indent.el @@ -270,11 +270,8 @@ Negative values of ARG indent backward, so you can remove all indentation by specifying a large negative ARG." (interactive "r\nP\np") (if (and (not arg) interactive) - (progn - (message - (substitute-command-keys - "Indent region with \\<indent-rigidly-map>\\[indent-rigidly-left], \\[indent-rigidly-right], \\[indent-rigidly-left-to-tab-stop], or \\[indent-rigidly-right-to-tab-stop].")) - (set-transient-map indent-rigidly-map t #'deactivate-mark)) + (set-transient-map indent-rigidly-map t #'deactivate-mark + "Indent region with %k") (save-excursion (goto-char end) (setq end (point-marker)) diff --git a/lisp/international/emoji.el b/lisp/international/emoji.el index 341b44cc11e..4f4d4f48320 100644 --- a/lisp/international/emoji.el +++ b/lisp/international/emoji.el @@ -704,10 +704,7 @@ We prefer the earliest unique letter." "Increase the size of the character under point. FACTOR is the multiplication factor for the size." (interactive) - (message - (substitute-command-keys - "Zoom with \\<emoji-zoom-map>\\[emoji-zoom-increase] and \\[emoji-zoom-decrease]")) - (set-transient-map emoji-zoom-map t) + (set-transient-map emoji-zoom-map t nil "Zoom with %k") (let* ((factor (or factor 1.1)) (old (get-text-property (point) 'face)) (height (or (and (consp old) diff --git a/lisp/subr.el b/lisp/subr.el index 2f9d37ffd6e..44d094d28dd 100644 --- a/lisp/subr.el +++ b/lisp/subr.el @@ -6013,7 +6013,15 @@ To test whether a function can be called interactively, use (define-obsolete-function-alias 'set-temporary-overlay-map #'set-transient-map "24.4") -(defun set-transient-map (map &optional keep-pred on-exit) +(defvar set-transient-map-timeout nil + "Deactivate the transient map after specified timeout. +When a number, after idle time of the specified number of seconds +deactivate the map set by the previous call of `set-transient-map'.") + +(defvar set-transient-map-timer nil + "Timer for `set-transient-map-timeout'.") + +(defun set-transient-map (map &optional keep-pred on-exit message timeout) "Set MAP as a temporary keymap taking precedence over other keymaps. Normally, MAP is used only once, to look up the very next key. However, if the optional argument KEEP-PRED is t, MAP stays @@ -6024,24 +6032,50 @@ if it returns non-nil, then MAP stays active. Optional arg ON-EXIT, if non-nil, specifies a function that is called, with no arguments, after MAP is deactivated. -This uses `overriding-terminal-local-map', which takes precedence over all -other keymaps. As usual, if no match for a key is found in MAP, the normal -key lookup sequence then continues. +Optional arg MESSAGE, if a string, specifies the format string for the +message to display after activating the transient map. When the string +contains the specifier %k, it's replaced with the list of keys from the +transient map. Other non-nil values of MESSAGE use the message format +\"Repeat with %k\". On deactivating the map the displayed message +is cleared out. + +Optional arg TIMEOUT, if a number, specifies the number of seconds +of idle time after which the map is deactivated. The variable +`set-transient-map-timeout' overrides the argument TIMEOUT. + +This function uses `overriding-terminal-local-map', which takes precedence +over all other keymaps. As usual, if no match for a key is found in MAP, +the normal key lookup sequence then continues. This returns an \"exit function\", which can be called with no argument to deactivate this transient map, regardless of KEEP-PRED." - (let* ((clearfun (make-symbol "clear-transient-map")) + (let* ((timeout (or set-transient-map-timeout timeout)) + (message + (when message + (let (keys) + (map-keymap (lambda (key cmd) (and cmd (push key keys))) map) + (format-spec (if (stringp message) message "Repeat with %k") + `((?k . ,(mapconcat + (lambda (key) + (substitute-command-keys + (format "\\`%s'" + (key-description (vector key))))) + keys ", "))))))) + (clearfun (make-symbol "clear-transient-map")) (exitfun (lambda () (internal-pop-keymap map 'overriding-terminal-local-map) (remove-hook 'pre-command-hook clearfun) + ;; Clear the prompt after exiting. + (when message (message "")) + (when set-transient-map-timer (cancel-timer set-transient-map-timer)) (when on-exit (funcall on-exit))))) ;; Don't use letrec, because equal (in add/remove-hook) could get trapped ;; in a cycle. (bug#46326) (fset clearfun (lambda () (with-demoted-errors "set-transient-map PCH: %S" - (unless (cond + (if (cond ((null keep-pred) nil) ((and (not (eq map (cadr overriding-terminal-local-map))) (memq map (cddr overriding-terminal-local-map))) @@ -6066,9 +6100,15 @@ to deactivate this transient map, regardless of KEEP-PRED." ;; nil and so is `mc`. (and mc (eq this-command mc)))) (t (funcall keep-pred))) + ;; Repeat the message for the next command. + (when message (message "%s" message)) (funcall exitfun))))) (add-hook 'pre-command-hook clearfun) (internal-push-keymap map 'overriding-terminal-local-map) + (when timeout + (when set-transient-map-timer (cancel-timer set-transient-map-timer)) + (setq set-transient-map-timer (run-with-idle-timer timeout nil exitfun))) + (when message (message "%s" message)) exitfun)) ;;;; Progress reporters. |