Add evil-collection-define-operator-key

This is for attaching additional keys to operator commands.

e.g. Add "f" to prefix/operator (evil-yank) "y" to get

"yf"

while still maintaining the other operator commands like "yy".
This commit is contained in:
James Nguyen 2021-01-31 20:51:39 -08:00 committed by James N
parent c02184f2fc
commit e52dfbeb68
2 changed files with 56 additions and 36 deletions

View File

@ -330,6 +330,58 @@ Evil Collection for that mode. More arguments may be added in the future, so
functions added to this hook should include a \"&rest _rest\" for forward
compatibility.")
(defun evil-collection-define-operator-key (operator map-sym &rest bindings)
"Defines a key on a specific operator e.g. yank or delete.
This function is useful for adding specific binds to operator maps
(e.g. `evil-yank' or `evil-delete') without erasing the original bind.
For example, say one wants to bind \"yf\" to something but also wants to keep
\"yy\".
This function takes care of checking the whitelist/blacklist against the full
binding.
For example:
(evil-collection-define-operator-key 'yank 'pass-mode-map \"f\" 'pass-copy-field)
This will check \"yf\" against a user's white/blacklist and also record the
binding in `annalist' as so."
(declare (indent defun))
(let* ((prefix (if (eq operator 'yank) "y" "d"))
(operators (if (eq operator 'yank)
'evil-collection-yank-operators
'evil-collection-delete-operators))
(remap (if (eq operator 'yank) [remap evil-yank] [remap evil-delete]))
(whitelist (mapcar 'kbd evil-collection-key-whitelist))
(blacklist (mapcar 'kbd evil-collection-key-blacklist))
filtered-bindings)
(while bindings
(let* ((key (pop bindings))
(key-with-prefix (concat prefix key))
(def
`(menu-item
""
nil
:filter
(lambda (&optional _)
(when (or
(eq evil-this-operator (key-binding ,remap))
(memq evil-this-operator ,operators))
(setq evil-inhibit-operator t)
',(pop bindings))))))
(when (or (and whitelist (member key-with-prefix whitelist))
(not (member key-with-prefix blacklist)))
(annalist-record 'evil-collection 'keybindings
(list map-sym 'operator key-with-prefix def)
:local (or (eq map-sym 'local)
(local-variable-p map-sym)))
;; Use the original key declared when actually setting the binding.
(push key filtered-bindings)
(push def filtered-bindings))))
(setq filtered-bindings (nreverse filtered-bindings))
(evil-collection--define-key 'operator map-sym filtered-bindings)))
(defun evil-collection-define-key (state map-sym &rest bindings)
"Wrapper for `evil-define-key*' with additional features.
Unlike `evil-define-key*' MAP-SYM should be a quoted keymap other than the

View File

@ -66,42 +66,10 @@ keybindings listed in `evil-collection-pass-command-to-label'."
(advice-add 'pass--display-keybinding
:around 'evil-collection-pass-display-keybinding)
;; FIXME: #1 This type of binding is duplicated throughout `evil-collection'
;; Maybe define new utility to do these types of bindings that append
;; to (e.g. y or d) operators.
;; FIXME: #2 These types of bindings will slip through the white/blacklist.
;; For example a user may want to set a blacklist for a bind like "yf"
;; but these binds would be registered as "f" in this case.
;; FIXME: #3 Handle [remap evil-yank], etc to be more bulletproof.
;; https://github.com/emacs-evil/evil-collection/pull/91#issuecomment-366181047
(evil-collection-define-key 'operator 'pass-mode-map
;; Like `eww'.
"f" '(menu-item
""
nil
:filter (lambda (&optional _)
(when (memq evil-this-operator
evil-collection-yank-operators)
(setq evil-inhibit-operator t)
'pass-copy-field)))
"n" '(menu-item
""
nil
:filter (lambda (&optional _)
(when (memq evil-this-operator
evil-collection-yank-operators)
(setq evil-inhibit-operator t)
'pass-copy-username)))
"u" '(menu-item
""
nil
:filter (lambda (&optional _)
(when (memq evil-this-operator
evil-collection-yank-operators)
(setq evil-inhibit-operator t)
'pass-copy-url))))
(evil-collection-define-operator-key 'yank 'pass-mode-map
"f" 'pass-copy-field
"n" 'pass-copy-username
"u" 'pass-copy-url)
;; https://github.com/NicolasPetton/pass/pull/47
(when (fboundp 'pass-edit)