From 0886aded95574ed53ea776aa28a22cb6f1769a70 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mart=C3=ADn=20Lucas=20Golini?= Date: Fri, 14 Apr 2023 20:52:29 -0300 Subject: [PATCH] Fixed syntax highlighting issues when inserting or removing multi-line comments. Added support for ranged semantic highlighting, improving performance for LSPs that support ranges but not fullDelta changes. --- include/eepp/ui/doc/textdocument.hpp | 3 +++ include/eepp/ui/uicodeeditor.hpp | 2 ++ src/eepp/ui/doc/syntaxhighlighter.cpp | 3 ++- src/eepp/ui/doc/textdocument.cpp | 6 ++++++ src/eepp/ui/uicodeeditor.cpp | 11 +++++++++++ .../ecode/plugins/lsp/lspdocumentclient.cpp | 17 +++++++++-------- .../ecode/plugins/lsp/lspdocumentclient.hpp | 1 + 7 files changed, 34 insertions(+), 9 deletions(-) diff --git a/include/eepp/ui/doc/textdocument.hpp b/include/eepp/ui/doc/textdocument.hpp index edb6859ac..5b9ab5dc4 100644 --- a/include/eepp/ui/doc/textdocument.hpp +++ b/include/eepp/ui/doc/textdocument.hpp @@ -88,6 +88,7 @@ class EE_API TextDocument { } virtual void onDocumentSyntaxDefinitionChange( const SyntaxDefinition& ) {} virtual void onDocumentLineMove( const Int64& /*fromLine*/, const Int64& /*numLines*/ ){}; + virtual TextRange getVisibleRange() const { return {}; }; }; TextDocument( bool verbose = true ); @@ -560,6 +561,8 @@ class EE_API TextDocument { void setMightBeBinary( bool mightBeBinary ); + TextRange getActiveClientVisibleRange() const; + protected: friend class UndoStack; diff --git a/include/eepp/ui/uicodeeditor.hpp b/include/eepp/ui/uicodeeditor.hpp index 6bf7aaa8b..33d8aa80c 100644 --- a/include/eepp/ui/uicodeeditor.hpp +++ b/include/eepp/ui/uicodeeditor.hpp @@ -523,6 +523,8 @@ class EE_API UICodeEditor : public UIWidget, public TextDocument::Client { std::pair getVisibleLineRange() const; + virtual TextRange getVisibleRange() const; + bool isLineVisible( const Uint64& line ) const; int getVisibleLinesCount() const; diff --git a/src/eepp/ui/doc/syntaxhighlighter.cpp b/src/eepp/ui/doc/syntaxhighlighter.cpp index 8f4924e2b..339980c12 100644 --- a/src/eepp/ui/doc/syntaxhighlighter.cpp +++ b/src/eepp/ui/doc/syntaxhighlighter.cpp @@ -149,7 +149,8 @@ bool SyntaxHighlighter::updateDirty( int visibleLinesCount ) { } } const auto& it = mLines.find( index ); - if ( it == mLines.end() || it->second.initState != state ) { + if ( it == mLines.end() || it->second.hash != mDoc->line( index ).getHash() || + it->second.initState != state ) { mLines[index] = tokenizeLine( index, state ); mTokenizerLines[index] = mLines[index]; changed = true; diff --git a/src/eepp/ui/doc/textdocument.cpp b/src/eepp/ui/doc/textdocument.cpp index 2c2e08532..e006ee001 100644 --- a/src/eepp/ui/doc/textdocument.cpp +++ b/src/eepp/ui/doc/textdocument.cpp @@ -1617,6 +1617,12 @@ void TextDocument::setMightBeBinary( bool mightBeBinary ) { mMightBeBinary = mightBeBinary; } +TextRange TextDocument::getActiveClientVisibleRange() const { + if ( mActiveClient ) + return mActiveClient->getVisibleRange(); + return {}; +} + void TextDocument::selectWord( bool withMulticursor ) { if ( !hasSelection() ) { setSelection( { nextWordBoundary( getSelection().start(), false ), diff --git a/src/eepp/ui/uicodeeditor.cpp b/src/eepp/ui/uicodeeditor.cpp index 3785dd229..d1c9b7ba1 100644 --- a/src/eepp/ui/uicodeeditor.cpp +++ b/src/eepp/ui/uicodeeditor.cpp @@ -1625,6 +1625,17 @@ std::pair UICodeEditor::getVisibleLineRange() const { return std::make_pair( (Uint64)minLine, (Uint64)maxLine ); } +TextRange UICodeEditor::getVisibleRange() const { + auto visibleLineRange = getVisibleLineRange(); + return mDoc->sanitizeRange( TextRange( + TextPosition( + visibleLineRange.first, + mDoc->endOfLine( { static_cast( visibleLineRange.first ), 0 } ).column() ), + TextPosition( + visibleLineRange.second, + mDoc->endOfLine( { static_cast( visibleLineRange.second ), 0 } ).column() ) ) ); +} + bool UICodeEditor::isLineVisible( const Uint64& line ) const { auto range = getVisibleLineRange(); return line >= range.first && line <= range.second; diff --git a/src/tools/ecode/plugins/lsp/lspdocumentclient.cpp b/src/tools/ecode/plugins/lsp/lspdocumentclient.cpp index 4e1685d55..73176d597 100644 --- a/src/tools/ecode/plugins/lsp/lspdocumentclient.cpp +++ b/src/tools/ecode/plugins/lsp/lspdocumentclient.cpp @@ -115,17 +115,18 @@ void LSPDocumentClient::requestSemanticHighlighting() { if ( !mServer || !mServer->getManager()->getPlugin()->semanticHighlightingEnabled() ) return; const auto& cap = mServer->getCapabilities(); - if ( !cap.semanticTokenProvider.full && !cap.semanticTokenProvider.fullDelta /*&& - !cap.semanticTokenProvider.range*/ ) + if ( !cap.semanticTokenProvider.full && !cap.semanticTokenProvider.fullDelta && + !cap.semanticTokenProvider.range ) return; TextRange range; std::string reqId; bool delta = false; - /*if ( cap.semanticTokenProvider.range ) { - range = mDoc->getDocRange(); - } else */ - if ( cap.semanticTokenProvider.fullDelta ) { + if ( cap.semanticTokenProvider.range && !mFirstHighlight ) { + range = mDoc->getActiveClientVisibleRange(); + } else if ( mFirstHighlight ) { + mFirstHighlight = false; + } else if ( cap.semanticTokenProvider.fullDelta ) { delta = true; reqId = mSemanticeResultId; } @@ -145,8 +146,8 @@ void LSPDocumentClient::requestSemanticHighlightingDelayed() { if ( !mServer || !mServer->getManager()->getPlugin()->semanticHighlightingEnabled() ) return; const auto& cap = mServer->getCapabilities(); - if ( !cap.semanticTokenProvider.full && !cap.semanticTokenProvider.fullDelta /*&& - !cap.semanticTokenProvider.range*/ ) + if ( !cap.semanticTokenProvider.full && !cap.semanticTokenProvider.fullDelta && + !cap.semanticTokenProvider.range ) return; UISceneNode* sceneNode = getUISceneNode(); if ( sceneNode ) { diff --git a/src/tools/ecode/plugins/lsp/lspdocumentclient.hpp b/src/tools/ecode/plugins/lsp/lspdocumentclient.hpp index 41efad9b9..10aa5455d 100644 --- a/src/tools/ecode/plugins/lsp/lspdocumentclient.hpp +++ b/src/tools/ecode/plugins/lsp/lspdocumentclient.hpp @@ -58,6 +58,7 @@ class LSPDocumentClient : public TextDocument::Client { LSPSemanticTokensDelta mSemanticTokens; bool mRunningSemanticTokens{ false }; bool mShutdown{ false }; + bool mFirstHighlight{ true }; void refreshTag();