A smooth scrolling plugin for Kakoune

Actually there’s one more such return statement that should be changed to exit, on line 171. This one will cause <c-d> to flash-back 15 lines after scrolling. Hand-override it solves the issue. Now the plugin works fine! I’ll definitely keep using it in the future ; )

Here’s some extra fun facts…
AFAIK, the %sh{...} block of kakoune behaves similar to a raw script file, not a function. But the behavior of return outside a function differs:

In dash, return outside a function acts the same as exit

In bash, return outside a function triggers an error

In zsh and ksh (strictly speaking zsh's ksh compilant mode), return outside a function has no effect

I didn’t managed to find the behaviour of the original bourne shell, just once again shocked by how much trouble the shells mess can cause lol (I am a victim too when writing my own plugin)

I am surprised to discover that ShellCheck doesn’t detect and report this problem. I’d file an issue myself, except I already have a bunch of other stuff on my plate at the moment.

For the <c-u> and <c-d> issue, I played around it just now, and have found its difficulty… It seems that kakoune’s -draft switch does not works on view-moving commands like <c-u> and <c-d>

However, I still managed to get the behavior I want (always smooth scroll when moving view) by doing some hacks:

define-command -params 1 \
    -docstring "smooth scroll 1/$1 page, positive for down" \
    smooth-scroll-by-page %{
        set-option window scroll_selections
        evaluate-commands %sh{
            printf ":smooth-scroll-move %s\n" "$(expr ${kak_window_range##* } / $1)"
        }
}

And on line 106 of smooth-scroll.kak, change select ... to try %{ select ... }.

Now I’ll explain the hacks. The basic idea is to call the internal smooth-scroll-move command directly. The problem is that when doing pure page scrolling, the resulting selection can not be known in advance, depending on whether current selection will get out of the window. Thankfully v* keys used by kakoune-smooth-scroll can handle such selection movement. So the hack is to disable the plugin’s builtin selection restoring mechanism.

This line:

        set-option window scroll_selections

cleans potential selection values left by the last, normal scroll.
And the hack in the plugin’s source will remove an error message for assigning a null value to %opt{selections_desc}.

Do you think the try %{...} change in the source file can be merged? It is mostly useless for normal use cases, but also not hamful AFAIK.

I fixed that too now, thanks for the heads up.

That’s very good information, thanks!

That would have prevented this from happening, since kakoune-shellcheck is awesome and I use it when writing all my scripts!

Yep, #3616 is the Kakoune issue I opened regarding this for reference. I think it makes sense to expect -draft mode to also preserve the viewport.

I added this change along with the return fix and merged the v2 branch to master now.

Your changes for supporting <c-d>/<c-u>/<c-f>/<c-b> seem simple enough – in addition we’d have to check whether the user is mapping those keys with the scroll_keys_normal option and treat them separately if they do. I’d welcome a PR if you would like to contribute your changes.

Actually, that small hack is not good enough, or even wrong. I found that it creates a problem on the opposite side. The behavior of <c-u> etc. in vanilla kakoune is:

keep the cursor if possible, put cursor on top/bottom otherwise

My expected behavior with smooth scrolling is

same cursor behavior with vanilla, but unconditionally smooth-scroll

The behavior of the plugin now is:

same cursor behavior with vanilla, but only smooth-scroll when cursor moves

My hack’s behavior is:

unconditionally move the cursor with the viewport, 
keeping the display-position of the cursor unchanged.

unconditionally smooth scroll.

Also, it uses window’s width instead of height to calculate distance…


----------------

Anyway, here’s an updated version of hack:

define-command -hidden -params 1 smooth-scroll-by-page %{
    evaluate-commands %sh{
        distance=$(expr $kak_window_height / $1)
        if [ $kak_cursor_line -ge $(( ${kak_window_range%% *} + $distance )) ] \
        && [ $kak_cursor_line -le $(( ${kak_window_range%% *} + $distance + $kak_window_height )) ];
        then
            printf 'set-option window scroll_selections %s\n' "$kak_selections_desc"
        else
            printf 'set-option window scroll_selections\n'
        fi
        printf "smooth-scroll-move %s\n" "$distance"
    }
}

It first tests if the cursor will fall out of window after scrolling. If so, it does not keep track of the cursor and let the scrolling decide where the cursor rests at last. If the cursor will still be in the screen, it sets scroll_selections, as ordinary scroll commands.

The final behavior is (still not exactly what vanilla kak provides, but good enough for me):

· unconditionally smooth scrolls

· keep the cursor unchanged, if possible

· otherwise, keep the display position of the cursor unchanged
(compared to placing the cursor on top/bottom of window in vanilla kakoune)

I am glad to commit a PR after using the hack for some more days for testing.

1 Like

A thread bump for a good plugin with asciinema show and tell on a wsl.exe. I had small page scroll issues but this plugin has cleaned it up for me kak -ui ncurses. Thanks @bravekarma and @Guest0.

asciicast
Bye :wave:

Hi Duncan, happy to hear it has been working well for you. I also work in WSL and can recommend Windows Terminal if you aren’t using it. It has faster rendering which helps with this plugin and I encountered fewer rendering issues with terminal apps overall, compared to conhost (default terminal with wsl.exe).

good-to-go: preview windows terminal on. Although It’s alot heavier though than vanilla and sadly all I use in it is tmux, but I’m ok with that.

ms have done the wsl.exe well. The $ wsl --export and --import can give a solid foundation on it for thumbnail travel, still yet to try it though.

Cool, bye :wave:

1 Like