diff --git a/evil-collection.el b/evil-collection.el index 30ea122..658b631 100644 --- a/evil-collection.el +++ b/evil-collection.el @@ -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 diff --git a/modes/pass/evil-collection-pass.el b/modes/pass/evil-collection-pass.el index eab592d..5e5551b 100644 --- a/modes/pass/evil-collection-pass.el +++ b/modes/pass/evil-collection-pass.el @@ -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)