From e15bb2386b75589731e2e33ca1be8079564d9734 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mart=C3=ADn=20Lucas=20Golini?= Date: Mon, 3 Mar 2025 12:29:53 -0300 Subject: [PATCH] Fix syntax highlight error in sub-syntaxes due to an incorrect line cache movement on added lines. Add a new event to track the number of visible lines changes in UICodeEditor. --- include/eepp/scene/event.hpp | 1 + include/eepp/ui/doc/documentview.hpp | 5 +++++ src/eepp/ui/doc/documentview.cpp | 22 ++++++++++++++++++++++ src/eepp/ui/doc/syntaxhighlighter.cpp | 3 ++- src/eepp/ui/uicodeeditor.cpp | 9 +++++++-- 5 files changed, 37 insertions(+), 3 deletions(-) diff --git a/include/eepp/scene/event.hpp b/include/eepp/scene/event.hpp index 37a27e4ac..a86bd83b5 100644 --- a/include/eepp/scene/event.hpp +++ b/include/eepp/scene/event.hpp @@ -116,6 +116,7 @@ class EE_API Event { OnScrollChange, OnModelChanged, OnWindowToFront, + OnVisibleLinesCountChange, NoEvent = eeINDEX_NOT_FOUND }; diff --git a/include/eepp/ui/doc/documentview.hpp b/include/eepp/ui/doc/documentview.hpp index a845cc44f..33559420f 100644 --- a/include/eepp/ui/doc/documentview.hpp +++ b/include/eepp/ui/doc/documentview.hpp @@ -155,6 +155,8 @@ class EE_API DocumentView { void onFoldRegionsUpdated(); + void setOnVisibleLineCountChange( std::function onVisibleLinesCountChangeCb ); + protected: std::shared_ptr mDoc; FontStyleConfig mFontStyle; @@ -168,6 +170,7 @@ class EE_API DocumentView { bool mPendingReconstruction{ false }; bool mUnderConstruction{ false }; bool mUpdatingFoldRegions{ false }; + std::function mOnVisibleLineCountChange; void changeVisibility( Int64 fromDocIdx, Int64 toDocIdx, bool visible, bool recomputeOffset = true, bool recomputeLineToVisibleIndex = true ); @@ -184,6 +187,8 @@ class EE_API DocumentView { bool recomputeLineToVisibleIndex = true ); void moveCursorToVisibleArea(); + + void onVisibleLinesCountChange(); }; }}} // namespace EE::UI::Doc diff --git a/src/eepp/ui/doc/documentview.cpp b/src/eepp/ui/doc/documentview.cpp index aa99bf02a..ca328821c 100644 --- a/src/eepp/ui/doc/documentview.cpp +++ b/src/eepp/ui/doc/documentview.cpp @@ -273,6 +273,8 @@ void DocumentView::invalidateCache() { mPendingReconstruction = false; + onVisibleLinesCountChange(); + Log::debug( "DocumentView for \"%s\" generated in %s", mDoc->getFilePath(), clock.getElapsedTime().toString() ); } @@ -430,9 +432,12 @@ void DocumentView::setPendingReconstruction( bool pendingReconstruction ) { } void DocumentView::clearCache() { + auto visibleLines = mVisibleLines.size(); mVisibleLines.clear(); mDocLineToVisibleIndex.clear(); mVisibleLinesOffset.clear(); + if ( mDoc && visibleLines != mDoc->linesCount() ) + onVisibleLinesCountChange(); } void DocumentView::clear() { @@ -487,6 +492,8 @@ void DocumentView::updateCache( Int64 fromLine, Int64 toLine, Int64 numLines ) { Int64 oldIdxFrom = static_cast( toVisibleIndex( fromLine, false ) ); Int64 oldIdxTo = static_cast( toVisibleIndex( toLine, true ) ); + auto visibleLinesCount = mVisibleLines.size(); + // Remove old visible lines mVisibleLines.erase( mVisibleLines.begin() + oldIdxFrom, mVisibleLines.begin() + oldIdxTo + 1 ); @@ -535,6 +542,9 @@ void DocumentView::updateCache( Int64 fromLine, Int64 toLine, Int64 numLines ) { recomputeDocLineToVisibleIndex( oldIdxFrom ); verifyStructuralConsistency(); + + if ( visibleLinesCount != mVisibleLines.size() ) + onVisibleLinesCountChange(); } void DocumentView::recomputeDocLineToVisibleIndex( Int64 fromVisibleIndex, bool ensureDocSize ) { @@ -696,6 +706,8 @@ void DocumentView::changeVisibility( Int64 fromDocIdx, Int64 toDocIdx, bool visi if ( recomputeLineToVisibleIndex ) eeASSERT( mDocLineToVisibleIndex.size() == mDoc->linesCount() ); + + onVisibleLinesCountChange(); } bool DocumentView::isFolded( Int64 docIdx, bool andNotFirstLine ) const { @@ -792,4 +804,14 @@ void DocumentView::verifyStructuralConsistency() { #endif } +void DocumentView::onVisibleLinesCountChange() { + if ( mOnVisibleLineCountChange ) + mOnVisibleLineCountChange(); +} + +void DocumentView::setOnVisibleLineCountChange( + std::function onVisibleLinesCountChangeCb ) { + mOnVisibleLineCountChange = std::move( onVisibleLinesCountChangeCb ); +} + }}} // namespace EE::UI::Doc diff --git a/src/eepp/ui/doc/syntaxhighlighter.cpp b/src/eepp/ui/doc/syntaxhighlighter.cpp index d4c9442f4..9a46f823b 100644 --- a/src/eepp/ui/doc/syntaxhighlighter.cpp +++ b/src/eepp/ui/doc/syntaxhighlighter.cpp @@ -89,7 +89,8 @@ void SyntaxHighlighter::moveHighlight( const Int64& fromLine, const Int64& /*toL return; Int64 linesCount = mDoc->linesCount(); if ( numLines > 0 ) { - for ( Int64 i = linesCount - 1; i >= fromLine; --i ) { + Int64 toLine = fromLine + numLines; + for ( Int64 i = linesCount - 1; i >= toLine; --i ) { auto lineIt = mLines.find( i - numLines ); if ( lineIt != mLines.end() ) { const auto& line = lineIt->second; diff --git a/src/eepp/ui/uicodeeditor.cpp b/src/eepp/ui/uicodeeditor.cpp index a896d2f24..55c5945e9 100644 --- a/src/eepp/ui/uicodeeditor.cpp +++ b/src/eepp/ui/uicodeeditor.cpp @@ -138,6 +138,8 @@ UICodeEditor::UICodeEditor( const std::string& elementTag, const bool& autoRegis setTextSelection( true ); setColorScheme( SyntaxColorScheme::getDefault() ); refreshTag(); + mDocView.setOnVisibleLineCountChange( + [this] { sendCommonEvent( Event::OnVisibleLinesCountChange ); } ); mVScrollBar = UIScrollBar::NewVertical(); mVScrollBar->setParent( this ); mVScrollBar->addEventListener( Event::OnSizeChange, @@ -2126,8 +2128,6 @@ void UICodeEditor::updateEditor() { void UICodeEditor::onDocumentTextChanged( const DocumentContentChange& change ) { invalidateDraw(); - checkMatchingBrackets(); - sendCommonEvent( Event::OnTextChanged ); mDocView.updateCache( change.range.start().line(), change.range.start().line(), 0 ); if ( !change.text.empty() && !mDocView.isWrapEnabled() ) { @@ -2141,6 +2141,8 @@ void UICodeEditor::onDocumentTextChanged( const DocumentContentChange& change ) } findRegionsDelayed(); + checkMatchingBrackets(); + sendCommonEvent( Event::OnTextChanged ); } void UICodeEditor::onDocumentCursorChange( const Doc::TextPosition& ) { @@ -2168,6 +2170,9 @@ void UICodeEditor::onDocumentLineCountChange( const size_t& lastCount, const siz if ( Math::countDigits( (Int64)lastCount ) != Math::countDigits( (Int64)newCount ) ) invalidateLineWrapMaxWidth( false ); + + if ( !mDocView.isWrapEnabled() ) + sendCommonEvent( Event::OnVisibleLinesCountChange ); } void UICodeEditor::onDocumentLineChanged( const Int64& lineNumber ) {