From c4d167f8d4f35cd5027765b2fe42b69dc4202ae3 Mon Sep 17 00:00:00 2001 From: paxcut <53811119+paxcut@users.noreply.github.com> Date: Sun, 10 Aug 2025 23:57:17 -0700 Subject: [PATCH] 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. --- .../content/text_highlighting/pattern_language.hpp | 10 ++++++++++ .../source/content/views/view_pattern_editor.cpp | 2 +- 2 files changed, 11 insertions(+), 1 deletion(-) diff --git a/plugins/builtin/include/content/text_highlighting/pattern_language.hpp b/plugins/builtin/include/content/text_highlighting/pattern_language.hpp index e91b76ca8..82b6c0c66 100644 --- a/plugins/builtin/include/content/text_highlighting/pattern_language.hpp +++ b/plugins/builtin/include/content/text_highlighting/pattern_language.hpp @@ -152,6 +152,12 @@ namespace hex::plugin::builtin { }; std::atomic m_needsToUpdateColors = true; std::atomic m_wasInterrupted = false; + std::atomic m_interrupt = false; + + + void interrupt() { + m_interrupt = true; + } TextHighlighter(ViewPatternEditor *viewPatternEditor, std::unique_ptr *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); diff --git a/plugins/builtin/source/content/views/view_pattern_editor.cpp b/plugins/builtin/source/content/views/view_pattern_editor.cpp index b105a8bfe..5bf38ae69 100644 --- a/plugins/builtin/source/content/views/view_pattern_editor.cpp +++ b/plugins/builtin/source/content/views/view_pattern_editor.cpp @@ -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(); } } }