aboutsummaryrefslogtreecommitdiffstats
path: root/lisp/repeat.el
diff options
context:
space:
mode:
authorStefan Kangas2022-12-21 02:37:17 +0100
committerStefan Kangas2022-12-21 02:37:17 +0100
commit2bbc554db63cc5cc140ade5bfcbbf53ecd18f5ae (patch)
tree044d6aa99d0ef54ace6c01583231c1ae286c8865 /lisp/repeat.el
parent1424342225ef5b18c630364dd88e004f4ebb1c7f (diff)
parentd3a76db88b4357fe1c92f240796ea9b522b97a8e (diff)
downloademacs-2bbc554db63cc5cc140ade5bfcbbf53ecd18f5ae.tar.gz
emacs-2bbc554db63cc5cc140ade5bfcbbf53ecd18f5ae.zip
Merge from origin/emacs-29
d3a76db88b4 * lisp/repeat.el: Fix repeat-keep-prefix to allow customi... 8ef3777d544 Correct capitalization of Lisp in the manual (bug#60222) d03ea893780 eglot.el: Add vscode-json-languageserver to eglot-server-... 8550a993785 ; * src/emacs-module.h.in (enum emacs_funcall_exit): Fix ... fb7f3999c59 ; Fix ruby-method-params-indent's :version value cfbfd393b45 * lisp/progmodes/project.el (project--read-file-cpd-relat... 2b1fdbffcb5 ruby-method-params-indent: New user option b9e813f79f2 ; ruby-indent-level: Improve the docstring 399433cc2b9 * lisp/progmodes/project.el: Filter out empty strings fro... 23f7c9c2a92 Fix storing email into nnmail by Gnus 63cdbd986bb ; Really respect browse-url var in erc-compat 64163618d21 whitespace: Fix unintended change in buffer modification ... a75d1da911c Make emacsclient add abbreviated file names to file-name-... b3e7768a0ee Repair setopt test after error demotion to warning
Diffstat (limited to 'lisp/repeat.el')
-rw-r--r--lisp/repeat.el117
1 files changed, 73 insertions, 44 deletions
diff --git a/lisp/repeat.el b/lisp/repeat.el
index 33e8d98ce33..3b3a444ee24 100644
--- a/lisp/repeat.el
+++ b/lisp/repeat.el
@@ -368,6 +368,13 @@ This property can override the value of this variable."
368(defcustom repeat-keep-prefix nil 368(defcustom repeat-keep-prefix nil
369 "Whether to keep the prefix arg of the previous command when repeating." 369 "Whether to keep the prefix arg of the previous command when repeating."
370 :type 'boolean 370 :type 'boolean
371 :initialize #'custom-initialize-default
372 :set (lambda (sym val)
373 (set-default sym val)
374 (when repeat-mode
375 (if repeat-keep-prefix
376 (add-hook 'pre-command-hook 'repeat-pre-hook)
377 (remove-hook 'pre-command-hook 'repeat-pre-hook))))
371 :group 'repeat 378 :group 'repeat
372 :version "28.1") 379 :version "28.1")
373 380
@@ -419,7 +426,11 @@ When Repeat mode is enabled, and the command symbol has the property named
419See `describe-repeat-maps' for a list of all repeatable commands." 426See `describe-repeat-maps' for a list of all repeatable commands."
420 :global t :group 'repeat 427 :global t :group 'repeat
421 (if (not repeat-mode) 428 (if (not repeat-mode)
422 (remove-hook 'post-command-hook 'repeat-post-hook) 429 (progn
430 (remove-hook 'pre-command-hook 'repeat-pre-hook)
431 (remove-hook 'post-command-hook 'repeat-post-hook))
432 (when repeat-keep-prefix
433 (add-hook 'pre-command-hook 'repeat-pre-hook))
423 (add-hook 'post-command-hook 'repeat-post-hook) 434 (add-hook 'post-command-hook 'repeat-post-hook)
424 (let* ((keymaps nil) 435 (let* ((keymaps nil)
425 (commands (all-completions 436 (commands (all-completions
@@ -431,15 +442,21 @@ See `describe-repeat-maps' for a list of all repeatable commands."
431 (length commands) 442 (length commands)
432 (length (delete-dups keymaps)))))) 443 (length (delete-dups keymaps))))))
433 444
434(defvar repeat--prev-mb '(0)
435 "Previous minibuffer state.")
436
437(defun repeat--command-property (property) 445(defun repeat--command-property (property)
438 (or (and (symbolp this-command) 446 (or (and (symbolp this-command)
439 (get this-command property)) 447 (get this-command property))
440 (and (symbolp real-this-command) 448 (and (symbolp real-this-command)
441 (get real-this-command property)))) 449 (get real-this-command property))))
442 450
451(defun repeat-get-map ()
452 "Return a transient map for keys repeatable after the current command."
453 (when repeat-mode
454 (let ((rep-map (or repeat-map (repeat--command-property 'repeat-map))))
455 (when rep-map
456 (when (and (symbolp rep-map) (boundp rep-map))
457 (setq rep-map (symbol-value rep-map)))
458 rep-map))))
459
443(defun repeat-check-key (key map) 460(defun repeat-check-key (key map)
444 "Check if the last key is suitable to activate the repeating MAP." 461 "Check if the last key is suitable to activate the repeating MAP."
445 (let* ((prop (repeat--command-property 'repeat-check-key)) 462 (let* ((prop (repeat--command-property 'repeat-check-key))
@@ -449,50 +466,61 @@ See `describe-repeat-maps' for a list of all repeatable commands."
449 ;; Try without modifiers: 466 ;; Try without modifiers:
450 (lookup-key map (vector (event-basic-type key)))))) 467 (lookup-key map (vector (event-basic-type key))))))
451 468
469(defvar repeat--prev-mb '(0)
470 "Previous minibuffer state.")
471
472(defun repeat-check-map (map)
473 "Decides whether MAP can be used for the next command."
474 (and map
475 ;; Detect changes in the minibuffer state to allow repetitions
476 ;; in the same minibuffer, but not when the minibuffer is activated
477 ;; in the middle of repeating sequence (bug#47566).
478 (or (< (minibuffer-depth) (car repeat--prev-mb))
479 (eq current-minibuffer-command (cdr repeat--prev-mb)))
480 (repeat-check-key last-command-event map)
481 t))
482
483(defun repeat-pre-hook ()
484 "Function run before commands to handle repeatable keys."
485 (when (and repeat-mode repeat-keep-prefix repeat-in-progress
486 (not prefix-arg) current-prefix-arg)
487 (let ((map (repeat-get-map)))
488 ;; Only when repeat-post-hook will activate the same map
489 (when (repeat-check-map map)
490 ;; Optimize to use less logic in the function `repeat-get-map'
491 ;; for the next call: when called again from `repeat-post-hook'
492 ;; it will use the variable `repeat-map'.
493 (setq repeat-map map)
494 ;; Preserve universal argument
495 (setq prefix-arg current-prefix-arg)))))
496
452(defun repeat-post-hook () 497(defun repeat-post-hook ()
453 "Function run after commands to set transient keymap for repeatable keys." 498 "Function run after commands to set transient keymap for repeatable keys."
454 (let ((was-in-progress repeat-in-progress)) 499 (let ((was-in-progress repeat-in-progress))
455 (setq repeat-in-progress nil) 500 (setq repeat-in-progress nil)
456 (when repeat-mode 501 (let ((map (repeat-get-map)))
457 (let ((rep-map (or repeat-map (repeat--command-property 'repeat-map)))) 502 (when (repeat-check-map map)
458 (when rep-map 503 ;; Messaging
459 (when (and (symbolp rep-map) (boundp rep-map)) 504 (funcall repeat-echo-function map)
460 (setq rep-map (symbol-value rep-map))) 505
461 (let ((map (copy-keymap rep-map))) 506 ;; Adding an exit key
462 507 (when repeat-exit-key
463 (when (and 508 (setq map (copy-keymap map))
464 ;; Detect changes in the minibuffer state to allow repetitions 509 (define-key map (if (key-valid-p repeat-exit-key)
465 ;; in the same minibuffer, but not when the minibuffer is activated 510 (kbd repeat-exit-key)
466 ;; in the middle of repeating sequence (bug#47566). 511 repeat-exit-key)
467 (or (< (minibuffer-depth) (car repeat--prev-mb)) 512 'ignore))
468 (eq current-minibuffer-command (cdr repeat--prev-mb))) 513
469 (or (not repeat-keep-prefix) prefix-arg) 514 (setq repeat-in-progress t)
470 (repeat-check-key last-command-event map)) 515 (repeat--exit)
471 516 (let ((exitfun (set-transient-map map)))
472 ;; Messaging 517 (setq repeat-exit-function exitfun)
473 (unless prefix-arg 518
474 (funcall repeat-echo-function map)) 519 (let* ((prop (repeat--command-property 'repeat-exit-timeout))
475 520 (timeout (unless (eq prop 'no) (or prop repeat-exit-timeout))))
476 ;; Adding an exit key 521 (when timeout
477 (when repeat-exit-key 522 (setq repeat-exit-timer
478 (define-key map (if (key-valid-p repeat-exit-key) 523 (run-with-idle-timer timeout nil #'repeat-exit)))))))
479 (kbd repeat-exit-key)
480 repeat-exit-key)
481 'ignore))
482
483 (when (and repeat-keep-prefix (not prefix-arg))
484 (setq prefix-arg current-prefix-arg))
485
486 (setq repeat-in-progress t)
487 (let ((exitfun (set-transient-map map)))
488 (repeat--exit)
489 (setq repeat-exit-function exitfun)
490
491 (let* ((prop (repeat--command-property 'repeat-exit-timeout))
492 (timeout (unless (eq prop 'no) (or prop repeat-exit-timeout))))
493 (when timeout
494 (setq repeat-exit-timer
495 (run-with-idle-timer timeout nil #'repeat-exit))))))))))
496 524
497 (setq repeat-map nil) 525 (setq repeat-map nil)
498 (setq repeat--prev-mb (cons (minibuffer-depth) current-minibuffer-command)) 526 (setq repeat--prev-mb (cons (minibuffer-depth) current-minibuffer-command))
@@ -582,6 +610,7 @@ Used in `repeat-mode'."
582 (push s (alist-get (get s 'repeat-map) keymaps))))) 610 (push s (alist-get (get s 'repeat-map) keymaps)))))
583 (with-help-window (help-buffer) 611 (with-help-window (help-buffer)
584 (with-current-buffer standard-output 612 (with-current-buffer standard-output
613 (setq-local outline-regexp "[*]+")
585 (insert "A list of keymaps used by commands with the symbol property `repeat-map'.\n") 614 (insert "A list of keymaps used by commands with the symbol property `repeat-map'.\n")
586 615
587 (dolist (keymap (sort keymaps (lambda (a b) 616 (dolist (keymap (sort keymaps (lambda (a b)