diff --git a/.gitignore b/.gitignore index 6667adf39..233633bf9 100644 --- a/.gitignore +++ b/.gitignore @@ -21,7 +21,7 @@ projects/android-project-ant/gen projects/android-project-ant/assets projects/android-project-ant/libs src/examples/strobe -src/thirdparty/SDL2-2.0.* +src/thirdparty/SDL2-* *.dll bin/ee* bin/eepp-* diff --git a/include/eepp/ui/keyboardshortcut.hpp b/include/eepp/ui/keyboardshortcut.hpp index 5f1a329e4..3eb746537 100644 --- a/include/eepp/ui/keyboardshortcut.hpp +++ b/include/eepp/ui/keyboardshortcut.hpp @@ -33,6 +33,8 @@ class EE_API KeyBindings { bool empty() const { return 0 == mod && 0 == key; } }; + static std::string keybindFormat( std::string str ); + KeyBindings( const Window::Input* input ); void addKeybindsString( const std::map& binds ); @@ -43,7 +45,7 @@ class EE_API KeyBindings { void addKeybindsUnordered( const std::unordered_map& binds ); - void addKeybindString(const std::string& key, const std::string& command ); + void addKeybindString( const std::string& key, const std::string& command ); void addKeybind( const Shortcut& key, const std::string& command ); @@ -81,9 +83,8 @@ class EE_API KeyBindings { }} // namespace EE::UI -template<> -struct std::hash { - std::size_t operator()(EE::UI::KeyBindings::Shortcut const& s) const noexcept { +template <> struct std::hash { + std::size_t operator()( EE::UI::KeyBindings::Shortcut const& s ) const noexcept { return s.toUint64(); } }; diff --git a/include/eepp/ui/uitabwidget.hpp b/include/eepp/ui/uitabwidget.hpp index 0b0e4f25c..f00535ff3 100644 --- a/include/eepp/ui/uitabwidget.hpp +++ b/include/eepp/ui/uitabwidget.hpp @@ -177,10 +177,10 @@ class EE_API UITabWidget : public UIWidget { UITab* mTabSelected; Uint32 mTabSelectedIndex; TabTryCloseCallback mTabTryCloseCallback; - bool mHideTabBarOnSingleTab; - bool mAllowRearrangeTabs; - bool mAllowDragAndDropTabs; - bool mAllowSwitchTabsInEmptySpaces; + bool mHideTabBarOnSingleTab{ false }; + bool mAllowRearrangeTabs{ false }; + bool mAllowDragAndDropTabs{ false }; + bool mAllowSwitchTabsInEmptySpaces{ false }; bool mDroppableHoveringColorWasSet{ false }; Float mTabVerticalDragResistance; Color mDroppableHoveringColor{ Color::Transparent }; diff --git a/src/eepp/ui/keyboardshortcut.cpp b/src/eepp/ui/keyboardshortcut.cpp index e99af485b..3e5dc947c 100644 --- a/src/eepp/ui/keyboardshortcut.cpp +++ b/src/eepp/ui/keyboardshortcut.cpp @@ -127,7 +127,7 @@ std::string KeyBindings::getCommandFromKeyBind( const KeyBindings::Shortcut& key return ""; } -static std::string keybindFormat( std::string str ) { +std::string KeyBindings::keybindFormat( std::string str ) { if ( !str.empty() ) { String::replace( str, "mod", KeyMod::getDefaultModifierString() ); str[0] = std::toupper( str[0] ); diff --git a/src/eepp/ui/uiconsole.cpp b/src/eepp/ui/uiconsole.cpp index 5ede815a4..d0be542f9 100644 --- a/src/eepp/ui/uiconsole.cpp +++ b/src/eepp/ui/uiconsole.cpp @@ -367,6 +367,8 @@ void UIConsole::draw() { size_t pos = 0; Float curY; Float lineHeight = getLineHeight(); + Float cw = + mFontStyleConfig.Font->getGlyph( '_', mFontStyleConfig.CharacterSize, false ).advance; mCon.min = eemax( 0, (Int32)mCmdLog.size() - linesInScreen ); mCon.max = (int)mCmdLog.size() - 1; @@ -385,8 +387,14 @@ void UIConsole::draw() { text.setStyleConfig( mFontStyleConfig ); text.setFillColor( fontColor ); if ( mCmdLog[i].hash != mTextCache[pos].hash ) { - text.setString( mCmdLog[i].log ); - mTextCache[pos].hash = mCmdLog[i].hash; + if ( mCmdLog[i].log.size() * cw <= mSize.getWidth() ) { + text.setString( mCmdLog[i].log ); + mTextCache[pos].hash = mCmdLog[i].hash; + } else { + auto substr = mCmdLog[i].log.substr( 0, ( mSize.getWidth() + 8 * cw ) / cw ); + mTextCache[pos].hash = String::hash( substr ); + text.setString( substr ); + } } text.draw( mScreenPos.x + mPaddingPx.Left, curY ); pos++; diff --git a/src/eepp/ui/uitabwidget.cpp b/src/eepp/ui/uitabwidget.cpp index 1279148c4..70c76165a 100644 --- a/src/eepp/ui/uitabwidget.cpp +++ b/src/eepp/ui/uitabwidget.cpp @@ -23,6 +23,8 @@ UITabWidget::UITabWidget() : mHideTabBarOnSingleTab( false ), mAllowRearrangeTabs( false ), mAllowDragAndDropTabs( false ), + mAllowSwitchTabsInEmptySpaces( false ), + mDroppableHoveringColorWasSet( false ), mTabVerticalDragResistance( PixelDensity::dpToPx( 64 ) ) { setHorizontalAlign( UI_HALIGN_CENTER ); setClipType( ClipType::ContentBox ); diff --git a/src/tools/ecode/appconfig.cpp b/src/tools/ecode/appconfig.cpp index 65cede6f4..286c791fb 100644 --- a/src/tools/ecode/appconfig.cpp +++ b/src/tools/ecode/appconfig.cpp @@ -422,7 +422,8 @@ void AppConfig::loadProject( std::string projectFolder, UICodeEditorSplitter* ed json j; try { j = json::parse( ini.getValue( "nodes", "documents" ) ); - } catch ( ... ) { + } catch ( const json::exception& e ) { + Log::error( "AppConfig::loadProject: error loading project: %s", e.what() ); return; } if ( j.is_discarded() ) diff --git a/src/tools/ecode/ecode.cpp b/src/tools/ecode/ecode.cpp index 2166a00b8..51ff39a80 100644 --- a/src/tools/ecode/ecode.cpp +++ b/src/tools/ecode/ecode.cpp @@ -408,26 +408,10 @@ void App::saveConfig() { mGlobalSearchController->getGlobalSearchBarConfig(), mPluginManager.get() ); } -static std::string keybindFormat( std::string str ) { - if ( !str.empty() ) { - String::replace( str, "mod", KeyMod::getDefaultModifierString() ); - str[0] = std::toupper( str[0] ); - size_t found = str.find_first_of( '+' ); - while ( found != std::string::npos ) { - if ( found + 1 < str.size() ) { - str[found + 1] = std::toupper( str[found + 1] ); - } - found = str.find_first_of( '+', found + 1 ); - } - return str; - } - return ""; -} - std::string App::getKeybind( const std::string& command ) { auto it = mKeybindingsInvert.find( command ); if ( it != mKeybindingsInvert.end() ) - return keybindFormat( it->second ); + return KeyBindings::keybindFormat( it->second ); return ""; } @@ -3099,6 +3083,8 @@ void App::consoleToggle() { mConsole->toggle(); bool lock = mConsole->isActive(); mSplitter->forEachEditor( [lock]( UICodeEditor* editor ) { editor->setLocked( lock ); } ); + if ( !lock && mSplitter->getCurWidget() ) + mSplitter->getCurWidget()->setFocus(); } void App::createProjectTreeMenu( const FileInfo& file ) { diff --git a/src/tools/ecode/plugins/formatter/formatterplugin.cpp b/src/tools/ecode/plugins/formatter/formatterplugin.cpp index 09069811a..67d3d1f70 100644 --- a/src/tools/ecode/plugins/formatter/formatterplugin.cpp +++ b/src/tools/ecode/plugins/formatter/formatterplugin.cpp @@ -124,7 +124,10 @@ void FormatterPlugin::loadFormatterConfig( const std::string& path ) { try { j = json::parse( data, nullptr, true, true ); - } catch ( ... ) { + } catch ( const json::exception& e ) { + Log::error( "FormatterPlugin::loadFormatterConfig - Error parsing formatter config from " + "path %s, error: ", + path.c_str(), e.what() ); return; } @@ -189,7 +192,8 @@ void FormatterPlugin::load( const PluginManager* pluginManager ) { paths.emplace_back( path ); path = pluginManager->getPluginsPath() + "formatters.json"; if ( FileSystem::fileExists( path ) || - FileSystem::fileWrite( path, "{\n\"config\":{},\n\"formatters\":[]\n}\n" ) ) { + FileSystem::fileWrite( + path, "{\n \"config\":{},\n \"keybindings\":{},\n \"formatters\":[]\n}\n" ) ) { mConfigPath = path; paths.emplace_back( path ); } diff --git a/src/tools/ecode/plugins/linter/linterplugin.cpp b/src/tools/ecode/plugins/linter/linterplugin.cpp index 7c7f8c370..70529cdbf 100644 --- a/src/tools/ecode/plugins/linter/linterplugin.cpp +++ b/src/tools/ecode/plugins/linter/linterplugin.cpp @@ -78,7 +78,10 @@ void LinterPlugin::loadLinterConfig( const std::string& path ) { json j; try { j = json::parse( data, nullptr, true, true ); - } catch ( ... ) { + } catch ( const json::exception& e ) { + Log::error( "LinterPlugin::loadLinterConfig - Error parsing linter config from " + "path %s, error: ", + path.c_str(), e.what() ); return; } diff --git a/src/tools/ecode/plugins/lsp/lspclientplugin.cpp b/src/tools/ecode/plugins/lsp/lspclientplugin.cpp index 1a8b018c1..4116f8437 100644 --- a/src/tools/ecode/plugins/lsp/lspclientplugin.cpp +++ b/src/tools/ecode/plugins/lsp/lspclientplugin.cpp @@ -14,8 +14,8 @@ UICodeEditorPlugin* LSPClientPlugin::New( const PluginManager* pluginManager ) { } LSPClientPlugin::LSPClientPlugin( const PluginManager* pluginManager ) : - mManager( pluginManager ), mPool( pluginManager->getThreadPool() ) { - mPool->run( [&, pluginManager] { load( pluginManager ); }, [] {} ); + mManager( pluginManager ), mThreadPool( pluginManager->getThreadPool() ) { + mThreadPool->run( [&, pluginManager] { load( pluginManager ); }, [] {} ); } LSPClientPlugin::~LSPClientPlugin() { @@ -56,7 +56,8 @@ void LSPClientPlugin::load( const PluginManager* pluginManager ) { paths.emplace_back( path ); path = pluginManager->getPluginsPath() + "lspclient.json"; if ( FileSystem::fileExists( path ) || - FileSystem::fileWrite( path, "{\n\"config\":{},\n\"servers\":[]\n}\n" ) ) { + FileSystem::fileWrite( + path, "{\n \"config\":{},\n \"keybindings\":{},\n \"formatters\":[]\n}\n" ) ) { mConfigPath = path; paths.emplace_back( path ); } @@ -75,7 +76,11 @@ void LSPClientPlugin::load( const PluginManager* pluginManager ) { mClientManager.load( this, pluginManager, std::move( lsps ) ); - mReady = mClientManager.clientCount() > 0; + mReady = mClientManager.lspCount() > 0; + for ( const auto& doc : mDelayedDocs ) + if ( mDocs.find( doc.first ) != mDocs.end() ) + mClientManager.tryRunServer( doc.second ); + mDelayedDocs.clear(); if ( mReady ) fireReadyCbs(); } @@ -87,14 +92,27 @@ void LSPClientPlugin::loadLSPConfig( std::vector& lsps, const std json j; try { j = json::parse( data, nullptr, true, true ); - } catch ( ... ) { + } catch ( const json::exception& e ) { + Log::error( "LSPClientPlugin::loadLSPConfig - Error parsing LSP config from " + "path %s, error: ", + path.c_str(), e.what() ); return; } if ( mKeyBindings.empty() ) mKeyBindings["lsp-go-to-definition"] = "f2"; - if ( j.contains( "keybindings" ) && j["keybindings"].contains( "lsp-go-to-definition" ) ) - mKeyBindings["lsp-go-to-definition"] = j["keybindings"]["lsp-go-to-definition"]; + + if ( j.contains( "keybindings" ) ) { + auto kb = j["keybindings"]; + auto bindKey = [this, kb]( const std::string& key ) { + if ( kb.contains( key ) ) + mKeyBindings[key] = kb[key]; + }; + auto list = { "lsp-go-to-definition", "lsp-go-to-declaration", "lsp-go-to-implementation", + "lsp-go-to-type-definition", "lsp-switch-header-source" }; + for ( const auto& key : list ) + bindKey( key ); + } if ( !j.contains( "servers" ) ) return; @@ -187,7 +205,29 @@ void LSPClientPlugin::onRegister( UICodeEditor* editor ) { if ( editor->hasDocument() ) { editor->getDocument().setCommand( "lsp-go-to-definition", [&, editor]() { - mClientManager.goToDocumentDefinition( editor->getDocumentRef().get() ); + mClientManager.getAndGoToLocation( editor->getDocumentRef(), + "textDocument/definition" ); + } ); + + editor->getDocument().setCommand( "lsp-go-to-declaration", [&, editor]() { + mClientManager.getAndGoToLocation( editor->getDocumentRef(), + "textDocument/declaration" ); + } ); + + editor->getDocument().setCommand( "lsp-go-to-implementation", [&, editor]() { + mClientManager.getAndGoToLocation( editor->getDocumentRef(), + "textDocument/implementation" ); + } ); + + editor->getDocument().setCommand( "lsp-go-to-type-definition", [&, editor]() { + mClientManager.getAndGoToLocation( editor->getDocumentRef(), + "textDocument/typeDefinition" ); + } ); + + editor->getDocument().setCommand( "lsp-switch-header-source", [&, editor]() { + auto* server = mClientManager.getOneLSPClientServer( editor ); + if ( server ) + server->switchSourceHeader( editor->getDocument().getURI() ); } ); } @@ -201,8 +241,10 @@ void LSPClientPlugin::onRegister( UICodeEditor* editor ) { mEditors.insert( { editor, listeners } ); mEditorDocs[editor] = editor->getDocumentRef().get(); - if ( editor->hasDocument() && editor->getDocument().hasFilepath() ) + if ( mReady && editor->hasDocument() && editor->getDocument().hasFilepath() ) mClientManager.run( editor->getDocumentRef() ); + if ( !mReady ) + mDelayedDocs[&editor->getDocument()] = editor->getDocumentRef(); } void LSPClientPlugin::onUnregister( UICodeEditor* editor ) { @@ -239,34 +281,27 @@ bool LSPClientPlugin::onCreateContextMenu( UICodeEditor* editor, UIPopUpMenu* me menu->addSeparator(); - auto addFn = [editor, server, menu]( const std::string& txtKey, const std::string& txtVal, - const std::string& cmd ) { - menu->add( editor->getUISceneNode()->i18n( txtKey, txtVal ) ) - ->setId( txtKey ) - ->on( Event::OnItemClicked, [server, editor, cmd]( const Event* event ) { - if ( !event->getNode()->isType( UI_TYPE_MENUITEM ) ) - return; - UIMenuItem* item = event->getNode()->asType(); - if ( String::startsWith( item->getId(), "lsp" ) ) { - server->getAndGoToLocation( editor->getDocument().getURI(), - editor->getDocument().getSelection().start(), cmd ); - } - } ); + auto addFn = [this, editor, menu]( const std::string& txtKey, const std::string& txtVal ) { + menu->add( editor->getUISceneNode()->i18n( txtKey, txtVal ), nullptr, + KeyBindings::keybindFormat( mKeyBindings[txtKey] ) ) + ->setId( txtKey ); }; auto cap = server->getCapabilities(); if ( cap.definitionProvider ) - addFn( "lsp-go-to-definition", "Go To Definition", "textDocument/definition" ); + addFn( "lsp-go-to-definition", "Go To Definition" ); if ( cap.declarationProvider ) - addFn( "lsp-go-to-declaration", "Go To Declaration", "textDocument/declaration" ); + addFn( "lsp-go-to-declaration", "Go To Declaration" ); if ( cap.typeDefinitionProvider ) - addFn( "lsp-go-to-type-definition", "Go To Type Definition", - "textDocument/typeDefinition" ); + addFn( "lsp-go-to-type-definition", "Go To Type Definition" ); if ( cap.implementationProvider ) - addFn( "lsp-go-to-implementation", "Go To Implementation", "textDocument/implementation" ); + addFn( "lsp-go-to-implementation", "Go To Implementation" ); + + if ( server->getDefinition().language == "cpp" || server->getDefinition().language == "c" ) + addFn( "lsp-switch-header-source", "Switch Header/Source" ); return false; } diff --git a/src/tools/ecode/plugins/lsp/lspclientplugin.hpp b/src/tools/ecode/plugins/lsp/lspclientplugin.hpp index 41d88a95c..882ead3c6 100644 --- a/src/tools/ecode/plugins/lsp/lspclientplugin.hpp +++ b/src/tools/ecode/plugins/lsp/lspclientplugin.hpp @@ -56,7 +56,7 @@ class LSPClientPlugin : public UICodeEditorPlugin { protected: const PluginManager* mManager{ nullptr }; - std::shared_ptr mPool; + std::shared_ptr mThreadPool; Clock mClock; Mutex mDocMutex; std::unordered_map> mEditors; @@ -67,6 +67,7 @@ class LSPClientPlugin : public UICodeEditorPlugin { bool mClosing{ false }; bool mReady{ false }; std::map mKeyBindings; /* cmd, shortcut */ + std::map> mDelayedDocs; LSPClientPlugin( const PluginManager* pluginManager ); diff --git a/src/tools/ecode/plugins/lsp/lspclientserver.cpp b/src/tools/ecode/plugins/lsp/lspclientserver.cpp index 3d3c0ab1c..3f7d48fd6 100644 --- a/src/tools/ecode/plugins/lsp/lspclientserver.cpp +++ b/src/tools/ecode/plugins/lsp/lspclientserver.cpp @@ -54,6 +54,10 @@ static json newRequest( const std::string& method, const json& params = {} ) { return j; } +static json textDocumentURI( const URI& document ) { + return json{ { MEMBER_URI, document.toString() } }; +} + static json versionedTextDocumentIdentifier( const URI& document, int version = -1 ) { json map{ { MEMBER_URI, document.toString() } }; if ( version >= 0 ) @@ -224,10 +228,9 @@ static void fromJson( LSPServerCapabilities& caps, const json& json ) { auto sync = json["textDocumentSync"]; caps.textDocumentSync.change = static_cast( - ( sync.is_object() ? sync["change"].get() : sync.get() ) ); - if ( sync.is_object() ) { - auto syncObject = sync; - auto save = syncObject["save"]; + ( sync.is_object() ? sync["change"].get() : sync.get() ) ); + if ( sync.is_object() && sync.contains( "save" ) ) { + auto save = sync["save"]; if ( save.is_boolean() ) { caps.textDocumentSync.save.includeText = save.get(); } else if ( save.is_object() && save.contains( "includeText" ) ) { @@ -246,9 +249,11 @@ static void fromJson( LSPServerCapabilities& caps, const json& json ) { caps.documentSymbolProvider = toBoolOrObject( json, "documentSymbolProvider" ); caps.documentHighlightProvider = toBoolOrObject( json, "documentHighlightProvider" ); caps.documentFormattingProvider = toBoolOrObject( json, "documentFormattingProvider" ); - caps.documentRangeFormattingProvider = - toBoolOrObject( json, "documentRangeFormattingProvider" ); - fromJson( caps.documentOnTypeFormattingProvider, json["documentOnTypeFormattingProvider"] ); + if ( json.contains( "documentRangeFormattingProvider" ) ) + caps.documentRangeFormattingProvider = + toBoolOrObject( json, "documentRangeFormattingProvider" ); + if ( json.contains( "documentOnTypeFormattingProvider" ) ) + fromJson( caps.documentOnTypeFormattingProvider, json["documentOnTypeFormattingProvider"] ); caps.renameProvider = toBoolOrObject( json, "renameProvider" ); if ( json.contains( "codeActionProvider" ) && json["codeActionProvider"].contains( "resolveProvider" ) ) { @@ -793,7 +798,7 @@ void LSPClientServer::initialize() { { "semanticTokens", semanticTokens }, { "synchronization", json{ { "didSave", true } } }, { "selectionRange", json{ { "dynamicRegistration", false } } }, - { "hover", json{ { "contentFormat", { "markdown", "plaintext" } } } } }, + { "hover", json{ { "contentFormat", { "plaintext" } } } } }, }, { "window", json{ { "workDoneProgress", true } } }, { "general", json{ { "positionEncodings", json::array( { "utf-32" } ) } } } }; @@ -878,6 +883,16 @@ LSPClientServer::RequestHandle LSPClientServer::documentImplementation( const UR return getAndGoToLocation( document, pos, "textDocument/implementation" ); } +LSPClientServer::RequestHandle LSPClientServer::switchSourceHeader( const URI& document ) { + return send( newRequest( "textDocument/switchSourceHeader", textDocumentURI( document ) ), + [this]( json res ) { + if ( res.is_string() ) { + mManager->goToLocation( + { res.get(), TextRange{ { 0, 0 }, { 0, 0 } } } ); + } + } ); +} + LSPClientServer::RequestHandle LSPClientServer::didChangeWorkspaceFolders( const std::vector& added, const std::vector& removed ) { diff --git a/src/tools/ecode/plugins/lsp/lspclientserver.hpp b/src/tools/ecode/plugins/lsp/lspclientserver.hpp index e3da34e46..efc3ddef6 100644 --- a/src/tools/ecode/plugins/lsp/lspclientserver.hpp +++ b/src/tools/ecode/plugins/lsp/lspclientserver.hpp @@ -116,6 +116,8 @@ class LSPClientServer { LSPClientServer::RequestHandle getAndGoToLocation( const URI& document, const TextPosition& pos, const std::string& search ); + LSPClientServer::RequestHandle switchSourceHeader( const URI& document ); + protected: LSPClientServerManager* mManager{ nullptr }; String::HashType mId; diff --git a/src/tools/ecode/plugins/lsp/lspclientservermanager.cpp b/src/tools/ecode/plugins/lsp/lspclientservermanager.cpp index 59df0b19f..647ef0635 100644 --- a/src/tools/ecode/plugins/lsp/lspclientservermanager.cpp +++ b/src/tools/ecode/plugins/lsp/lspclientservermanager.cpp @@ -136,6 +136,10 @@ size_t LSPClientServerManager::clientCount() const { return mClients.size(); } +size_t LSPClientServerManager::lspCount() const { + return mLSPs.size(); +} + const std::shared_ptr& LSPClientServerManager::getThreadPool() const { return mThreadPool; } @@ -153,13 +157,11 @@ void LSPClientServerManager::updateDirty() { closeLSPServer( server ); } -void LSPClientServerManager::goToDocumentDefinition( TextDocument* doc ) { - for ( auto& server : mClients ) { - if ( server.second->hasDocument( doc ) ) { - server.second->documentDefinition( doc->getURI(), doc->getSelection().start() ); - return; - } - } +void LSPClientServerManager::getAndGoToLocation( const std::shared_ptr& doc, + const std::string& search ) { + auto* server = getOneLSPClientServer( doc ); + if ( server ) + server->getAndGoToLocation( doc->getURI(), doc->getSelection().start(), search ); } void LSPClientServerManager::didChangeWorkspaceFolders( const std::string& folder ) { diff --git a/src/tools/ecode/plugins/lsp/lspclientservermanager.hpp b/src/tools/ecode/plugins/lsp/lspclientservermanager.hpp index 1d16b223e..1517302cf 100644 --- a/src/tools/ecode/plugins/lsp/lspclientservermanager.hpp +++ b/src/tools/ecode/plugins/lsp/lspclientservermanager.hpp @@ -19,16 +19,20 @@ class LSPClientServerManager { void load( LSPClientPlugin*, const PluginManager* pluginManager, std::vector&& lsps ); + // async void run( const std::shared_ptr& doc ); + // sync + void tryRunServer( const std::shared_ptr& doc ); + size_t clientCount() const; + size_t lspCount() const; + const std::shared_ptr& getThreadPool() const; void updateDirty(); - void goToDocumentDefinition( TextDocument* doc ); - void didChangeWorkspaceFolders( const std::string& folder ); const LSPWorkspaceFolder& getLSPWorkspaceFolder() const; @@ -41,6 +45,8 @@ class LSPClientServerManager { LSPClientServer* getOneLSPClientServer( const std::shared_ptr& doc ); + void getAndGoToLocation( const std::shared_ptr& doc, const std::string& search ); + protected: friend class LSPClientServer; @@ -59,8 +65,6 @@ class LSPClientServerManager { std::string findRootPath( const LSPDefinition& lsp, const std::shared_ptr& doc ); - void tryRunServer( const std::shared_ptr& doc ); - void closeLSPServer( const String::HashType& id ); void goToLocation( const LSPLocation& loc ); diff --git a/src/tools/ecode/plugins/pluginmanager.cpp b/src/tools/ecode/plugins/pluginmanager.cpp index 09ee0b79f..9db94c113 100644 --- a/src/tools/ecode/plugins/pluginmanager.cpp +++ b/src/tools/ecode/plugins/pluginmanager.cpp @@ -112,6 +112,8 @@ void PluginManager::subscribeNotifications( UICodeEditorPlugin* plugin, std::function cb ) const { const_cast( this )->mSubscribedPlugins[plugin->getId()] = cb; + if ( !mWorkspaceFolder.empty() ) + cb( Notification::WorkspaceFolderChanged, json{ { "folder", mWorkspaceFolder } } ); } void PluginManager::unsubscribeNotifications( UICodeEditorPlugin* plugin ) const {