8

dj in vim deletes the current line as well as the next. It's a bit idiosyncratic (in that it doesn't really make sense as a motion) but I've come to rely on it.

In evil, however, dj deletes only the current line. How can I remap it so that it has vim's behaviour?

I've tried a few methods and all don't work:

(defun delete-two-lines ()
  (interactive)
  (kill-whole-line)
  (kill-whole-line))
  • using key-chord.el: (key-chord-define evil-normal-state-map "dj" 'delete-two-lines)
  • trying to remap the j motion in evil to jump two lines ((evil-line-move 2)). This works but affects every use of j.
  • dd is a linewise shortcut; it's not special-cased, so I can't hook into it (why is evil so elegant...)
  • (define-key evil-mode-normal-map (kbd "dj") 'delete-two-lines): d isn't a prefix key, and this seems like it would interfere with evil's d mapping anyway

I'm at my wit's end. Help would be appreciated.

user1953221
  • 211
  • 1
  • 5

2 Answers2

5

I think your problem, that dj deletes only a single line, is caused by the binding of evil-next-visual-line to j. So, it could be solved by making j call evil-next-line instead only after an operator is input.

This can be achieved by mapping j to evil-next-line in the operator state map, while we simultaneously bind evil-next-visual-line to j in the motion state map.

I also had the same problem and the following configurations worked for me:

(define-key evil-motion-state-map   (kbd "<remap> <evil-next-line>")     #'evil-next-visual-line)
(define-key evil-motion-state-map   (kbd "<remap> <evil-previous-line>") #'evil-previous-visual-line)
(define-key evil-operator-state-map (kbd "<remap> <evil-next-line>")     #'evil-next-line)
(define-key evil-operator-state-map (kbd "<remap> <evil-previous-line>") #'evil-previous-line)
yuttie
  • 51
  • 1
  • 4
3

Should have used (define-key evil-normal-state-map "j" 'evil-next-visual-line) to remap it instead of evil-motion-state-map. Works now.

user1953221
  • 211
  • 1
  • 5