Text wrapping in Scintilla is a background activity that can take a long time to fully wrap a document. This may take seconds or even minutes for a really huge document or slow computer. It also means that applications manipulating the editor may encounter partially wrapped situations where calls do not have their intended behaviour.
An example is an application setting the scroll position to match the previous time that document was showing. Wrapping may move that scroll position out of view. There are several issues on the trackers referencing this problem such as this issue.
https://sourceforge.net/p/scintilla/bugs/1395/A possible solution is to defer scrolling vertically until after wrapping has completed or, at least passed the desired scroll position so that the view is stable. This is the purpose of a proposed API SCI_SCROLLVERTICAL(docLine, subLine) which bases scroll positioning on a combination of a document line and a sub-line within that document line. This is more stable than using a visual line as it better handles changes in view width.
This API will first synchronously set the scroll position based on no wrapping information which is correct when wrap is off and an OK first approximation when wrapping is on. It remembers the desired (docLine, subLine) scroll position and uses that inside the wrapping code to maintain a stable view. The desired scroll position is forgotten once the document has been fully wrapped or the user manually scrolls.
If the user's manual scrolling did not forget the desired position then the effect is to scroll back to the desired position repeatedly which is frustrating. A problem then is to work out when a scroll is user-initiated. This is now done by treating every SetVerticalScrollPos call as user initiated except for those performed inside WrapLines. Earlier attempts tried to intercept the different ways a user can cause a scroll but the number of places grew and more would have to be added for each platform. This does require platform layers to call the superclass Editor::SetVerticalScrollPos() inside their own SetVerticalScrollPos implementation. There is a good chance that the user-initiated scrolling detection will need refinement.
Another approach would be to store the byte index (position) of the first character in the view as the scrolling anchor. That may ensure scroll restoration shows more of the initial text when the window changed width since saving but it relies on more expensive calls.
From the application side, SciTE, for example has code like this when saving the scroll position.
ScrollDocWithOffset SciTEBase::GetCurrentScrollPosition() {
const SA::Line lineDisplayTop = wEditor.FirstVisibleLine();
const SA::Line lineDocTop = wEditor.DocLineFromVisible(lineDisplayTop);
const SA::Line subLineTop = lineDisplayTop - wEditor.VisibleFromDocLine(lineDocTop);
return { lineDocTop, subLineTop };
}
Here is SciTE's code when restoring a scroll position.
wEditor.ScrollVertical(fp.scrollPosition.lineDoc, fp.scrollPosition.subLine);
A patch implementing SCI_SCROLLVERTICAL is attached.
Applications will have to choose to use this new API for it to have any effect and platform layers will also need to add the one call mentioned above.
Neil