From 84595efff6d5a4ec4bf108cee19236eb77a330d3 Mon Sep 17 00:00:00 2001 From: Morgan Willcock Date: Mon, 22 Jan 2024 21:07:08 +0000 Subject: [PATCH] Add optional repeat suppression This change introduces an option which allows translated key bindings to avoid being repeated, to be used by Devil or by other packages where the Devil repeat map should not be activated. Repeat suppression is configured by maintaining a list of functions which are treated as repeat suppression predicates. Interactive functions will not be repeated when their symbol is a list member. Non-interactive functions are called with the binding as the argument and should return a non-nil value when the repeat should be suppressed. By default the predicate list contains the symbol devil--isearch-suppress-repeat-p which suppresses the repeat of isearch-forward while the isearch specific mode map is not active. This fixes initiating an isearch with the default list of repeatable keys and trying to enter the letter 's' as the search criteria. --- devil.el | 33 ++++++++++++++++++++++++++++++++- 1 file changed, 32 insertions(+), 1 deletion(-) diff --git a/devil.el b/devil.el index 58c73c5..4e30a27 100644 --- a/devil.el +++ b/devil.el @@ -245,6 +245,35 @@ in the format control string." "Turn Devil mode on." (devil-mode 1)) + +;;; Repeat suppression =============================================== + +(defun devil--isearch-suppress-repeat-p (binding) + "Suppress the repeat of BINDING if it will initiate isearch." + (and (eq binding 'isearch-forward) + (not (eq (current-local-map) isearch-mode-map)))) + +(defvar devil-suppress-repeat-predicates + (list #'devil--isearch-suppress-repeat-p) + "The list of function symbols treated as predicates.") + +(defun devil--suppress-repeat-p (binding) + "Return a non-nil value if BINDING should not be repeated. + +For every symbol in `devil-suppress-repeat-predicates', if the +symbol is an interactive command, compare it to BINDING using +`eq', otherwise if the symbol is a function, call it with BINDING +as the single argument. If any result is non-nil, return the +result without testing any additional symbols." + (seq-some (lambda (x) + (cond ((commandp x) + (eq x binding)) + ((functionp x) + (funcall x binding)) + (t + (error "Bad suppress-repeat value")))) + devil-suppress-repeat-predicates)) + ;;; Bonus Key Bindings =============================================== @@ -288,7 +317,9 @@ in the format control string." (message "Devil: %s is undefined" translated-key) (devil--execute-command key binding) (when translated-key - (devil--set-repeatable-keys (key-description key)))))) + (if (devil--suppress-repeat-p binding) + (devil--log "Repeat suppressed for %s" binding) + (devil--set-repeatable-keys (key-description key))))))) (defun devil-describe-key () "Describe a Devil key sequence."