mirror of
https://github.com/SpartanJ/eepp.git
synced 2026-10-27 08:37:58 +03:00
ecode: Minor LSP improvements.
This commit is contained in:
@@ -53,7 +53,7 @@
|
||||
"language": "c",
|
||||
"name": "clangd",
|
||||
"url": "https://clang.llvm.org/extra/clangd/",
|
||||
"command": "clangd -log=error --background-index --limit-results=500 --completion-style=bundled",
|
||||
"command": "clangd -log=error --background-index --header-insertion=never --limit-results=0 --limit-references=0 --clang-tidy=0 --use-dirty-headers --completion-style=bundled -j=$NPROC",
|
||||
"file_patterns": ["%.c$", "%.h$", "%.C$", "%.H$", "%.objc$"]
|
||||
},
|
||||
{
|
||||
|
||||
@@ -71,6 +71,10 @@ static LSPURIAndServer getServerURIFromTextDocumentURI( LSPClientServerManager&
|
||||
return { uri, manager.getOneLSPClientServer( uri ) };
|
||||
}
|
||||
|
||||
static void sanitizeCommand( std::string& cmd ) {
|
||||
String::replaceAll( cmd, "$NPROC", String::toString( Sys::getCPUCount() ) );
|
||||
}
|
||||
|
||||
LSPPositionAndServer getLSPLocationFromJSON( LSPClientServerManager& manager, const json& data ) {
|
||||
if ( !data.contains( "uri" ) || !data.contains( "position" ) )
|
||||
return {};
|
||||
@@ -307,7 +311,7 @@ void LSPClientPlugin::loadLSPConfig( std::vector<LSPDefinition>& lsps, const std
|
||||
auto list = { "lsp-go-to-definition", "lsp-go-to-declaration",
|
||||
"lsp-go-to-implementation", "lsp-go-to-type-definition",
|
||||
"lsp-switch-header-source", "lsp-symbol-info",
|
||||
"lsp-symbol-references" };
|
||||
"lsp-symbol-references", "lsp-memory-usage" };
|
||||
for ( const auto& key : list ) {
|
||||
if ( kb.contains( key ) ) {
|
||||
if ( !kb[key].empty() )
|
||||
@@ -326,34 +330,47 @@ void LSPClientPlugin::loadLSPConfig( std::vector<LSPDefinition>& lsps, const std
|
||||
auto& servers = j["servers"];
|
||||
|
||||
for ( auto& obj : servers ) {
|
||||
bool lspOverwritten = false;
|
||||
// Allow disabling an LSP by redeclaring it in the user configuration file.
|
||||
if ( obj.contains( "name" ) && obj.contains( "disabled" ) &&
|
||||
obj.at( "disabled" ).is_boolean() ) {
|
||||
for ( auto& lsp : lsps ) {
|
||||
if ( lsp.name == obj["name"] ) {
|
||||
lsp.disabled = obj["disabled"].get<bool>();
|
||||
break;
|
||||
if ( updateConfigFile && ( obj.contains( "name" ) || obj.contains( "use" ) ) &&
|
||||
obj.contains( "disabled" ) && obj.at( "disabled" ).is_boolean() ) {
|
||||
std::string name = obj.contains( "name" ) ? obj["name"] : obj["use"];
|
||||
for ( auto& lspD : lsps ) {
|
||||
if ( lspD.name == name ) {
|
||||
lspD.disabled = obj["disabled"].get<bool>();
|
||||
lspOverwritten = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Allow overriding the command for already defined LSP
|
||||
// And allow adding parameters to the already defined LSP
|
||||
if ( obj.contains( "name" ) &&
|
||||
if ( updateConfigFile && ( obj.contains( "name" ) || obj.contains( "use" ) ) &&
|
||||
( ( obj.contains( "command" ) && obj.at( "command" ).is_string() ) ||
|
||||
( obj.contains( "command_parameters" ) &&
|
||||
obj.at( "command_parameters" ).is_string() ) ) ) {
|
||||
for ( auto& lsp : lsps ) {
|
||||
if ( lsp.name == obj["name"] ) {
|
||||
if ( !obj.value( "command", "" ).empty() )
|
||||
lsp.command = obj.value( "command", "" );
|
||||
if ( !obj.value( "command_parameters", "" ).empty() )
|
||||
lsp.commandParameters = obj.value( "command_parameters", "" );
|
||||
break;
|
||||
for ( auto& lspR : lsps ) {
|
||||
std::string name = obj.contains( "name" ) ? obj["name"] : obj["use"];
|
||||
if ( lspR.name == name ) {
|
||||
lspOverwritten = true;
|
||||
if ( !obj.value( "command", "" ).empty() ) {
|
||||
lspR.command = obj.value( "command", "" );
|
||||
sanitizeCommand( lspR.command );
|
||||
}
|
||||
if ( !obj.value( "command_parameters", "" ).empty() ) {
|
||||
std::string cmdParam( obj.value( "command_parameters", "" ) );
|
||||
if ( !cmdParam.empty() && cmdParam.front() != ' ' )
|
||||
cmdParam = " " + cmdParam;
|
||||
lspR.commandParameters += cmdParam;
|
||||
sanitizeCommand( lspR.commandParameters );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ( lspOverwritten )
|
||||
continue;
|
||||
|
||||
if ( !obj.contains( "language" ) || !obj.contains( "file_patterns" ) ) {
|
||||
Log::warning( "LSP server without language or file_patterns, ignored..." );
|
||||
continue;
|
||||
@@ -408,6 +425,9 @@ void LSPClientPlugin::loadLSPConfig( std::vector<LSPDefinition>& lsps, const std
|
||||
lsp.rootIndicationFileNames.push_back( fn );
|
||||
}
|
||||
|
||||
sanitizeCommand( lsp.command );
|
||||
sanitizeCommand( lsp.commandParameters );
|
||||
|
||||
// If the file pattern is repeated, we will overwrite the previous LSP.
|
||||
// The previous LSP should be the "default" LSP that comes with ecode.
|
||||
size_t pos = lspFilePatternPosition( lsps, lsp.filePatterns );
|
||||
@@ -473,6 +493,10 @@ void LSPClientPlugin::onRegister( UICodeEditor* editor ) {
|
||||
doc.setCommand( "lsp-symbol-references", [&, editor] {
|
||||
mClientManager.getSymbolReferences( editor->getDocumentRef() );
|
||||
} );
|
||||
|
||||
doc.setCommand( "lsp-memory-usage", [&, editor] {
|
||||
mClientManager.memoryUsage( editor->getDocumentRef() );
|
||||
} );
|
||||
}
|
||||
|
||||
std::vector<Uint32> listeners;
|
||||
@@ -585,6 +609,11 @@ bool LSPClientPlugin::onCreateContextMenu( UICodeEditor* editor, UIPopUpMenu* me
|
||||
if ( server->getDefinition().language == "cpp" || server->getDefinition().language == "c" )
|
||||
addFn( "lsp-switch-header-source", "Switch Header/Source" );
|
||||
|
||||
#ifdef EE_DEBUG
|
||||
if ( server->getDefinition().name == "clangd" )
|
||||
addFn( "lsp-memory-usage", "LSP Memory Usage" );
|
||||
#endif
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
@@ -892,8 +892,13 @@ LSPClientServer::~LSPClientServer() {
|
||||
}
|
||||
|
||||
bool LSPClientServer::start() {
|
||||
bool ret = mProcess.create( mLSP.command + mLSP.commandParameters, Process::getDefaultOptions(),
|
||||
{}, mRootPath );
|
||||
std::string cmd( mLSP.command );
|
||||
if ( !mLSP.commandParameters.empty() ) {
|
||||
if ( mLSP.commandParameters.front() != ' ' )
|
||||
mLSP.commandParameters = " " + mLSP.commandParameters;
|
||||
cmd += mLSP.commandParameters;
|
||||
}
|
||||
bool ret = mProcess.create( cmd, Process::getDefaultOptions(), {}, mRootPath );
|
||||
if ( ret && mProcess.isAlive() ) {
|
||||
mProcess.startAsyncRead(
|
||||
[this]( const char* bytes, size_t n ) { readStdOut( bytes, n ); },
|
||||
@@ -1216,7 +1221,6 @@ void LSPClientServer::processNotification( const json& msg ) {
|
||||
} else if ( method == ( "$/progress" ) ) {
|
||||
workDoneProgress( parseWorkDone( msg[MEMBER_PARAMS] ) );
|
||||
return;
|
||||
} else {
|
||||
}
|
||||
Log::debug( "LSPClientServer::processNotification server %s: %s", mLSP.name.c_str(),
|
||||
msg.dump().c_str() );
|
||||
@@ -1557,6 +1561,16 @@ LSPClientServer::documentFormatting( const URI& document, const json& options,
|
||||
} );
|
||||
}
|
||||
|
||||
LSPClientServer::LSPRequestHandle LSPClientServer::memoryUsage( const JsonReplyHandler& h ) {
|
||||
return send( newRequest( "$/memoryUsage" ), h );
|
||||
}
|
||||
|
||||
LSPClientServer::LSPRequestHandle LSPClientServer::memoryUsage() {
|
||||
return memoryUsage( []( const IdType&, const json& json ) {
|
||||
Log::warning( "Received Memory Usage Information:\n%s", json.dump( 2 ).c_str() );
|
||||
} );
|
||||
}
|
||||
|
||||
LSPClientServer::LSPRequestHandle
|
||||
LSPClientServer::documentSemanticTokensFull( const URI& document, bool delta,
|
||||
const std::string& requestId, const TextRange& range,
|
||||
@@ -1575,4 +1589,5 @@ LSPClientServer::documentSemanticTokensFull( const URI& document, bool delta,
|
||||
|
||||
return send( newRequest( "textDocument/semanticTokens/full", params ), h );
|
||||
}
|
||||
|
||||
} // namespace ecode
|
||||
|
||||
@@ -188,6 +188,11 @@ class LSPClientServer {
|
||||
LSPRequestHandle documentFormatting( const URI& document, const json& options,
|
||||
const TextEditArrayHandler& h );
|
||||
|
||||
|
||||
LSPRequestHandle memoryUsage( const JsonReplyHandler& h );
|
||||
|
||||
LSPRequestHandle memoryUsage();
|
||||
|
||||
void removeDoc( TextDocument* doc );
|
||||
|
||||
protected:
|
||||
|
||||
@@ -279,6 +279,13 @@ void LSPClientServerManager::getSymbolReferences( std::shared_ptr<TextDocument>
|
||||
} );
|
||||
}
|
||||
|
||||
void LSPClientServerManager::memoryUsage( std::shared_ptr<TextDocument> doc ) {
|
||||
auto* server = getOneLSPClientServer( doc );
|
||||
if ( !server )
|
||||
return;
|
||||
server->memoryUsage();
|
||||
}
|
||||
|
||||
void LSPClientServerManager::didChangeWorkspaceFolders( const std::string& folder ) {
|
||||
mLSPWorkspaceFolder = { "file://" + folder, FileSystem::fileNameFromPath( folder ) };
|
||||
Lock l( mClientsMutex );
|
||||
|
||||
@@ -66,6 +66,8 @@ class LSPClientServerManager {
|
||||
|
||||
void getSymbolReferences( std::shared_ptr<TextDocument> doc );
|
||||
|
||||
void memoryUsage( std::shared_ptr<TextDocument> doc );
|
||||
|
||||
protected:
|
||||
friend class LSPClientServer;
|
||||
PluginManager* mPluginManager{ nullptr };
|
||||
|
||||
Reference in New Issue
Block a user