good-scroll.el icon indicating copy to clipboard operation
good-scroll.el copied to clipboard

Good scrolling when navigating by moving the cursor

Open neonmoe opened this issue 3 years ago • 5 comments

Is your feature request related to a problem? Please describe. I usually don't use the scroll wheel or page down/up keys to navigate emacs, I skip around by paragraph. This causes the window to snap to the new position, but I would prefer if it scrolled smoothly instead of snapping, like this package does when scrolling with the scroll wheel or page down/up keys.

Describe the solution you'd like When the window snaps to the new position, it could be snapped back to where it was (or as far back as possible while keeping the cursor inside the window), and then running the regular good-scroll movement logic to move smoothly to where the window was originally snapped.

Describe alternatives you've considered Entirely reimplementing the window snapping that happens when moving around with the cursor, so that it uses the good-scroll scrolling functionality straight away. However, this seems like it would require a lot of replacing functionality that isn't needed by the solution above.

Additional context This feature feels like it would be better off being its own package, but on the other hand, good-scroll has scrolling logic that I think would be beneficial to share with this feature. In any case, I've implement a sort-of-working proof of concept in my fork, but it still requires some tweaking, and might be overall relatively misguided, as it's the first elisp thing I've written. The actual functionality also looks a little weird when scrolling a lot (out-pacing the smooth scrolling), but I think that's a necessary side-effect of the solution I came up with.

And finally, thank you for writing this package, it's made my daily emacs use a much nicer experience!

neonmoe avatar Oct 22 '21 17:10 neonmoe

Thanks for this feature request! I tried your proof of concept and I like the idea.

One of the reasons I haven't implemented this yet is that good-scroll-move needs the total distance in pixels. It can be hard to get something like the distance in pixels to the top of a buffer from somewhere deep in the middle, and there might be performance issues. It looks like you handled this by not scrolling more than a full screen, which seems like a great compromise.

When trying your proof of concept, I noticed a flicker where you see the scroll at the destination in between the time when the cursor moves and the time of the next good-scroll--render call. One way to fix this would be to put the logic in post-command-hook instead of good-scroll--render, because functions in post-command-hook are called after every cursor movement. This would be kind of like your "reimplementing the window snapping that happens when moving around with the cursor" idea, but I don't think it would be that hard.

io12 avatar Oct 29 '21 10:10 io12

Don't have anything useful to contribute atm, but just chiming in that this would be a fantastic feature! I hadn't checked out good-scroll in a while, but coming back to it I'm elated to see how good it is now, and with this feature it would definitely be the ideal package!

tefkah avatar Nov 04 '21 12:11 tefkah

I pushed what I have so far to the cursor-scrolling branch. What's confusing is something's setting (point) to a value less than (window-start) in between window-scroll-functions and good-scroll--render. This causes an error when moving the cursor backwards one line when it's at the top of the window. I haven't figured out so far what's trying to move the cursor between the end of window-scroll-functions and the beginning of good-scroll--render. It might be related to Bug #22404.

io12 avatar Nov 06 '21 15:11 io12

I think the point movement inside window-scroll-functions/good-scroll--after-window-scroll is being reset, possibly by the C redisplay code. This happens with both Emacs 27.2 and df2438d3695e065d4037e1c26a0c769c373f914c (the latest git commit).

io12 avatar Nov 12 '21 03:11 io12

Yeah, seems to be reverted at the very end of redisplay_window() in xdisp.c.

io12 avatar Nov 12 '21 05:11 io12