[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
master ddbc33343c 2/2: * lisp/keymap.el (defvar-keymap): Add support for
|
From: |
Juri Linkov |
|
Subject: |
master ddbc33343c 2/2: * lisp/keymap.el (defvar-keymap): Add support for repeat-mode. |
|
Date: |
Thu, 17 Nov 2022 02:30:27 -0500 (EST) |
branch: master
commit ddbc33343cca8c66d841cc16eac77ea626e50e23
Author: Juri Linkov <juri@linkov.net>
Commit: Juri Linkov <juri@linkov.net>
* lisp/keymap.el (defvar-keymap): Add support for repeat-mode.
Put symbol properties 'repeat-map' on commands from the keymap
when a ':repeat' keyword is non-nil. Also include/exclude commands
according to ':repeat (:enter (commands ...) :exit (commands ...))'.
https://lists.gnu.org/archive/html/emacs-devel/2022-11/msg00968.html
---
etc/NEWS | 4 ++++
lisp/keymap.el | 52 +++++++++++++++++++++++++++++++++++++++++++---------
2 files changed, 47 insertions(+), 9 deletions(-)
diff --git a/etc/NEWS b/etc/NEWS
index bb2bd52134..47fc9f1e8e 100644
--- a/etc/NEWS
+++ b/etc/NEWS
@@ -4075,6 +4075,10 @@ This function allows defining a number of keystrokes
with one form.
** New macro 'defvar-keymap'.
This macro allows defining keymap variables more conveniently.
+** 'repeat-map' can be defined in the macro 'defvar-keymap'.
+This is possible either by using ':repeat t' or more advanced
+':repeat (:enter (commands ...) :exit (commands ...))'.
+
---
** 'kbd' can now be used in built-in, preloaded libraries.
It no longer depends on edmacro.el and cl-lib.el.
diff --git a/lisp/keymap.el b/lisp/keymap.el
index 107565590c..953fb233cb 100644
--- a/lisp/keymap.el
+++ b/lisp/keymap.el
@@ -559,22 +559,37 @@ In addition to the keywords accepted by `define-keymap',
this
macro also accepts a `:doc' keyword, which (if present) is used
as the variable documentation string.
-\(fn VARIABLE-NAME &key DOC FULL PARENT SUPPRESS NAME PREFIX KEYMAP &rest [KEY
DEFINITION]...)"
+When a `:repeat' keyword is non-nil, put `repeat-map' symbol
+properties on commands in this map for `repeat-mode'. The value
+could also be a property list with properties `:enter' and `:exit',
+for example, :repeat (:enter (commands ...) :exit (commands ...)).
+`:enter' is a list of additional commands that only enter `repeat-mode'.
+When the list is empty then by default all commands in the map enter
+`repeat-mode'. This is applicable when a command has the `repeat-map'
+symbol property on its symbol, but doesn't exist in the map. `:exit'
+is a list of commands that exit `repeat-mode'. When the list is
+empty, no commands in the map exit `repeat-mode'. This is applicable
+when a command exists in the map, but doesn't have the `repeat-map'
+symbol property on its symbol.
+
+\(fn VARIABLE-NAME &key DOC FULL PARENT SUPPRESS NAME PREFIX KEYMAP REPEAT
&rest [KEY DEFINITION]...)"
(declare (indent 1))
(let ((opts nil)
- doc)
+ doc repeat props)
(while (and defs
(keywordp (car defs))
(not (eq (car defs) :menu)))
(let ((keyword (pop defs)))
(unless defs
(error "Uneven number of keywords"))
- (if (eq keyword :doc)
- (setq doc (pop defs))
- (push keyword opts)
- (push (pop defs) opts))))
+ (pcase keyword
+ (:doc (setq doc (pop defs)))
+ (:repeat (setq repeat (pop defs)))
+ (_ (push keyword opts)
+ (push (pop defs) opts)))))
(unless (zerop (% (length defs) 2))
(error "Uneven number of key/definition pairs: %s" defs))
+
(let ((defs defs)
key seen-keys)
(while defs
@@ -585,9 +600,28 @@ as the variable documentation string.
(error "Duplicate definition for key '%s' in keymap '%s'"
key variable-name)
(push key seen-keys)))))
- `(defvar ,variable-name
- (define-keymap ,@(nreverse opts) ,@defs)
- ,@(and doc (list doc)))))
+
+ (when repeat
+ (let ((defs defs)
+ def)
+ (dolist (def (plist-get repeat :enter))
+ (push `(put ',def 'repeat-map ',variable-name) props))
+ (while defs
+ (pop defs)
+ (setq def (pop defs))
+ (when (and (memq (car def) '(function quote))
+ (not (memq (cadr def) (plist-get repeat :exit))))
+ (push `(put ,def 'repeat-map ',variable-name) props)))))
+
+ (let ((defvar-form
+ `(defvar ,variable-name
+ (define-keymap ,@(nreverse opts) ,@defs)
+ ,@(and doc (list doc)))))
+ (if repeat
+ `(progn
+ ,defvar-form
+ ,@(nreverse props))
+ defvar-form))))
(defun make-non-key-event (symbol)
"Mark SYMBOL as an event that shouldn't be returned from `where-is'."