Non-blocking idle styling

57 views
Skip to first unread message

Neil Hodgson

unread,
Nov 4, 2015, 4:30:10 AM11/4/15
to Scintilla mailing list
This feature has been requested multiple times before now. Currently, before painting, Scintilla calls the lexer to style all the text that is to be displayed. When rapidly scrolling in a large document, this causes the application to not respond to user actions, possibly for lengthy periods. Also, when an application shows two views for one document then changes in the earlier view will cause delays as styling is performed for the range between the earlier and later view.

The attached patch permits styling to be performed in small sections during idle time allowing Scintilla to remain responsive. The cost is that the display may show the text with incorrect styles until the styling catches up.

As well as a mode SC_IDLESTYLING_NONE corresponding to the current behaviour, there is SC_IDLESTYLING_TOVISIBLE which causes styling up to the end of the visible area to be performed during idle time. The API to set this is SCI_SETIDLESTYLING.

SC_IDLESTYLING_AFTERVISIBLE will style visible text before painting and then incrementally style the remainder of the file. This makes it likely that scrolling further down will only show already styled text so will be smooth. Finally, SC_IDLESTYLING_ALL is a combination of SC_IDLESTYLING_TOVISIBLE and SC_IDLESTYLING_AFTERVISIBLE, styling all of the document during idle.

These new options will be less computationally efficient than the current behaviour as smaller portions are lexed and some extra lexing will occur when the document is styled after the visible area.

Some similar styling is performed when wrap is turned on as wrapping requires accurate text position information which depends on the text being styled. Because of this, wrapping takes precedence and the new modes have no effect when wrap is turned on.

Some of this is a little complex, particularly on Cocoa which has a larger area ‘visible’ due to responsive scrolling. There is a good chance that there are bugs in the code so watch for them and report them. I’m not sure all 4 modes are needed (the two that style after the visible area may not be worthwhile) so if no one wants them they’ll be dropped to simplify the code. This feature is too late so will not be included in version 3.6.2.

The size of the styled segments were tuned for my main development machines and could be tweaked if they make scrolling jerky or have other problems. On Windows, scrolling messages are received quite rapidly (possibly 100-200 per second) so the code tries to keep styling during scrolling to 5 milliseconds per scroll message. When idling, it opens up with larger batches taking 20 milliseconds.

The segment scaling requires accurate (about 1ms) time measurement so may not work on platforms that are using less accurate clocks for the ElapsedTime class. Each platform contained in the core distribution appear to work.

Neil
IdleStyling.patch

Neil Hodgson

unread,
Nov 11, 2015, 3:33:14 AM11/11/15
to scintilla...@googlegroups.com, scite-i...@googlegroups.com
   The idle styling feature has now been committed.

   This is also exposed as properties in SciTE with idle.styling=1 meaning that the visible area is painted without waiting to be fully styled. Then styling is performed in the background as an idle task, eventually catching up with the displayed area. This may help scrolling in very large files. idle.styling=2 will style after the visible area as an idle task so that the area scrolled to is likely to already be styled. idle.styling=3 combines 1 and 2 so the whole file is incrementally styled as an idle task. The default idle.styling=0 is the same behaviour as the current release.

   output.idle.styling affects the output pane.

   Some features that depend on style information such as bracket highlighting may behave incorrectly or differently with this option.

   Available from the Mercurial repositories:
   and from

   Neil

Reply all
Reply to author
Forward
0 new messages