bugGNU nano - Bugs: bug #60041, after certain edits, miscoloring...


You are not allowed to post comments on this tracker with your current authentication level.

bug #60041: after certain edits, miscoloring will still occur

Submitted by:  Benno Schulenberg <bens>
Submitted on:  Thu 11 Feb 2021 11:12:05 AM UTC  
Severity:  2 - Minor Status:  None
Assigned to:  None Open/Closed:  Open

Wed 17 Feb 2021 03:28:04 PM UTC, comment #2: 

When we would recalculate the multidata every time the multiline-matching situation of the current line has changed, it would mean that for C files every character typed or deleted in a line would cause of full recalculation: the c syntax contains a multiline coloring rule for preprocessor directives, and that rule's end regex matches almost every line.  But almost no line will actually be marked as ENDSHERE, meaning that for almost all lines check_the_multis() will find a mismatch between multidata and current regex matches, leading to a full recalculation of the multidata.  This is unacceptably wasteful.

Maybe all lines that match the end regex should be marked as ENDSHERE even if there is no corresponding start match?

(Note that currently every typed or deleted character in a C file causes a full refresh, a full redraw of the contents of the edit window.  This is wasteful too, but I never noticed it until now.)

Benno Schulenberg <bens>
Project Administrator
Thu 11 Feb 2021 11:47:53 AM UTC, comment #1: 

The only solution to this would be: to recalculate the multidata every time the multiline-matching situation of the current line has changed (or the matching situation of earlier lines, in case of a multiline paste or insert -- not just a large paste or insert, but any paste or insert that is more than one line).

That looks costly.  But... at the moment paging around at the end of the NEWS file takes around 65 milliseconds (on my machine, and when using the Python syntax), whereas precalculating takes only 30 milliseconds.  Thus it would be faster to always precalculate the multidata and not do any backtracking: then paging around costs from around 10 to 35 milliseconds.  (But this normal painting can be made faster when the multidata can be trusted: there is no need to seek forward for an end match either, so paint times will be at most around 10 milliseconds.)

The 65 milliseconds is for a 2000-line file.  When the file is ten thousand lines, the painting time is around 190 milliseconds.   This becomes unacceptable.

But... these miscolorings can occur with only a few syntaxes (elisp, markdown, python), that have coloring rules where the start= and end= regexes can match the same thing.  For most syntaxes the start= and end= regexes are distinct and will never match the same thing.  Is it worth the trouble to always do a full recalculation when this benefits just a few syntaxes and means an unnecessary waste of CPU cycles for most others?  And when furthermore the miscolorings will occur only if the user jumps in the file (with M-\, M-/, M-G, or Alt+PgUp/PgDn, or even Ctrl+Up/Down), not when they simply scroll or PgUp/PgDn?

What if I just add a precalc() call in the ^L Refresh function, so that the user can force a fully correct repainting of the file, and drop all the costly attempts at doing the right thing?  That would make the normal painting fast again, and would be good enough in all practical cases: because no one reported any miscoloring with any syntax for quite a while -- either they don't encounter it, or when they do encounter it, they simply close the file, reopen it, and things are fine.

Benno Schulenberg <bens>
Project Administrator
Thu 11 Feb 2021 11:12:05 AM UTC, original submission:  

To reproduce, run:

src/nano --rc=syntax/python.nanorc -Ypython +222 NEWS

Then type: ''' ^V ^V ^V '''
See that the text before the cursor gets colored green.
Now type: M-\ '''
The text after the cursor becomes green, and we know that the text that was green before this last edit should now be uncolored.
Now type: M-/ '''
See that the text before the cursor does not get colored.  But it should, because there is now a matching ''' before it.

What happens is that after typing the ''' at the head of the buffer, the line with the next ''' gets marked as an end match (ENDSHERE), but the line with the next ''' (which was marked with ENDSHERE earlier) does not get changed, so it stays marked with ENDSHERE.  Which means that when we type the ''' at the end of the buffer, the coloring code backtracks to find a start match, finds the line with the ''', but sees that it is marked as ENDSHERE, believes it, and concludes that there is no matching start, and leaves things uncolored.

Benno Schulenberg <bens>
Project Administrator


No files currently attached


Depends on the following items: None found

Items that depend on this one: None found


Carbon-Copy List
  • -email is unavailable- added by bens (Submitted the item)

    Do you think this task is very important?
    If so, you can add your encouragement to it.
    This task has 0 encouragements so far.

    Only logged-in users can vote.




    Follows 1 latest change.

    Date Changed by Updated Field Previous Value => Replaced by
    2021-06-16 bens Assigned tobens => None

    Back to the top

    Powered by Savane 3.7