diff options
| author | John Wiegley | 2022-08-07 08:30:25 -0700 |
|---|---|---|
| committer | GitHub | 2022-08-07 08:30:25 -0700 |
| commit | de0c8c36c7c4bb68b2c881b0449dcee050b19e63 (patch) | |
| tree | 4bc14e50f4119ddb674b132329458e20d8d20cfd | |
| parent | 015c921a2e0fdf5f17f095235dd96d8080b0e6eb (diff) | |
| parent | 1143f14d650c7201d7ddbcb7012dc2c9bf3b1824 (diff) | |
| download | emacs-de0c8c36c7c4bb68b2c881b0449dcee050b19e63.tar.gz emacs-de0c8c36c7c4bb68b2c881b0449dcee050b19e63.zip | |
Merge pull request from Hugo-Heagren/bind-keys-repeat-map
GitHub-reference: https://github.com/jwiegley/use-package/issues/974
| -rw-r--r-- | lisp/use-package/bind-key.el | 74 | ||||
| -rw-r--r-- | lisp/use-package/use-package-bind-key.el | 7 |
2 files changed, 72 insertions, 9 deletions
diff --git a/lisp/use-package/bind-key.el b/lisp/use-package/bind-key.el index 9a2ddcd8437..3169e24412f 100644 --- a/lisp/use-package/bind-key.el +++ b/lisp/use-package/bind-key.el | |||
| @@ -258,30 +258,60 @@ Accepts keyword arguments: | |||
| 258 | for these bindings | 258 | for these bindings |
| 259 | :prefix-docstring STR - docstring for the prefix-map variable | 259 | :prefix-docstring STR - docstring for the prefix-map variable |
| 260 | :menu-name NAME - optional menu string for prefix map | 260 | :menu-name NAME - optional menu string for prefix map |
| 261 | :repeat-docstring STR - docstring for the repeat-map variable | ||
| 262 | :repeat-map MAP - name of the repeat map that should be created | ||
| 263 | for these bindings. If specified, the | ||
| 264 | 'repeat-map property of each command bound | ||
| 265 | (within the scope of the :repeat-map keyword) | ||
| 266 | is set to this map. | ||
| 267 | :exit BINDINGS - Within the scope of :repeat-map will bind the | ||
| 268 | key in the repeat map, but will not set the | ||
| 269 | 'repeat-map property of the bound command. | ||
| 270 | :continue BINDINGS - Within the scope of :repeat-map forces the | ||
| 271 | same behaviour as if no special keyword had | ||
| 272 | been used (that is, the command is bound, and | ||
| 273 | it's 'repeat-map property set) | ||
| 261 | :filter FORM - optional form to determine when bindings apply | 274 | :filter FORM - optional form to determine when bindings apply |
| 262 | 275 | ||
| 263 | The rest of the arguments are conses of keybinding string and a | 276 | The rest of the arguments are conses of keybinding string and a |
| 264 | function symbol (unquoted)." | 277 | function symbol (unquoted)." |
| 265 | (let (map | 278 | (let (map |
| 266 | doc | 279 | prefix-doc |
| 267 | prefix-map | 280 | prefix-map |
| 268 | prefix | 281 | prefix |
| 282 | repeat-map | ||
| 283 | repeat-doc | ||
| 284 | repeat-type ;; Only used internally | ||
| 269 | filter | 285 | filter |
| 270 | menu-name | 286 | menu-name |
| 271 | pkg) | 287 | pkg) |
| 272 | 288 | ||
| 273 | ;; Process any initial keyword arguments | 289 | ;; Process any initial keyword arguments |
| 274 | (let ((cont t)) | 290 | (let ((cont t) |
| 291 | (arg-change-func 'cddr)) | ||
| 275 | (while (and cont args) | 292 | (while (and cont args) |
| 276 | (if (cond ((and (eq :map (car args)) | 293 | (if (cond ((and (eq :map (car args)) |
| 277 | (not prefix-map)) | 294 | (not prefix-map)) |
| 278 | (setq map (cadr args))) | 295 | (setq map (cadr args))) |
| 279 | ((eq :prefix-docstring (car args)) | 296 | ((eq :prefix-docstring (car args)) |
| 280 | (setq doc (cadr args))) | 297 | (setq prefix-doc (cadr args))) |
| 281 | ((and (eq :prefix-map (car args)) | 298 | ((and (eq :prefix-map (car args)) |
| 282 | (not (memq map '(global-map | 299 | (not (memq map '(global-map |
| 283 | override-global-map)))) | 300 | override-global-map)))) |
| 284 | (setq prefix-map (cadr args))) | 301 | (setq prefix-map (cadr args))) |
| 302 | ((eq :repeat-docstring (car args)) | ||
| 303 | (setq repeat-doc (cadr args))) | ||
| 304 | ((and (eq :repeat-map (car args)) | ||
| 305 | (not (memq map '(global-map | ||
| 306 | override-global-map)))) | ||
| 307 | (setq repeat-map (cadr args)) | ||
| 308 | (setq map repeat-map)) | ||
| 309 | ((eq :continue (car args)) | ||
| 310 | (setq repeat-type :continue | ||
| 311 | arg-change-func 'cdr)) | ||
| 312 | ((eq :exit (car args)) | ||
| 313 | (setq repeat-type :exit | ||
| 314 | arg-change-func 'cdr)) | ||
| 285 | ((eq :prefix (car args)) | 315 | ((eq :prefix (car args)) |
| 286 | (setq prefix (cadr args))) | 316 | (setq prefix (cadr args))) |
| 287 | ((eq :filter (car args)) | 317 | ((eq :filter (car args)) |
| @@ -290,13 +320,17 @@ function symbol (unquoted)." | |||
| 290 | (setq menu-name (cadr args))) | 320 | (setq menu-name (cadr args))) |
| 291 | ((eq :package (car args)) | 321 | ((eq :package (car args)) |
| 292 | (setq pkg (cadr args)))) | 322 | (setq pkg (cadr args)))) |
| 293 | (setq args (cddr args)) | 323 | (setq args (funcall arg-change-func args)) |
| 294 | (setq cont nil)))) | 324 | (setq cont nil)))) |
| 295 | 325 | ||
| 296 | (when (or (and prefix-map (not prefix)) | 326 | (when (or (and prefix-map (not prefix)) |
| 297 | (and prefix (not prefix-map))) | 327 | (and prefix (not prefix-map))) |
| 298 | (error "Both :prefix-map and :prefix must be supplied")) | 328 | (error "Both :prefix-map and :prefix must be supplied")) |
| 299 | 329 | ||
| 330 | (when repeat-type | ||
| 331 | (unless repeat-map | ||
| 332 | (error ":continue and :exit require specifying :repeat-map"))) | ||
| 333 | |||
| 300 | (when (and menu-name (not prefix)) | 334 | (when (and menu-name (not prefix)) |
| 301 | (error "If :menu-name is supplied, :prefix must be too")) | 335 | (error "If :menu-name is supplied, :prefix must be too")) |
| 302 | 336 | ||
| @@ -328,13 +362,16 @@ function symbol (unquoted)." | |||
| 328 | (append | 362 | (append |
| 329 | (when prefix-map | 363 | (when prefix-map |
| 330 | `((defvar ,prefix-map) | 364 | `((defvar ,prefix-map) |
| 331 | ,@(when doc `((put ',prefix-map 'variable-documentation ,doc))) | 365 | ,@(when prefix-doc `((put ',prefix-map 'variable-documentation ,prefix-doc))) |
| 332 | ,@(if menu-name | 366 | ,@(if menu-name |
| 333 | `((define-prefix-command ',prefix-map nil ,menu-name)) | 367 | `((define-prefix-command ',prefix-map nil ,menu-name)) |
| 334 | `((define-prefix-command ',prefix-map))) | 368 | `((define-prefix-command ',prefix-map))) |
| 335 | ,@(if (and map (not (eq map 'global-map))) | 369 | ,@(if (and map (not (eq map 'global-map))) |
| 336 | (wrap map `((bind-key ,prefix ',prefix-map ,map ,filter))) | 370 | (wrap map `((bind-key ,prefix ',prefix-map ,map ,filter))) |
| 337 | `((bind-key ,prefix ',prefix-map nil ,filter))))) | 371 | `((bind-key ,prefix ',prefix-map nil ,filter))))) |
| 372 | (when repeat-map | ||
| 373 | `((defvar ,repeat-map (make-sparse-keymap) | ||
| 374 | ,@(when repeat-doc `(,repeat-doc))))) | ||
| 338 | (wrap map | 375 | (wrap map |
| 339 | (cl-mapcan | 376 | (cl-mapcan |
| 340 | (lambda (form) | 377 | (lambda (form) |
| @@ -342,13 +379,19 @@ function symbol (unquoted)." | |||
| 342 | (if prefix-map | 379 | (if prefix-map |
| 343 | `((bind-key ,(car form) ,fun ,prefix-map ,filter)) | 380 | `((bind-key ,(car form) ,fun ,prefix-map ,filter)) |
| 344 | (if (and map (not (eq map 'global-map))) | 381 | (if (and map (not (eq map 'global-map))) |
| 345 | `((bind-key ,(car form) ,fun ,map ,filter)) | 382 | ;; Only needed in this branch, since when |
| 383 | ;; repeat-map is non-nil, map is always | ||
| 384 | ;; non-nil | ||
| 385 | `(,@(when (and repeat-map (not (eq repeat-type :exit))) | ||
| 386 | `((put ,fun 'repeat-map ',repeat-map))) | ||
| 387 | (bind-key ,(car form) ,fun ,map ,filter)) | ||
| 346 | `((bind-key ,(car form) ,fun nil ,filter)))))) | 388 | `((bind-key ,(car form) ,fun nil ,filter)))))) |
| 347 | first)) | 389 | first)) |
| 348 | (when next | 390 | (when next |
| 349 | (bind-keys-form (if pkg | 391 | (bind-keys-form `(,@(when repeat-map `(:repeat-map ,repeat-map)) |
| 350 | (cons :package (cons pkg next)) | 392 | ,@(if pkg |
| 351 | next) map))))))) | 393 | (cons :package (cons pkg next)) |
| 394 | next)) map))))))) | ||
| 352 | 395 | ||
| 353 | ;;;###autoload | 396 | ;;;###autoload |
| 354 | (defmacro bind-keys (&rest args) | 397 | (defmacro bind-keys (&rest args) |
| @@ -362,6 +405,19 @@ Accepts keyword arguments: | |||
| 362 | for these bindings | 405 | for these bindings |
| 363 | :prefix-docstring STR - docstring for the prefix-map variable | 406 | :prefix-docstring STR - docstring for the prefix-map variable |
| 364 | :menu-name NAME - optional menu string for prefix map | 407 | :menu-name NAME - optional menu string for prefix map |
| 408 | :repeat-docstring STR - docstring for the repeat-map variable | ||
| 409 | :repeat-map MAP - name of the repeat map that should be created | ||
| 410 | for these bindings. If specified, the | ||
| 411 | 'repeat-map property of each command bound | ||
| 412 | (within the scope of the :repeat-map keyword) | ||
| 413 | is set to this map. | ||
| 414 | :exit BINDINGS - Within the scope of :repeat-map will bind the | ||
| 415 | key in the repeat map, but will not set the | ||
| 416 | 'repeat-map property of the bound command. | ||
| 417 | :continue BINDINGS - Within the scope of :repeat-map forces the | ||
| 418 | same behaviour as if no special keyword had | ||
| 419 | been used (that is, the command is bound, and | ||
| 420 | it's 'repeat-map property set) | ||
| 365 | :filter FORM - optional form to determine when bindings apply | 421 | :filter FORM - optional form to determine when bindings apply |
| 366 | 422 | ||
| 367 | The rest of the arguments are conses of keybinding string and a | 423 | The rest of the arguments are conses of keybinding string and a |
diff --git a/lisp/use-package/use-package-bind-key.el b/lisp/use-package/use-package-bind-key.el index e476b060ad6..9642f311750 100644 --- a/lisp/use-package/use-package-bind-key.el +++ b/lisp/use-package/use-package-bind-key.el | |||
| @@ -86,13 +86,20 @@ deferred until the prefix key sequence is pressed." | |||
| 86 | ;; :prefix-docstring STRING | 86 | ;; :prefix-docstring STRING |
| 87 | ;; :prefix-map SYMBOL | 87 | ;; :prefix-map SYMBOL |
| 88 | ;; :prefix STRING | 88 | ;; :prefix STRING |
| 89 | ;; :repeat-docstring STRING | ||
| 90 | ;; :repeat-map SYMBOL | ||
| 89 | ;; :filter SEXP | 91 | ;; :filter SEXP |
| 90 | ;; :menu-name STRING | 92 | ;; :menu-name STRING |
| 91 | ;; :package SYMBOL | 93 | ;; :package SYMBOL |
| 94 | ;; :continue and :exit are used within :repeat-map | ||
| 92 | ((or (and (eq x :map) (symbolp (cadr arg))) | 95 | ((or (and (eq x :map) (symbolp (cadr arg))) |
| 93 | (and (eq x :prefix) (stringp (cadr arg))) | 96 | (and (eq x :prefix) (stringp (cadr arg))) |
| 94 | (and (eq x :prefix-map) (symbolp (cadr arg))) | 97 | (and (eq x :prefix-map) (symbolp (cadr arg))) |
| 95 | (and (eq x :prefix-docstring) (stringp (cadr arg))) | 98 | (and (eq x :prefix-docstring) (stringp (cadr arg))) |
| 99 | (and (eq x :repeat-map) (symbolp (cadr arg))) | ||
| 100 | (eq x :continue) | ||
| 101 | (eq x :exit) | ||
| 102 | (and (eq x :repeat-docstring) (stringp (cadr arg))) | ||
| 96 | (eq x :filter) | 103 | (eq x :filter) |
| 97 | (and (eq x :menu-name) (stringp (cadr arg))) | 104 | (and (eq x :menu-name) (stringp (cadr arg))) |
| 98 | (and (eq x :package) (symbolp (cadr arg)))) | 105 | (and (eq x :package) (symbolp (cadr arg)))) |