Good day,

I wanted to use evil to move a few lines down or up at once, less than with evil-scroll-down/up, but more than one line. I made a brief function:

defun  go-up-few-lines ()
  "Insert a todo-subheading"
  (evil-previous-line 4)

It works, however when I enter a visual mode it stops working. Even usual previous line doesn't work if I try to execute it with M-x. When I press the shortcut button previous line works, but go up a few lines command. I am using doom emacs on a MacOS. How can I make go up few lines work in visual mode also?

  • Do you use a normal keyboard or some another types, like bepo or azerty? since in these some movement keys are not implemented in doomemacs.
    – Ian
    Oct 27, 2023 at 7:38
  • I use built-in Mac keyboard and US layout
    – Rareform
    Oct 27, 2023 at 7:45

1 Answer 1


EDIT in response to comment

Interestingly, the command in the answer below seems to work only when invoked from a keyboard shortcut; you could bind it (e.g. to, capital, 'K') as follows:

(evil-global-set-key 'motion (kbd "K") #'my-evil-go-up-few-lines)

Due to how marking a line is implemented by evil, it is not obvious to me how to use evil commands for this programmatically, however, it anyway is preferable to use 'native emacs' functions, if possible, in 'programs'.


I am not sure how evil works exactly, but it is (somewhat) documented here. It mentions that using evil-declare-motion 'ensures that it behaves correctly in visual state'.

However, for this tiny modification, I would first inspect the evil-previous-line function itself, and conclude it is easiest to just adapt it to a custom version as follows:

(evil-define-motion my-evil-go-up-few-lines (count)
  "Move the cursor 4 times COUNT lines up."
  :type line
  (let (line-move-visual)
    (evil-line-move (- (* (or count 1) 4)))))
  • 1
    Hey, I've tested it out. For me it seems to have exactly the same issue, namely nothing happens and I don't move in the visual mode.
    – Rareform
    Nov 19, 2023 at 15:47
  • I did not notice it before, but indeed it seems to work only by calling it from a keyboard shortcut; it works here after binding it as follows (e.g. on k): (evil-global-set-key 'motion (kbd "K") #'my-evil-go-up-few-lines). Nov 19, 2023 at 19:09
  • 1
    This works, noteworthy is that your function works, while mine with evil-previous-line doesn't.
    – Rareform
    Dec 2, 2023 at 13:46

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

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