When running scroll-up
or scroll-down
, it's possible emacs isn't scrolling the number of lines requested (if you hit the start/end of the buffer for eg).
Is there a convenient way to know how many lines were actually scrolled?
When running scroll-up
or scroll-down
, it's possible emacs isn't scrolling the number of lines requested (if you hit the start/end of the buffer for eg).
Is there a convenient way to know how many lines were actually scrolled?
Here's an attempt:
(defvar jpk/scroll-count 0
"Signed number of lines scrolled in the last scroll-up or scroll-down.")
(make-variable-buffer-local 'jpk/scroll-count)
(defun jpk/scroll-tracking (orig &rest args)
(let ((start (window-start))
(error t))
(unwind-protect
(prog1
(apply orig args)
(setq error nil))
(when error
(setq jpk/scroll-count 0)))
(setq jpk/scroll-count (* (signum (- (window-start) start))
(count-lines (window-start) start)))))
(advice-add 'scroll-up :around #'jpk/scroll-tracking)
(advice-add 'scroll-down :around #'jpk/scroll-tracking)
I used count-lines
because line-number-at-pos
can be slow. But count-lines
implicitly takes the absolute value, hence the signum
. Also I'm not sure I got the error handling exactly right.
(setq max-lines (- (window-height) next-screen-context-lines))
(if (< (lines-before) max-lines) 0 max-lines)
(if (< (lines-after) max-lines) 0 max-lines)
(defun lines-before ()
"Report number of lines on current page, and how many are before or after point."
(interactive)
(save-excursion
(let
(
(opoint (point))
beg
end
total
before
after)
(forward-page)
(beginning-of-line)
(or (looking-at page-delimiter) (end-of-line))
(setq end (point))
(backward-page)
(setq beg (point))
(count-lines beg opoint))))
(defun lines-after ()
"Report number of lines on current page, and how many are before or after point."
(interactive)
(save-excursion
(let
(
(opoint (point))
beg
end
total
before
after)
(forward-page)
(beginning-of-line)
(or (looking-at page-delimiter) (end-of-line))
(setq end (point))
(backward-page)
(setq beg (point))
(count-lines opoint end))))
I took the code from count-lines-page
and turned it into two functions that outputs how many lines exist above and below the position at point.
Then, it's just a matter of finding out if the scroll will take place. In the above case, I'm finding out how many lines will be scrolled if I hit scroll-down-command
or scroll-up-command
.
Not sure if this helps. I'm a newbie in Elisp.
I use a thing like this
(defun jump-length-test (window _window-start-after)
(with-selected-window window
(unless (> 0.001 (float-time (time-subtract (current-time) buffer-display-time))) ; Don't run this function after a change of buffer.
(let* ((bottom-line-before (line-number-at-pos (window-end)))
(bottom-line-after (line-number-at-pos (window-end nil 'update))) ; NB: ‘window-start’ doesn't take the ‘update’ argument.
(vertical-displacement (- bottom-line-after bottom-line-before)))
(message "Lines scrolled: %s" (abs vertical-displacement))))))
(add-hook 'window-scroll-functions #'jump-length-test)
It checks if the difference between the current-time
and the buffer-display-time
is under 0.001 s to avoid running when you change the buffer displayed by the window (which also triggers window-scroll-functions
), and then it compares the line number of the bottom lines before and after the jump to get its length.