@Gilles answer is the right way to go. I’ll keep this one here for the information and the hacks.
I believe the point
movement is performed by the C functions
window_scroll_line_based
and window_scroll_pixel_based
(dependinyg
on your frame parameters). These functions are not exposed to the lisp
machine, so you can’t advise them. You would have to advise functions
that call them.
Two of the (lisp accessible) functions that can do this are
scroll-up
and
scroll-down
.
Here’s how I found out about them:
- Go to some long buffer.
- Select a small region.
- Call,
M-x (put-text-property (region-beginning) (region-end) 'point-left (lambda (&rest _) (error "Point leaving")))
. This will throw an error when point leaves the region.
- Activate
M-x toggle-debug-on-error
.
- Make sure point is inside this region.
- Scroll with the mouse wheel until point is dragged out of the region.
You will be given a backtrace buffer like this one, which clearly
points out the scroll-down
function.
Debugger entered--Lisp error: (error "Point leaving")
signal(error ("Point leaving"))
error("Point leaving")
(lambda (&rest _) (error "Point leaving"))(1508 1192)
scroll-down(10)
funcall(scroll-down 10)
mwheel-scroll((double-mouse-4 (#<window 50 on *Backtrace*> 1299 (578 . 545) 77086296 nil 1299 (57 . 25) nil (398 . 20) (10 . 21)) 2))
funcall-interactively(mwheel-scroll (double-mouse-4 (#<window 50 on *Backtrace*> 1299 (578 . 545) 77086296 nil 1299 (57 . 25) nil (398 . 20) (10 . 21)) 2))
call-interactively(mwheel-scroll nil nil)
command-execute(mwheel-scroll)
I followed scroll-down
to its C definition, which led me to
window_scroll
, which lead me to those two functions above.
What you can do
You can advise scroll-down/up
with an around
advice (as well as
any other functions that might also result in point movement). Use this
advice to check if the position of point
has changed and record the
old position. And then do whatever you want with it.
Be warned, advices are very unreliable when it comes to C functions.
Some important functions have special addresses in byte-compiled code,
which means advices on them aren’t called when the code is compiled. I
don’t think that will be the case here, but I figured you should no.