diff --git a/src/tools/ecode/commandpalette.hpp b/src/tools/ecode/commandpalette.hpp index a3e558067..d4a54b922 100644 --- a/src/tools/ecode/commandpalette.hpp +++ b/src/tools/ecode/commandpalette.hpp @@ -51,11 +51,12 @@ class CommandPalette { const std::shared_ptr& getEditorModel() const; - void setCommandPaletteEditor(const std::vector >& commandPaletteEditor); + void + setCommandPaletteEditor( const std::vector>& commandPaletteEditor ); - void setCurModel(const std::shared_ptr& curModel); + void setCurModel( const std::shared_ptr& curModel ); - protected: + protected: mutable Mutex mMatchingMutex; std::shared_ptr mPool; std::vector> mCommandPalette; diff --git a/src/tools/ecode/ecode.cpp b/src/tools/ecode/ecode.cpp index ba8ace38f..63fc8077c 100644 --- a/src/tools/ecode/ecode.cpp +++ b/src/tools/ecode/ecode.cpp @@ -3118,7 +3118,11 @@ void App::init( const LogLevel& logLevel, std::string file, const Float& pidelDe { "symbol-constant", 0xeb5d }, { "symbol-struct", 0xea91 }, { "symbol-event", 0xea86 }, { "symbol-operator", 0xeb64 }, { "symbol-type-parameter", 0xea92 }, { "expand-all", 0xeb95 }, - { "collapse-all", 0xeac5 }, + { "symbol-namespace", 0xea8b }, { "symbol-package", 0xea8b }, + { "symbol-string", 0xeb8d }, { "symbol-number", 0xea90 }, + { "symbol-boolean", 0xea8f }, { "symbol-array", 0xea8a }, + { "symbol-object", 0xea8b }, { "symbol-key", 0xea93 }, + { "symbol-null", 0xea8f }, { "collapse-all", 0xeac5 }, }; for ( const auto& icon : codIcons ) diff --git a/src/tools/ecode/filelocator.cpp b/src/tools/ecode/filelocator.cpp index 69524f594..9d510fcaa 100644 --- a/src/tools/ecode/filelocator.cpp +++ b/src/tools/ecode/filelocator.cpp @@ -3,6 +3,77 @@ namespace ecode { +class LSPSymbolInfoModel : public Model { + public: + static std::shared_ptr + create( UISceneNode* uiSceneNode, const std::string& query, + const std::vector& data ) { + return std::make_shared( uiSceneNode, query, data ); + } + + explicit LSPSymbolInfoModel( UISceneNode* uiSceneNode, const std::string& query, + const std::vector& info ) : + mUISceneNode( uiSceneNode ), mQuery( query ), mInfo( info ) {} + + size_t rowCount( const ModelIndex& ) const override { return mInfo.size(); }; + + size_t columnCount( const ModelIndex& ) const override { return 2; } + + Variant data( const ModelIndex& index, ModelRole role ) const override { + if ( index.row() >= (Int64)mInfo.size() ) + return {}; + if ( role == ModelRole::Display ) { + switch ( index.column() ) { + case 0: + return Variant( mInfo[index.row()].name.c_str() ); + case 1: + return Variant( mInfo[index.row()].url.getFSPath() ); + } + } else if ( role == ModelRole::Icon && index.column() == 0 ) { + return mUISceneNode->findIcon( + LSPSymbolKindHelper::toIconString( mInfo[index.row()].kind ) ); + } else if ( role == ModelRole::Custom && index.column() == 1 ) { + return Variant( mInfo[index.row()].range.toString() ); + } + return {}; + } + + void update() override { onModelUpdate(); } + + const std::vector& getInfo() const { return mInfo; } + + LSPSymbolInformation at( const size_t& idx ) { + eeASSERT( idx < mInfo.size() ); + return mInfo[idx]; + } + + const std::string& getQuery() const { return mQuery; } + + void append( const std::vector& res ) { + mInfo.insert( mInfo.end(), res.begin(), res.end() ); + std::sort( mInfo.begin(), mInfo.end(), + []( const LSPSymbolInformation& l, const LSPSymbolInformation& r ) { + return l.score > r.score; + } ); + onModelUpdate(); + } + + void setQuery( const std::string& query ) { + if ( mQuery != query ) { + mQuery = query; + clear(); + onModelUpdate(); + } + } + + void clear() { mInfo.clear(); } + + protected: + UISceneNode* mUISceneNode{ nullptr }; + std::string mQuery; + std::vector mInfo; +}; + static int LOCATEBAR_MAX_VISIBLE_ITEMS = 18; static int LOCATEBAR_MAX_RESULTS = 100; @@ -10,7 +81,11 @@ FileLocator::FileLocator( UICodeEditorSplitter* editorSplitter, UISceneNode* sce mSplitter( editorSplitter ), mUISceneNode( sceneNode ), mApp( app ), - mCommandPalette( mApp->getThreadPool() ) {} + mCommandPalette( mApp->getThreadPool() ) { + mApp->getPluginManager()->subscribeMessages( + "universallocator", + [&]( const PluginMessage& msg ) -> PluginRequestHandle { return processResponse( msg ); } ); +} void FileLocator::hideLocateBar() { mLocateBarLayout->setVisible( false ); @@ -32,6 +107,7 @@ void FileLocator::updateFilesTable() { mLocateTable->setModel( mApp->getDirTree()->fuzzyMatchTree( mLocateInput->getText(), LOCATEBAR_MAX_RESULTS ) ); mLocateTable->getSelection().set( mLocateTable->getModel()->index( 0 ) ); + mLocateTable->scrollToTop(); #endif } else { mLocateTable->setModel( mApp->getDirTree()->asModel( LOCATEBAR_MAX_RESULTS ) ); @@ -56,7 +132,6 @@ void FileLocator::updateCommandPaletteTable() { txt.trim(); if ( txt.size() > 1 ) { - #if EE_PLATFORM != EE_PLATFORM_EMSCRIPTEN || defined( __EMSCRIPTEN_PTHREADS__ ) mCommandPalette.asyncFuzzyMatch( txt.substr( 1 ), 1000, [&]( auto res ) { mUISceneNode->runOnMainThread( [&, res] { @@ -68,6 +143,7 @@ void FileLocator::updateCommandPaletteTable() { #else mLocateTable->setModel( mCommandPalette.fuzzyMatch( txt.substr(), 1000 ) ); mLocateTable->getSelection().set( mLocateTable->getModel()->index( 0 ) ); + mLocateTable->scrollToTop(); #endif } else if ( mCommandPalette.getCurModel() ) { mLocateTable->setModel( mCommandPalette.getCurModel() ); @@ -118,6 +194,8 @@ void FileLocator::initLocateBar( UILocateBar* locateBar, UITextInput* locateInpu } } else if ( !txt.empty() && mLocateInput->getText()[0] == '>' ) { showCommandPalette(); + } else if ( !txt.empty() && mLocateInput->getText()[0] == ':' ) { + showWorkspaceSymbol(); } else { showLocateTable(); if ( !mApp->isDirTreeReady() ) @@ -168,15 +246,30 @@ void FileLocator::initLocateBar( UILocateBar* locateBar, UITextInput* locateInpu Variant vPath( modelEvent->getModel()->data( modelEvent->getModel()->index( modelEvent->getModelIndex().row(), 1 ), ModelRole::Display ) ); - if ( vPath.isValid() && vPath.is( Variant::Type::cstr ) ) { - std::string path( vPath.asCStr() ); + if ( vPath.isValid() ) { + std::string path( vPath.is( Variant::Type::cstr ) ? vPath.asCStr() + : vPath.asStdString() ); + Variant rangeStr( modelEvent->getModel()->data( + modelEvent->getModel()->index( modelEvent->getModelIndex().row(), 1 ), + ModelRole::Custom ) ); + auto range = rangeStr.isValid() + ? TextRange::fromString( rangeStr.asStdString() ) + : TextRange(); UITab* tab = mSplitter->isDocumentOpen( path, true ); if ( !tab ) { FileInfo fileInfo( path ); if ( fileInfo.exists() && fileInfo.isRegularFile() ) - mApp->loadFileFromPath( path ); + mApp->loadFileFromPath( path, true, nullptr, + [range]( UICodeEditor* editor, auto ) { + if ( range.isValid() ) + editor->goToLine( range.start() ); + } ); } else { tab->getTabWidget()->setTabSelected( tab ); + if ( range.isValid() ) { + UICodeEditor* editor = tab->getOwnedWidget()->asType(); + editor->goToLine( range.start() ); + } } mLocateBarLayout->execute( "close-locatebar" ); } @@ -209,7 +302,7 @@ void FileLocator::showBar() { mLocateTable->setVisible( true ); const String& text = mLocateInput->getText(); - if ( !text.empty() && text[0] == '>' ) { + if ( !text.empty() && ( text[0] == '>' || text[0] == ':' ) ) { Int64 selectFrom = 1; if ( text.size() >= 2 && text[1] == ' ' ) selectFrom = 2; @@ -228,7 +321,8 @@ void FileLocator::showBar() { void FileLocator::showLocateBar() { showBar(); - if ( !mLocateInput->getText().empty() && mLocateInput->getText()[0] == '>' ) + if ( !mLocateInput->getText().empty() && + ( mLocateInput->getText()[0] == '>' || mLocateInput->getText()[0] == ':' ) ) mLocateInput->setText( "" ); if ( mApp->getDirTree() && !mLocateTable->getModel() ) { @@ -249,4 +343,59 @@ void FileLocator::showCommandPalette() { updateLocateBar(); } +void FileLocator::showWorkspaceSymbol() { + showBar(); + + if ( mLocateInput->getText().empty() || mLocateInput->getText()[0] != ':' ) + mLocateInput->setText( ": " ); + + requestWorkspaceSymbol(); + updateLocateBar(); +} + +void FileLocator::requestWorkspaceSymbol() { + if ( mLocateInput->getText().empty() ) + return; + auto txt( mLocateInput->getText().substr( 1 ).trim() ); + if ( mWorkspaceSymbolQuery != txt.toUtf8() || mWorkspaceSymbolQuery.empty() ) { + mWorkspaceSymbolQuery = txt.toUtf8(); + if ( mWorkspaceSymbolModel ) { + mWorkspaceSymbolModel->setQuery( mWorkspaceSymbolQuery ); + } else { + mWorkspaceSymbolModel = + LSPSymbolInfoModel::create( mApp->getUISceneNode(), mWorkspaceSymbolQuery, {} ); + } + json j = json{ json{ "query", mWorkspaceSymbolQuery } }; + mApp->getPluginManager()->sendRequest( PluginMessageType::WorkspaceSymbol, + PluginMessageFormat::JSON, &j ); + } +} + +void FileLocator::updateWorkspaceSymbol( const std::vector& res ) { +#if EE_PLATFORM != EE_PLATFORM_EMSCRIPTEN || defined( __EMSCRIPTEN_PTHREADS__ ) + mUISceneNode->runOnMainThread( [&, res] { + if ( !mWorkspaceSymbolModel ) { + mWorkspaceSymbolModel = + LSPSymbolInfoModel::create( mApp->getUISceneNode(), mWorkspaceSymbolQuery, res ); + } else { + mWorkspaceSymbolModel->append( res ); + } + mLocateTable->setModel( mWorkspaceSymbolModel ); + mLocateTable->getSelection().set( mLocateTable->getModel()->index( 0 ) ); + mLocateTable->scrollToTop(); + } ); +#else + mLocateTable->setModel( mWorkspaceSymbolModel ); + mLocateTable->getSelection().set( mLocateTable->getModel()->index( 0 ) ); + mLocateTable->scrollToTop(); +#endif +} + +PluginRequestHandle FileLocator::processResponse( const PluginMessage& msg ) { + if ( msg.isResponse() && msg.type == PluginMessageType::WorkspaceSymbol ) { + updateWorkspaceSymbol( msg.asSymbolInformation() ); + } + return {}; +} + } // namespace ecode diff --git a/src/tools/ecode/filelocator.hpp b/src/tools/ecode/filelocator.hpp index f3dc030a2..921e880e7 100644 --- a/src/tools/ecode/filelocator.hpp +++ b/src/tools/ecode/filelocator.hpp @@ -2,12 +2,14 @@ #define ECODE_FILELOCATOR_HPP #include "commandpalette.hpp" +#include "plugins/pluginmanager.hpp" #include "widgetcommandexecuter.hpp" #include namespace ecode { class App; +class LSPSymbolInfoModel; class FileLocator { public: @@ -29,18 +31,28 @@ class FileLocator { void showLocateTable(); + void showWorkspaceSymbol(); + protected: UILocateBar* mLocateBarLayout{ nullptr }; UITableView* mLocateTable{ nullptr }; UITextInput* mLocateInput{ nullptr }; UICodeEditorSplitter* mSplitter{ nullptr }; UISceneNode* mUISceneNode{ nullptr }; + std::shared_ptr mWorkspaceSymbolModel{ nullptr }; + std::string mWorkspaceSymbolQuery; App* mApp{ nullptr }; CommandPalette mCommandPalette; void updateLocateBar(); void showBar(); + + PluginRequestHandle processResponse( const PluginMessage& msg ); + + void requestWorkspaceSymbol(); + + void updateWorkspaceSymbol( const std::vector& info ); }; } // namespace ecode diff --git a/src/tools/ecode/plugins/lsp/lspclientplugin.cpp b/src/tools/ecode/plugins/lsp/lspclientplugin.cpp index 787ae3d15..c1928f029 100644 --- a/src/tools/ecode/plugins/lsp/lspclientplugin.cpp +++ b/src/tools/ecode/plugins/lsp/lspclientplugin.cpp @@ -248,6 +248,26 @@ PluginRequestHandle LSPClientPlugin::processDocumentFormatting( const PluginMess return ret; } +PluginRequestHandle LSPClientPlugin::processWorkspaceSymbol( const PluginMessage& msg ) { + if ( !msg.isRequest() || !msg.isJSON() ) + return {}; + + auto servers = mClientManager.getAllRunningServers(); + if ( servers.empty() ) + return {}; + + for ( const auto server : servers ) { + server->workspaceSymbol( + msg.asJSON().value( "query", "" ), + [&]( const PluginIDType& id, const std::vector& info ) { + mManager->sendResponse( this, PluginMessageType::WorkspaceSymbol, + PluginMessageFormat::SymbolInformation, &info, id ); + } ); + } + + return {}; +} + bool LSPClientPlugin::processDocumentFormattingResponse( const URI& uri, std::vector edits ) { auto doc = mManager->getSplitter()->findDocFromURI( uri ); @@ -467,6 +487,12 @@ PluginRequestHandle LSPClientPlugin::processMessage( const PluginMessage& msg ) processCancelRequest( msg ); break; } + case PluginMessageType::WorkspaceSymbol: { + auto ret = processWorkspaceSymbol( msg ); + if ( !ret.isEmpty() ) + return ret; + break; + } default: break; } diff --git a/src/tools/ecode/plugins/lsp/lspclientplugin.hpp b/src/tools/ecode/plugins/lsp/lspclientplugin.hpp index 7367b1ff5..0c0618e20 100644 --- a/src/tools/ecode/plugins/lsp/lspclientplugin.hpp +++ b/src/tools/ecode/plugins/lsp/lspclientplugin.hpp @@ -117,6 +117,8 @@ class LSPClientPlugin : public UICodeEditorPlugin { PluginRequestHandle processDocumentFormatting( const PluginMessage& msg ); + PluginRequestHandle processWorkspaceSymbol( const PluginMessage& msg ); + void tryHideTooltip( UICodeEditor* editor, const Vector2i& position ); void hideTooltip( UICodeEditor* editor ); diff --git a/src/tools/ecode/plugins/lsp/lspclientserver.cpp b/src/tools/ecode/plugins/lsp/lspclientserver.cpp index 38d5adf6f..a51f28e89 100644 --- a/src/tools/ecode/plugins/lsp/lspclientserver.cpp +++ b/src/tools/ecode/plugins/lsp/lspclientserver.cpp @@ -48,6 +48,7 @@ static const char* MEMBER_TARGET_SELECTION_RANGE = "targetSelectionRange"; static const char* MEMBER_PREVIOUS_RESULT_ID = "previousResultId"; static const char* MEMBER_QUERY = "query"; static const char* MEMBER_SUCCESS = "success"; +static const char* MEMBER_LIMIT = "limit"; static json newRequest( const std::string& method, const json& params = json{} ) { json j; @@ -392,24 +393,23 @@ static std::vector parseWorkspaceSymbols( const json& res std::vector symbols; symbols.reserve( res.size() ); - std::transform( - res.cbegin(), res.cend(), std::back_inserter( symbols ), []( const json& symbol ) { - LSPSymbolInformation symInfo; + std::transform( res.cbegin(), res.cend(), std::back_inserter( symbols ), + []( const json& symbol ) { + LSPSymbolInformation symInfo; - const auto& location = symbol.at( MEMBER_LOCATION ); - const auto& mrange = symbol.contains( MEMBER_RANGE ) ? symbol.at( MEMBER_RANGE ) - : location.at( MEMBER_RANGE ); + const auto& location = symbol.at( MEMBER_LOCATION ); + const auto& mrange = location.at( MEMBER_RANGE ); - auto containerName = symbol.value( "containerName", "" ); - if ( !containerName.empty() ) - containerName.append( "::" ); - symInfo.name = containerName + symbol.value( "name", "" ); - symInfo.kind = (LSPSymbolKind)symbol.value( MEMBER_KIND, 1 ); - symInfo.range = parseRange( mrange ); - symInfo.url = URI( location.value( MEMBER_URI, "" ) ); - symInfo.score = symbol.value( "score", 0.0 ); - return symInfo; - } ); + auto containerName = symbol.value( "containerName", "" ); + if ( !containerName.empty() ) + containerName.append( "::" ); + symInfo.name = containerName + symbol.value( "name", "" ); + symInfo.kind = (LSPSymbolKind)symbol.value( MEMBER_KIND, 1 ); + symInfo.range = parseRange( mrange ); + symInfo.url = URI( location.value( MEMBER_URI, "" ) ); + symInfo.score = symbol.value( "score", 0.0 ); + return symInfo; + } ); std::sort( symbols.begin(), symbols.end(), []( const LSPSymbolInformation& l, const LSPSymbolInformation& r ) { @@ -1039,6 +1039,10 @@ bool LSPClientServer::registerDoc( const std::shared_ptr& doc ) { return true; } +bool LSPClientServer::isRunning() { + return mProcess.isAlive() && !mProcess.isShootingDown(); +} + void LSPClientServer::removeDoc( TextDocument* doc ) { Lock l( mClientsMutex ); if ( mClients.erase( doc ) > 0 ) { @@ -1240,18 +1244,22 @@ LSPClientServer::documentSymbols( const URI& document, } LSPClientServer::LSPRequestHandle LSPClientServer::workspaceSymbol( const std::string& querySymbol, - const JsonReplyHandler& h ) { - auto params = json{ { MEMBER_QUERY, querySymbol } }; + const JsonReplyHandler& h, + const size_t& limit ) { + auto params = json{ { MEMBER_QUERY, querySymbol }, { MEMBER_LIMIT, limit } }; return send( newRequest( "workspace/symbol", params ), h ); } LSPClientServer::LSPRequestHandle -LSPClientServer::workspaceSymbol( const std::string& querySymbol, - const SymbolInformationHandler& h ) { - return workspaceSymbol( querySymbol, [h]( const IdType& id, const json& json ) { - if ( h ) - h( id, parseWorkspaceSymbols( json ) ); - } ); +LSPClientServer::workspaceSymbol( const std::string& querySymbol, const SymbolInformationHandler& h, + const size_t& limit ) { + return workspaceSymbol( + querySymbol, + [h]( const IdType& id, const json& json ) { + if ( h ) + h( id, parseWorkspaceSymbols( json ) ); + }, + limit ); } void fromJson( LSPWorkDoneProgressValue& value, const json& data ) { diff --git a/src/tools/ecode/plugins/lsp/lspclientserver.hpp b/src/tools/ecode/plugins/lsp/lspclientserver.hpp index b7d12511c..35c4f7d2c 100644 --- a/src/tools/ecode/plugins/lsp/lspclientserver.hpp +++ b/src/tools/ecode/plugins/lsp/lspclientserver.hpp @@ -63,6 +63,8 @@ class LSPClientServer { bool registerDoc( const std::shared_ptr& doc ); + bool isRunning(); + const LSPServerCapabilities& getCapabilities() const; LSPClientServerManager* getManager() const; @@ -161,10 +163,12 @@ class LSPClientServer { LSPRequestHandle documentCompletion( const URI& document, const TextPosition& pos, const CompletionHandler& h ); - LSPRequestHandle workspaceSymbol( const std::string& querySymbol, const JsonReplyHandler& h ); + LSPRequestHandle workspaceSymbol( const std::string& querySymbol, const JsonReplyHandler& h, + const size_t& limit = 100 ); LSPRequestHandle workspaceSymbol( const std::string& querySymbol, - const SymbolInformationHandler& h ); + const SymbolInformationHandler& h, + const size_t& limit = 100 ); LSPRequestHandle selectionRange( const URI& document, const std::vector& positions, diff --git a/src/tools/ecode/plugins/lsp/lspclientservermanager.cpp b/src/tools/ecode/plugins/lsp/lspclientservermanager.cpp index 297425304..ef00e1c67 100644 --- a/src/tools/ecode/plugins/lsp/lspclientservermanager.cpp +++ b/src/tools/ecode/plugins/lsp/lspclientservermanager.cpp @@ -451,4 +451,14 @@ LSPClientServerManager::getLSPClientServers( const std::string& language ) { return servers; } +std::vector LSPClientServerManager::getAllRunningServers() { + std::vector servers; + Lock l( mClientsMutex ); + for ( auto& server : mClients ) { + if ( server.second->isRunning() ) + servers.push_back( server.second.get() ); + } + return servers; +} + } // namespace ecode diff --git a/src/tools/ecode/plugins/lsp/lspclientservermanager.hpp b/src/tools/ecode/plugins/lsp/lspclientservermanager.hpp index 1030eb2d9..68324f194 100644 --- a/src/tools/ecode/plugins/lsp/lspclientservermanager.hpp +++ b/src/tools/ecode/plugins/lsp/lspclientservermanager.hpp @@ -44,6 +44,8 @@ class LSPClientServerManager { std::vector getLSPClientServers( const std::string& language ); + std::vector getAllRunningServers(); + LSPClientServer* getOneLSPClientServer( UICodeEditor* editor ); LSPClientServer* getOneLSPClientServer( const std::shared_ptr& doc ); diff --git a/src/tools/ecode/plugins/lsp/lspprotocol.hpp b/src/tools/ecode/plugins/lsp/lspprotocol.hpp index c9a4e7d16..ddfd46b21 100644 --- a/src/tools/ecode/plugins/lsp/lspprotocol.hpp +++ b/src/tools/ecode/plugins/lsp/lspprotocol.hpp @@ -244,6 +244,68 @@ enum class LSPSymbolKind { TypeParameter = 26, }; +class LSPSymbolKindHelper { + public: + // TODO: Complete this list + static std::string toIconString( const LSPSymbolKind& kind ) { + switch ( kind ) { + case LSPSymbolKind::Method: + return "symbol-method"; + case LSPSymbolKind::Function: + return "symbol-function"; + case LSPSymbolKind::Constructor: + return "symbol-constructor"; + case LSPSymbolKind::Field: + return "symbol-field"; + case LSPSymbolKind::Variable: + return "symbol-variable"; + case LSPSymbolKind::Class: + return "symbol-class"; + case LSPSymbolKind::Interface: + return "symbol-interface"; + case LSPSymbolKind::Module: + return "symbol-module"; + case LSPSymbolKind::Property: + return "symbol-property"; + case LSPSymbolKind::Enum: + return "symbol-enum"; + case LSPSymbolKind::File: + return "symbol-file"; + case LSPSymbolKind::EnumMember: + return "symbol-enum-member"; + case LSPSymbolKind::Constant: + return "symbol-constant"; + case LSPSymbolKind::Struct: + return "symbol-struct"; + case LSPSymbolKind::Event: + return "symbol-event"; + case LSPSymbolKind::Operator: + return "symbol-operator"; + case LSPSymbolKind::TypeParameter: + return "symbol-type-parameter"; + case LSPSymbolKind::Namespace: + return "symbol-namespace"; + case LSPSymbolKind::Package: + return "symbol-package"; + case LSPSymbolKind::String: + return "symbol-string"; + case LSPSymbolKind::Number: + return "symbol-number"; + case LSPSymbolKind::Boolean: + return "symbol-boolean"; + case LSPSymbolKind::Array: + return "symbol-array"; + case LSPSymbolKind::Object: + return "symbol-object"; + case LSPSymbolKind::Key: + return "symbol-key"; + case LSPSymbolKind::Null: + return "symbol-null"; + } + return "symbol-text"; + } +}; + struct LSPSymbolInformation { LSPSymbolInformation() = default; LSPSymbolInformation( const std::string& _name, LSPSymbolKind _kind, TextRange _range, diff --git a/src/tools/ecode/plugins/pluginmanager.cpp b/src/tools/ecode/plugins/pluginmanager.cpp index bff860189..ca4924646 100644 --- a/src/tools/ecode/plugins/pluginmanager.cpp +++ b/src/tools/ecode/plugins/pluginmanager.cpp @@ -115,6 +115,23 @@ void PluginManager::setWorkspaceFolder( const std::string& workspaceFolder ) { sendBroadcast( PluginMessageType::WorkspaceFolderChanged, PluginMessageFormat::JSON, &data ); } +PluginRequestHandle PluginManager::sendRequest( PluginMessageType type, PluginMessageFormat format, + const void* data ) { + if ( mClosing ) + return PluginRequestHandle::empty(); + SubscribedPlugins subscribedPlugins; + { + Lock l( mSubscribedPluginsMutex ); + subscribedPlugins = mSubscribedPlugins; + } + for ( const auto& plugin : subscribedPlugins ) { + auto handle = plugin.second( { type, format, data } ); + if ( !handle.isEmpty() ) + return handle; + } + return PluginRequestHandle::empty(); +} + PluginRequestHandle PluginManager::sendRequest( UICodeEditorPlugin* pluginWho, PluginMessageType type, PluginMessageFormat format, const void* data ) { diff --git a/src/tools/ecode/plugins/pluginmanager.hpp b/src/tools/ecode/plugins/pluginmanager.hpp index 832135664..4482ac9f7 100644 --- a/src/tools/ecode/plugins/pluginmanager.hpp +++ b/src/tools/ecode/plugins/pluginmanager.hpp @@ -73,6 +73,7 @@ enum class PluginMessageType { SymbolReference, // Request the LSP Server to find a symbol reference in the project ShowMessage, // The LSP server sends a request to the client to show a message on screen ShowDocument, // The LSP server sends a request to the client to show a document + WorkspaceSymbol, Undefined }; @@ -85,6 +86,7 @@ enum class PluginMessageFormat { ProjectSearchResult, ShowMessage, ShowDocument, + SymbolInformation }; class PluginIDType { @@ -172,6 +174,10 @@ struct PluginMessage { return *static_cast( data ); } + const std::vector& asSymbolInformation() const { + return *static_cast*>( data ); + } + const PluginIDType& asPluginID() const { return *static_cast( data ); } bool isResponse() const { return -1 != responseID && 0 != responseID; } @@ -247,6 +253,9 @@ class PluginManager { void setWorkspaceFolder( const std::string& workspaceFolder ); + PluginRequestHandle sendRequest( PluginMessageType type, PluginMessageFormat format, + const void* data ); + PluginRequestHandle sendRequest( UICodeEditorPlugin* pluginWho, PluginMessageType type, PluginMessageFormat format, const void* data ); @@ -290,8 +299,6 @@ class PluginManager { void setSplitter( UICodeEditorSplitter* splitter ); - PluginRequestHandle sendRequest( const PluginMessageType& notification, - const PluginMessageFormat& format, void* data ); }; class PluginsModel : public Model { diff --git a/src/tools/ecode/projectdirectorytree.hpp b/src/tools/ecode/projectdirectorytree.hpp index d804b7eed..fa4a421ba 100644 --- a/src/tools/ecode/projectdirectorytree.hpp +++ b/src/tools/ecode/projectdirectorytree.hpp @@ -45,10 +45,11 @@ class FileListModel : public Model { switch ( role ) { case ModelRole::Icon: return Variant( iconFor( index ) ); - default: case ModelRole::Display: return Variant( index.column() == 0 ? mNames[index.row()].c_str() : mFiles[index.row()].c_str() ); + default: + break; } return {};