fix: Highlighter can fail to update a files contents. (#2400)

If you project has two patterns and one is very big, switching providers
while the big file is being highlighted makes the small one skip its own
coloring. The error was caused by a failure to interrupt the ongoing
lengthy highlighting process in a timely manner. It appears that calling
task interrupt allows the task to run to completion and when the task
runs to completion then the retrying mechanism is not trigger and the
small pattern never has a task assigned for coloring.

This was fixed by creating a variable that signals the intention to
interrupt the current highlighting process. The most used function in
the highlighter (used to update the current token) checks the variable
and throws an out of range exception causing the interruption of the
current highlighter and triggering the retry mechanic.
This commit is contained in:
paxcut
2025-08-10 23:57:17 -07:00
committed by GitHub
parent 50f1fe2b2d
commit c4d167f8d4
2 changed files with 11 additions and 1 deletions

View File

@@ -152,6 +152,12 @@ namespace hex::plugin::builtin {
};
std::atomic<bool> m_needsToUpdateColors = true;
std::atomic<bool> m_wasInterrupted = false;
std::atomic<bool> m_interrupt = false;
void interrupt() {
m_interrupt = true;
}
TextHighlighter(ViewPatternEditor *viewPatternEditor, std::unique_ptr<pl::PatternLanguage> *patternLanguage ) :
m_viewPatternEditor(viewPatternEditor), patternLanguage(patternLanguage), m_needsToUpdateColors(true) {}
@@ -315,6 +321,10 @@ namespace hex::plugin::builtin {
}
void next(i32 count = 1) {
if (m_interrupt) {
m_interrupt = false;
throw std::out_of_range("Highlights were deliberately interrupted");
}
if (count == 0)
return;
i32 id = getTokenId(m_curr->location);

View File

@@ -578,7 +578,7 @@ namespace hex::plugin::builtin {
m_changesWereParsed = false;
taskHolder = TaskManager::createBackgroundTask("HighlightSourceCode", [this](auto &) { m_textHighlighter.highlightSourceCode(); });
} else {
taskHolder.interrupt();
m_textHighlighter.interrupt();
}
}
}