1

I'm playing with evil-mode and this is one of the things where evil differs from vim. In vim G takes you to the last line, but evil uses Emacs end-of-buffer which for some reason takes me beyond last line to some imaginary line.

4
  • Emacs and Vim differ in how they deal with the final newline. Evil does not try working around this as it's purely concerned with emulating Vim-style editing. I've found it helpful to visualize it with fringe indicators, you may find another package of that kind useful.
    – wasamasa
    Commented Mar 23, 2017 at 17:42
  • I'm sorry, visualise what? Commented Mar 23, 2017 at 17:45
  • The final newline.
    – wasamasa
    Commented Mar 23, 2017 at 18:06
  • @wasamasa Hmm, I don't see the point of doing that. Can you explain? Commented Mar 23, 2017 at 18:08

2 Answers 2

3

The command end-of-buffer uses a variation on (goto-char (point-max)) to go to the last position in the buffer. If the buffer ends with a newline, end-of-buffer will leave you on the empty line at the end, whereas if you delete this last newline, end-of-buffer will leave you at the end of the text in the now non-empty last line.

One possible solution is to advise end-of-buffer to just go up a line if it leaves you on an empty line:

(defun my-end-of-buffer-dwim (&rest _)
  "If current line is empty, call `previous-line'."
  (when (looking-at-p "^$")
    (previous-line)))

(advice-add #'end-of-buffer :after #'my-end-of-buffer-dwim)

If you want end-of-buffer to always leave you at the beginning of the penultimate line (rather than at the end if the file has no trailing newline), you might want this instead:

(defun my-end-of-buffer-dwim (&rest _)
  "Go to beginning of line.
If current line is empty, go to beginning of previous one
instead."
  (beginning-of-line (and (looking-at-p "^$") 0)))

(advice-add #'end-of-buffer :after #'my-end-of-buffer-dwim)

And the standard advice disclaimer: You can avoid unanticipated side-effects by just creating your own end-of-buffer command and rebinding the keys, rather than using advice:

(defun my-end-of-buffer ()
  "Go to beginning of last line in buffer.
If last line is empty, go to beginning of penultimate one
instead."
  (interactive)
  (goto-char (point-max))
  (beginning-of-line (and (looking-at-p "^$") 0)))

(global-set-key [remap end-of-buffer] #'my-end-of-buffer)

Note that all of the above solutions leave you at most one line away from the end of the buffer - they do not leave you on the last non-empty line.

2
  • Thanks, your solution works! I'm new to elisp, so I haven't knew about advice-add. I didn't want to remap keys, because in evil G is a motion, so you can delete till the end of file with dG etc. I don't think tht.his would work if I would just remap key to another function. But maybe I don't know lisp well enough. Commented Mar 23, 2017 at 19:49
  • If you wish to remap my-end-of-buffer to the default shortcut (overriding it), use (global-set-key "\M->" #'my-end-of-buffer). Commented Jan 4 at 12:09
0

This probably doesn't answer your question, question about stopping Emacs scrolling past end-of-buffer.

(setq next-line-add-newlines t)

The problem with this though is that mouse scroll is not going paste end-of-buffer, and you will end up with alot of empty lines in your files (pressing down arrows adds newlines, up arrow does not remove them).

1
  • Yeah, this doesn't answer my question Commented Mar 23, 2017 at 14:05

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.