[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[elpa] externals/compat afc7d3f46a: compat-29: Add set-transient-map
From: |
ELPA Syncer |
Subject: |
[elpa] externals/compat afc7d3f46a: compat-29: Add set-transient-map |
Date: |
Mon, 30 Jan 2023 15:57:24 -0500 (EST) |
branch: externals/compat
commit afc7d3f46a81b764f0824659d537dd4affa81e43
Author: Daniel Mendler <mail@daniel-mendler.de>
Commit: Daniel Mendler <mail@daniel-mendler.de>
compat-29: Add set-transient-map
---
NEWS.org | 1 +
compat-29.el | 57 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++
compat-tests.el | 9 +++++++++
compat.texi | 39 +++++++++++++++++++++++++++++++++++++++
4 files changed, 106 insertions(+)
diff --git a/NEWS.org b/NEWS.org
index 533725252f..c114b3bba4 100644
--- a/NEWS.org
+++ b/NEWS.org
@@ -5,6 +5,7 @@
- compat-26: Add ~make-temp-file~ with optional argument TEXT.
- compat-29: Add ~funcall-with-delayed-message~ and ~with-delayed-message~.
- compat-29: Add ~ert-with-temp-file~ and ~ert-with-temp-directory~.
+- compat-29: Add ~set-transient-map~ with optional arguments MESSAGE and
TIMEOUT.
* Release of "Compat" Version 29.1.3.1
diff --git a/compat-29.el b/compat-29.el
index fa62c45295..97b44f56f6 100644
--- a/compat-29.el
+++ b/compat-29.el
@@ -416,6 +416,63 @@ CONDITION."
(push buf bufs)))
bufs))
+(compat-defvar set-transient-map-timeout nil ;;
<compat-tests:set-transient-map>
+ "Timeout in seconds for deactivation of a transient keymap.
+If this is a number, it specifies the amount of idle time
+after which to deactivate the keymap set by `set-transient-map',
+thus overriding the value of the TIMEOUT argument to that function.")
+
+(compat-defvar set-transient-map-timer nil ;; <compat-tests:set-transient-map>
+ "Timer for `set-transient-map-timeout'.")
+
+(autoload 'format-spec "format-spec")
+(compat-defun set-transient-map (map &optional keep-pred on-exit message
timeout) ;; <compat-tests:set-transient-map>
+ "Handle the optional arguments MESSAGE and TIMEOUT."
+ :extended t
+ (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)
+ (when message (message ""))
+ (when set-transient-map-timer (cancel-timer
set-transient-map-timer))
+ (when on-exit (funcall on-exit)))))
+ (fset clearfun
+ (lambda ()
+ (with-demoted-errors "set-transient-map PCH: %S"
+ (if (cond
+ ((null keep-pred) nil)
+ ((and (not (eq map (cadr
overriding-terminal-local-map)))
+ (memq map (cddr overriding-terminal-local-map)))
+ t)
+ ((eq t keep-pred)
+ (let ((mc (lookup-key map (this-command-keys-vector))))
+ (when (and mc (symbolp mc))
+ (setq mc (or (command-remapping mc) mc)))
+ (and mc (eq this-command mc))))
+ (t (funcall keep-pred)))
+ (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))
+
;;;; Defined in simple.el
(compat-defun use-region-noncontiguous-p () ;;
<compat-tests:region-noncontiguous-p>
diff --git a/compat-tests.el b/compat-tests.el
index 11e108c9ee..2e2d0d2866 100644
--- a/compat-tests.el
+++ b/compat-tests.el
@@ -2875,6 +2875,15 @@
(should-equal 'result (funcall-with-delayed-message
1 "timeout" (lambda () 'result))))
+(ert-deftest set-transient-map ()
+ (let (overriding-terminal-local-map)
+ ;; TODO Implement a proper test. Interactive features like
+ ;; `set-transient-map' are hard to test and Emacs itself is lacking tests.
+ ;; For now only test the calling convention here.
+ (set-transient-map (define-keymap "x" #'ignore))
+ (compat-call set-transient-map (define-keymap "x" #'ignore))
+ (compat-call set-transient-map (define-keymap "x" #'ignore) nil nil "msg"
1)))
+
(ert-deftest ert-with-temp-file ()
(ert-with-temp-file file
(should-not (directory-name-p file))
diff --git a/compat.texi b/compat.texi
index e323c59007..b5fd2dc64e 100644
--- a/compat.texi
+++ b/compat.texi
@@ -2912,6 +2912,45 @@ The same keyword arguments are supported as in
These functions must be called explicitly via @code{compat-call},
since their calling convention or behavior was extended in Emacs 29.1:
+@c copied from lispref/keymaps.texi
+@defun compat-call@ set-transient-map keymap &optional keep-pred on-exit
message timeout
+This function adds @var{keymap} as a @dfn{transient} keymap, which
+takes precedence over other keymaps for one (or more) subsequent keys.
+
+Normally, @var{keymap} is used just once, to look up the very next key.
+If the optional argument @var{keep-pred} is @code{t}, the map stays
+active as long as the user types keys defined in @var{keymap}; when the
+user types a key that is not in @var{keymap}, the transient keymap is
+deactivated and normal key lookup continues for that key.
+
+The @var{keep-pred} argument can also be a function. In that case, the
+function is called with no arguments, prior to running each command,
+while @var{keymap} is active; it should return non-@code{nil} if
+@var{keymap} should stay active.
+
+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} specifies the message to display
+after activating the transient map. If @var{message} is a string, it
+is the format string for the message, and any @samp{%k} specifier in
+that string is replaced with the list of keys from the transient map.
+Any other non-@code{nil} value of @var{message} stands for the default
+message format @samp{Repeat with %k}.
+
+@vindex set-transient-map-timeout
+If the optional argument @var{timeout} is non-@code{nil}, it should be
+a number that specifies how many seconds of idle time to wait before
+deactivating @var{keymap}. The value of the variable
+@code{set-transient-map-timeout}, if non-@code{nil}, overrides the
+value of this argument.
+
+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{elisp,,,Searching Keymaps}).
+@end defun
+
@c copied from lispref/strings.texi
@defun compat-call@ string-lines string &optional omit-nulls keep-newlines
Split @var{string} into a list of strings on newline boundaries. If
[Prev in Thread] |
Current Thread |
[Next in Thread] |
- [elpa] externals/compat afc7d3f46a: compat-29: Add set-transient-map,
ELPA Syncer <=