diff --git a/include/eepp/ui/uicodeeditor.hpp b/include/eepp/ui/uicodeeditor.hpp index 1717851b9..d50411ba5 100644 --- a/include/eepp/ui/uicodeeditor.hpp +++ b/include/eepp/ui/uicodeeditor.hpp @@ -408,6 +408,14 @@ class EE_API UICodeEditor : public UIWidget, public TextDocument::Client { void moveScrollDown(); + void jumpLinesUp(); + + void jumpLinesDown(); + + void jumpLinesUp( int offset ); + + void jumpLinesDown( int offset ); + void indent(); void unindent(); @@ -605,7 +613,11 @@ class EE_API UICodeEditor : public UIWidget, public TextDocument::Client { UIScrollBar* getHScrollBar() const; - protected: + size_t getJumpLinesLength() const; + + void setJumpLinesLength(size_t jumpLinesLength); + + protected: struct LastXOffset { TextPosition position{ 0, 0 }; Float offset{ 0.f }; @@ -711,6 +723,7 @@ class EE_API UICodeEditor : public UIWidget, public TextDocument::Client { Float mPluginsTopSpace{ 0 }; Uint64 mLastExecuteEventId{ 0 }; Text mLineTextCache; + size_t mJumpLinesLength{ 5 }; UICodeEditor( const std::string& elementTag, const bool& autoRegisterBaseCommands = true, const bool& autoRegisterBaseKeybindings = true ); diff --git a/src/eepp/ui/tools/uicodeeditorsplitter.cpp b/src/eepp/ui/tools/uicodeeditorsplitter.cpp index f7cd671f8..9e8cee480 100644 --- a/src/eepp/ui/tools/uicodeeditorsplitter.cpp +++ b/src/eepp/ui/tools/uicodeeditorsplitter.cpp @@ -156,6 +156,14 @@ UICodeEditor* UICodeEditorSplitter::createCodeEditor() { if ( mCurEditor ) mCurEditor->moveScrollDown(); } ); + doc.setCommand( "jump-lines-up", [this] { + if ( mCurEditor ) + mCurEditor->jumpLinesUp(); + } ); + doc.setCommand( "jump-lines-down", [this] { + if ( mCurEditor ) + mCurEditor->jumpLinesDown(); + } ); doc.setCommand( "indent", [this] { if ( mCurEditor ) mCurEditor->indent(); diff --git a/src/eepp/ui/uicodeeditor.cpp b/src/eepp/ui/uicodeeditor.cpp index a5e3cfbb6..bc1e6a18c 100644 --- a/src/eepp/ui/uicodeeditor.cpp +++ b/src/eepp/ui/uicodeeditor.cpp @@ -51,10 +51,12 @@ const std::map UICodeEditor::getDefaultKeybi { { KEY_RETURN, 0 }, "new-line" }, { { KEY_UP, KeyMod::getDefaultModifier() | KEYMOD_SHIFT }, "move-lines-up" }, { { KEY_UP, KeyMod::getDefaultModifier() }, "move-scroll-up" }, + { { KEY_PAGEUP, KeyMod::getDefaultModifier() | KEYMOD_SHIFT }, "jump-lines-up" }, { { KEY_UP, KEYMOD_SHIFT }, "select-to-previous-line" }, { { KEY_UP, 0 }, "move-to-previous-line" }, { { KEY_DOWN, KeyMod::getDefaultModifier() | KEYMOD_SHIFT }, "move-lines-down" }, { { KEY_DOWN, KeyMod::getDefaultModifier() }, "move-scroll-down" }, + { { KEY_PAGEDOWN, KeyMod::getDefaultModifier() | KEYMOD_SHIFT }, "jump-lines-down" }, { { KEY_DOWN, KEYMOD_SHIFT }, "select-to-next-line" }, { { KEY_DOWN, 0 }, "move-to-next-line" }, { { KEY_LEFT, KeyMod::getDefaultModifier() | KEYMOD_SHIFT }, "select-to-previous-word" }, @@ -2418,29 +2420,45 @@ TextPosition UICodeEditor::moveToLineOffset( const TextPosition& position, int o } void UICodeEditor::moveToPreviousLine() { + jumpLinesUp( -1 ); +} + +void UICodeEditor::moveToNextLine() { + jumpLinesDown( 1 ); +} + +void UICodeEditor::jumpLinesUp( int offset ) { for ( size_t i = 0; i < mDoc->getSelections().size(); ++i ) { TextPosition position = mDoc->getSelections()[i].start(); if ( position.line() == 0 ) { mDoc->setSelection( i, mDoc->startOfDoc(), mDoc->startOfDoc() ); } else { - mDoc->moveTo( i, moveToLineOffset( position, -1, i ) ); + mDoc->moveTo( i, moveToLineOffset( position, offset, i ) ); } } mDoc->mergeSelection(); } -void UICodeEditor::moveToNextLine() { +void UICodeEditor::jumpLinesDown( int offset ) { for ( size_t i = 0; i < mDoc->getSelections().size(); ++i ) { TextPosition position = mDoc->getSelections()[i].start(); - if ( position.line() == (Int64)mDoc->linesCount() - 1 ) { + if ( position.line() >= (Int64)mDoc->linesCount() - offset ) { mDoc->setSelection( i, mDoc->endOfDoc(), mDoc->endOfDoc() ); } else { - mDoc->moveTo( i, moveToLineOffset( position, 1, i ) ); + mDoc->moveTo( i, moveToLineOffset( position, offset, i ) ); } } mDoc->mergeSelection(); } +void UICodeEditor::jumpLinesUp() { + jumpLinesDown( -mJumpLinesLength ); +} + +void UICodeEditor::jumpLinesDown() { + jumpLinesDown( mJumpLinesLength ); +} + void UICodeEditor::selectToPreviousLine() { for ( size_t i = 0; i < mDoc->getSelections().size(); ++i ) { TextPosition position = mDoc->getSelectionIndex( i ).start(); @@ -2471,6 +2489,14 @@ void UICodeEditor::moveScrollDown() { setScrollY( mScroll.y + getLineHeight() ); } +size_t UICodeEditor::getJumpLinesLength() const { + return mJumpLinesLength; +} + +void UICodeEditor::setJumpLinesLength( size_t jumpLinesLength ) { + mJumpLinesLength = jumpLinesLength; +} + void UICodeEditor::indent() { UIEventDispatcher* eventDispatcher = static_cast( getUISceneNode()->getEventDispatcher() ); @@ -3125,6 +3151,8 @@ void UICodeEditor::registerCommands() { mDoc->setCommand( "select-to-next-line", [this] { selectToNextLine(); } ); mDoc->setCommand( "move-scroll-up", [this] { moveScrollUp(); } ); mDoc->setCommand( "move-scroll-down", [this] { moveScrollDown(); } ); + mDoc->setCommand( "jump-lines-up", [this] { jumpLinesUp(); } ); + mDoc->setCommand( "jump-lines-down", [this] { jumpLinesDown(); } ); mDoc->setCommand( "indent", [this] { indent(); } ); mDoc->setCommand( "unindent", [this] { unindent(); } ); mDoc->setCommand( "copy", [this] { copy(); } ); diff --git a/src/tools/ecode/plugins/lsp/lspclientplugin.cpp b/src/tools/ecode/plugins/lsp/lspclientplugin.cpp index f4a34d147..a70547fc6 100644 --- a/src/tools/ecode/plugins/lsp/lspclientplugin.cpp +++ b/src/tools/ecode/plugins/lsp/lspclientplugin.cpp @@ -803,6 +803,7 @@ void LSPClientPlugin::loadLSPConfig( std::vector& lsps, const std mKeyBindings["lsp-symbol-info"] = "f1"; mKeyBindings["lsp-symbol-code-action"] = "alt+return"; mKeyBindings["lsp-rename-symbol-under-cursor"] = "mod+shift+r"; + mKeyBindings["lsp-symbol-references"] = "mod+shift+u"; } if ( j.contains( "keybindings" ) ) { diff --git a/src/tools/ecode/plugins/lsp/lspclientserver.cpp b/src/tools/ecode/plugins/lsp/lspclientserver.cpp index e94a50e2c..35131bb14 100644 --- a/src/tools/ecode/plugins/lsp/lspclientserver.cpp +++ b/src/tools/ecode/plugins/lsp/lspclientserver.cpp @@ -69,7 +69,7 @@ static json newID( const PluginIDType& id ) { static json newEmptyResult( const PluginIDType& id ) { json j; - j[MEMBER_RESULT] = json( json::value_t::object ); + j[MEMBER_RESULT] = nullptr; if ( id.isInteger() ) j[MEMBER_ID] = id.asInt(); else @@ -1751,7 +1751,6 @@ void LSPClientServer::readStdErr( const char* bytes, size_t n ) { mReceiveErr.erase( 0, lastNewLineIndex + 1 ); } if ( !msg.message.empty() ) { - msg.type = LSPMessageType::Log; Log::debug( "LSPClientServer::readStdErr server %s:\n%s", mLSP.name.c_str(), msg.message.c_str() ); } diff --git a/src/tools/ecode/plugins/lsp/lspclientservermanager.cpp b/src/tools/ecode/plugins/lsp/lspclientservermanager.cpp index 1c9aea9b5..2eb8eeeb3 100644 --- a/src/tools/ecode/plugins/lsp/lspclientservermanager.cpp +++ b/src/tools/ecode/plugins/lsp/lspclientservermanager.cpp @@ -348,20 +348,39 @@ void LSPClientServerManager::sendSymbolReferenceBroadcast( const std::vector res; + std::unordered_map> tmpDocs; for ( auto& r : resp ) { - auto fspath( r.uri.getFSPath() ); + std::string fspath( r.uri.getFSPath() ); auto& rd = res[fspath]; if ( rd.file.empty() ) rd.file = fspath; + auto curDoc = mPluginManager->getSplitter()->findDocFromURI( r.uri ); - if ( !curDoc ) - continue; + if ( curDoc ) { + ProjectSearch::ResultData::Result rs( curDoc->line( r.range.start().line() ).getText(), + r.range, -1, -1 ); - ProjectSearch::ResultData::Result rs( curDoc->line( r.range.start().line() ).getText(), - r.range, -1, -1 ); + rd.results.emplace_back( std::move( rs ) ); + } else { + String lineText; + auto foundDoc = tmpDocs.find( fspath ); + if ( foundDoc == tmpDocs.end() ) { + std::unique_ptr doc = std::make_unique(); + if ( TextDocument::LoadStatus::Loaded != doc->loadFromFile( fspath ) ) + continue; - rd.results.emplace_back( std::move( rs ) ); + lineText = doc->line( r.range.start().line() ).getText(); + + tmpDocs.insert( { std::move( fspath ), std::move( doc ) } ); + } else { + lineText = foundDoc->second->line( r.range.start().line() ).getText(); + } + + ProjectSearch::ResultData::Result rs( lineText, r.range, -1, -1 ); + + rd.results.emplace_back( std::move( rs ) ); + } } ProjectSearch::Result result; diff --git a/src/tools/ecode/plugins/pluginmanager.hpp b/src/tools/ecode/plugins/pluginmanager.hpp index a5e6633b5..5c67be997 100644 --- a/src/tools/ecode/plugins/pluginmanager.hpp +++ b/src/tools/ecode/plugins/pluginmanager.hpp @@ -151,6 +151,8 @@ struct PluginMessage { const void* data; PluginIDType responseID{ 0 }; // 0 if it's not a response; + const void* asData() const { return data; } + const nlohmann::json& asJSON() const { return *static_cast( data ); } bool isJSON() const { return format == PluginMessageFormat::JSON; } @@ -195,7 +197,7 @@ struct PluginMessage { bool isResponse() const { return -1 != responseID && 0 != responseID; } - bool isRequest() const { return -1 != responseID && 0 == responseID; } + bool isRequest() const { return 0 == responseID; } bool isBroadcast() const { return -1 == responseID; } }; diff --git a/src/tools/ecode/projectbuild.cpp b/src/tools/ecode/projectbuild.cpp index 50254fccb..bf367e720 100644 --- a/src/tools/ecode/projectbuild.cpp +++ b/src/tools/ecode/projectbuild.cpp @@ -661,9 +661,11 @@ void ProjectBuildManager::buildCurrentConfig( StatusBuildOutputController* sboc if ( buildIt.second.getName() == mConfig.buildName ) build = &buildIt.second; - if ( build ) + if ( build ) { + mApp->saveAll(); sboc->runBuild( build->getName(), mConfig.buildType, getOutputParser( build->getName() ) ); + } } }