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.
This commit is contained in:
Juri Linkov 2022-07-06 20:39:41 +03:00
parent 6a7bb1ddbc
commit 0e99046d62
6 changed files with 72 additions and 26 deletions

View file

@ -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}).

View file

@ -2277,6 +2277,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.

View file

@ -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")))))
;; ----------------------------------------------------------------

View file

@ -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))

View file

@ -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)

View file

@ -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.