Reputation: 139
I am new to Emacs and have been using evil-mode. I have been having some trouble remapping some of the mappings that i had in vim. In vim it was easy to remap keys using the map
function. I wanted to remap cw
to ciw
and dw
to diw
. But I dont have much understanding of elisp. So is there any plugin or function that allows easy mapping.
Thanks.
Upvotes: 5
Views: 1800
Reputation: 148
First the bad news: out of the box this is currently not possible without influencing other operators as well. The reason is that c
is an operator, so Emacs executes evil-change
as soon as c
is typed. Then Evil enters operator pending state and the following w
(or iw
) is read to figure out the correct motion.
The problem is that there is only one operator state for all operators, i.e. there is only one shared keymap. Thus, changing w
to iw
will change the behavior for all operators not only c
or d
.
First good news: if this is okay for you then you could simply do
(define-key evil-operator-state-map "w" "iw")
Now even better news. If you know the stuff above then it is relatively easy solve the problem using a little bit of Emacs lisp magic. The range that is passed to the operator is determined by the function evil-operator-range
. The idea is to advice this function and temporarily change the keybindings if the current operator is evil-change
or evil-delete
. There are several candidate keymaps where you could place the new bindings but evil-operator-state-local-map
is a reasonable choice.
(defun my/evil-motion-range (orig-fun &rest args)
(if (not (memq this-command '(evil-delete evil-change)))
(apply orig-fun args)
(let* ((orig-keymap evil-operator-state-local-map)
(evil-operator-state-local-map (copy-keymap orig-keymap)))
(define-key evil-operator-state-local-map "w" "iw")
(apply orig-fun args))))
(advice-add 'evil-operator-range :around #'my/evil-motion-range)
Actually, this technique would allow to implement operator specific bindings in a generic way.
Upvotes: 3