ENB: A greatly simplified colorizer!

52 views
Skip to first unread message

Edward K. Ream

unread,
Nov 5, 2024, 5:15:44 AM11/5/24
to leo-editor

PR #4147 fixes a medium-scale performance bug. While doing so, I discovered two ways of collapsing the complexity of the colorizer.


Naive expectations


We have the right to expect that the qsh will work as follows:

- When changing nodes, the qsh should call _redraw for every line of p.b.

- Otherwise, we expect the qsh to issue highly optimized calls to _redraw when users edit text.


In fact, the qsh called _redraw for all lines of p.b whenever the user changed p.b. Ouch!


The PR identifies two culprits as the cause of the performance bug.


jedit.colorizer


Previously, this method always forced a full redraw. That makes no sense! Now it contains the following new code:


# #4146: Fully recolor p.b *only* if necessary.

old_language = self.language

self.updateSyntaxColorer(p)

if p.v == self.old_v and self.language == old_language:

    return


jedit._redraw


Imagine my surprise when I found the following code at the start of jedit._redraw:


block_n = self.currentBlockNumber()

n = self.prevState()

if p.v == self.old_v:

    new_language = self.n2languageDict.get(n)

    if new_language != self.language:

        self.language = new_language

        self.init()

else:

    self.updateSyntaxColorer(p) # Force a full recolor

    assert self.language

    self.init_all_state(p.v)

    self.init()


Huh??? My intense study of the code showed me that jedit._redraw was a callback for qsh.highlightBlock. Nothing else should ever be calling jedit._redraw. That's why I added the leading underscore.


Forcing the qsh to do a full redraw inside _redraw is utterly misguided. It is a gross interference with the qsh!


I immediately removed this bizarre code. All of a sudden, for the first time in Leo's history, the qsh worked as one would naively expect!


Summary


How did Leo's legacy syntax colorer have any chance of working? It's a mystery.


I fixed the two culprits as follows:

- jedit.colorize forces a full redraw only when Leo changes nodes.

- jedit._redraw never forces a full redraw.


After these changes, the qsh operates exactly as one would naively expect.


Edward

Reply all
Reply to author
Forward
0 new messages