See also Emacs bug tracker feature request #22404 (which has not yet been implemented, but the mailing archive contains a rough draft rudimentary patch that creates a new hook for this specific issue): https://debbugs.gnu.org/cgi/bugreport.cgi?bug=22404
Whenever point moves outside of the visible window, the window-scroll-functions hook is triggered -- at the very least one (1) time -- before the screen updates visually. The window-scroll-functions hook is one of the last hooks available to the user via elisp from which to obtain the new values for window-start and window-end before a visual redisplay occurs. It is necessary to use the optional second argument in window-end -- i.e., t for force.
The function abo-abo-wsf-fn when attached to the window-scroll-functions hook will generate the new values for window-start and window-end prior to visual redisplay. The hook is using a buffer-local argument.
(defun abo-abo-wsf-fn (win _start)
"A function attached to the `window-scroll-functions` hook."
(when
(and
(window-live-p (get-buffer-window (current-buffer)))
(not (minibufferp)))
(let* (
(selected-window (selected-window))
(window-start (window-start selected-window))
(window-end (window-end selected-window t)) )
(message "window-start: %s | window-end: %s" window-start window-end) )))
(add-hook 'window-scroll-functions 'abo-abo-wsf-fn nil t)
COMPLEXITIES: The above-example is not designed to deal with the complexities of a point being partially visible, or situations when the window-scroll-functions hook is triggered more than one time per command loop. The links in the comments underneath the question of the original poster deal with those complexities. The original poster has not requested specific assistance in relation to those issues; however, so they are excluded from this limited example.