Oni: Weird scrolling behavior when `scrolloff` is set to a non-zero value

Created on 20 Apr 2017  路  7Comments  路  Source: onivim/oni

To reproduce:

  • In a buffer with more lines than fit in the window, :set scrolloff=1
  • Move using j or k

Expected behavior:

The cursor moves down or up, but the content of the window doesn't change until the cursor reaches the penultimate line when moving down or the second line when moving up

Observed behavior:

When starting from the top, as soon as the cursor is on the second line, the content starts to scroll with every move. When the cursor is in a lower line at the time the setting is changed, moving up also causes weird scrolling

This is using a current checkout (d9e6571) and neovim 0.1.7

bounty-50 bug help wanted

Most helpful comment

Yep, I can reproduce this. That's some weird behavior.

All 7 comments

Yep, I can reproduce this. That's some weird behavior.

I can reproduce this too. I have scrolloff 3 in my vimrc and oni just moves the content at every 5 j scrolldown.

Actually, if scrolloff is not zero, another weird scrolling occurs when you scroll from the bottom of the file up using mousewheel. The content just keeps glitching while going up. @ohle Can you reproduce this one? or it's just my configuration problem?
I've temporarily disabled scrolloff if Oni is detected.

I'm also having this problem. Took me a while to find this issue here to see what the problem was. Looking forward to have this fixed.

Put a bounty on this in case someone is interested in checking it out, as it sounds like it is impacting several people:
https://www.bountysource.com/issues/44356173-weird-scrolling-behavior-when-scrolloff-is-set-to-a-non-zero-value

There are a few places to look in terms of investigation:

  • browser\src\neovim\NeovimInstance.ts - check out the msgpack-rpc messages we receive from Neovim in this scenario
  • browser\src\Screen.ts - manages the state of the screen, and it can actually be queried at runtime
  • browser\src\Renderer\CanvasRenderer.ts - if the state of the screen is updating correctly, then it's likely a problem with the render strategy.

I'm going to have a bit of a look into this, and see what is causing it.

From a quick 10 min look, I can see that Oni is receiving the messages for scrolling when moving from line 2 to line 3, that it should be getting at the bottom of the window instead. I'm seeing this in the Session.ts file, so I need to trace that backwards and see if I can find what is causing it to be sent.

From that, it doesn't seem to be a render strategy issue, the renderer is doing exactly what it has been told, its just the instructions are wrong.

I'll keep looking and see if I can work it out, if not then it will have helped me understand the code base a little better.

To bring in some discussion from PR #802:

It looks like the winline() call that is used to update the screen mapping doesn't work well with scrolloff values.
However, as other parts of the code base depend on this call, the fix is more complicated than just removing it.

From @bryphe :

This whole pipeline is pretty hacky and convoluted - really what this is building for us is one function - a function that maps buffer space (like a line and column in a buffer) into screen space - and I suspect there is a way to simplify this without all the back-and-forth events and crazy iteration in init.vim.

I'm trying to explore right now if there is an alternative fix - instead of needing to have this OniUpdateWindowDisplayMap in init.vim, perhaps we can do a pull instead from the Oni side, and based on the info we already have in the event context, and the state of the buffer, maybe we can simplify and build up that bufferSpaceToScreenSpace function. If we go this route, we could get rid of the hacky iteration + winline code that is causing issues with scrolloff (and I suspect it is causing some other problems as well), and have a more robust solution in general.

A solution like this should both make cases like scrolloff work, as well as making the process as a whole more robust and easily debugged, as currently this interaction can only be debugged using the message-pack calls.

Was this page helpful?
0 / 5 - 0 ratings