3

I have the following definition in my init.el:

(define-key evil-motion-state-map (kbd "SPC j") #'evilem-motion-next-line)

This works if I want to do dSPCj, but I'd like to be able to do SPCdj as well. (Here, SPC is meant to take the place of the prefix argument or "count", which can come in either location. see evil-easymotion for a description of its behavior).

The naive solution

(define-key evil-normal-state-map (kbd "SPC d") (kbd "d SPC"))

Does not work for the same reason described in Emacs bind key to prefix. The solution to that question doesn't work for me because there is no prefix command to bind to, as all commands are hidden behind evil-delete.

Is there any way to accomplish this?

4

Try the following, not sure if it will work.

(defun simulate-key-press (key)
  "Return a command that pretends KEY was presssed.
KEY must be given in `kbd' notation."
  `(lambda () (interactive)
     (setq prefix-arg current-prefix-arg)
     (setq unread-command-events (listify-key-sequence (read-kbd-macro ,key)))))

(define-key evil-normal-state-map (kbd "SPC d") (simulate-key-press "d SPC"))
  • This is ridiculously awesome. – PythonNut Jun 25 '15 at 14:52
  • Ah. One caveat: this doesn't work for multiple keys, as in SPC gu ==> gu SPC. – PythonNut Jun 25 '15 at 16:15
  • @PythonNut Did you try writting it as SPC g u (with a space between the g and the u)? – Malabarba Jun 25 '15 at 22:12
  • No, but even with that I get user-error: Key sequence contains no complete binding. – PythonNut Jun 26 '15 at 2:20
  • Alas, can't win them all. :( – Malabarba Jun 27 '15 at 6:42
1

Mmh. But SPC in your example is not like a counter. It rather acts as a leader key for j: SPC j becomes a new unit, a motion that does "something related to j, but more advanced" (as a mnemonic), and is bound to #'evilem-motion-next-line. And - you don't usually break a leader-key combination in the same way you'd use a counter (what I'm saying is - I don't expect a leader to work the same way a counter does).

That said, what you want (with vim grammar power) translates (for me) as:
"Create a different operation, and map it to SPC d" - one that understands the j motion (and others). If done properly, it can happen that SPC d j will do the same thing as d SPC j :)

Although, IMHO, the "Vim way" would be to have SPC d j perform another operation. So that one can also type SPC d SPC j for example, with a meaningful result. So, instead of the redundancy (SPC d j = d SPC j), more functionality (SPC d j != d SPC j).

Although, I think in Emacs you probably can implement the leader key as a counter, since the counter is also a custom Evil implementation.

  • I'm doing this for evil-easymotion, where SPC means I really want a count, but I'd like to enter it visually. So the interpretation of SPC is like a placeholder for the count you'll enter later. You'll do SPC dft and look at which t is the one you want and teleport there (regardless of the number of ts between) – PythonNut Jun 25 '15 at 14:55
  • 1
    You define what you want, no need to feel constrained by "Vim-like" rules :). For me, it's not the same, logically, to do an operation n times on a motion/text-object, or to do a single operation on a range of n motions/text-objects (i.e. 3dw may have the same effect as d3w, but nothing guarantees that, for custom operations/text-objects, n operation text-object == operation n text-object). For example, a "trim" operation could remove spaces for the beginning and end of a range: if I do "3 times trim a line", this is different (and it's ok) than "trim a range of 3 lines". – VanLaser Jun 25 '15 at 15:18
  • 1
    indeed. I just haven't thought of something clever to do with the alternate meaning. easymotions are super motions. What is a super operator? In the meantime, I'd rather have the prefix modifier as an option instead of leaving it unbound. My fingers find it slightly easier to type, and my mind seems to prefer declaring the use of the grenade launcher up-front. – PythonNut Jun 25 '15 at 16:28
  • Heh - It's high time for an easyoperator plugin then :) – VanLaser Jun 25 '15 at 16:39
0

So you want SPC to be a prefix key, which means binding it to a keymap. You want d to be bound in that map, and you want it too to be a prefix key, which means that you want to bind d to another keymap.

I don't see why you would want to do this, but if that's what you want to do then that's one way to do it.

(define-prefix-command 'space-map)
(define-key evil-normal-state-map (kbd "<SPC>") space-map)                                    

(define-prefix-command 'space-d-map)
(define-key space-map "d" space-d-map)                                    

(define-key space-d-map "j" 'evilem-motion-next-line)
  • 1
    It has to do with the way Vim works. We have our prefixes and keys, Vim has arguments, operators, and objects. In vim you say 3dw: argument is 3, the action is delete, and the object is words. In Vim, 3dw does the same thing as d3w. Your answer does not take into account that the d is significant, it will just move the point, but not delete the region. That's why this problem is stickier than usual. – PythonNut Jun 25 '15 at 0:37

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.