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.
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.
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).