<!-- language-all: lang-el --> 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.