ecode: More minor improvements to the LSP plugin. Added rustfmt formatter, and added rust-analyzer LSP. Fixed plugins exit.

This commit is contained in:
Martín Lucas Golini
2022-11-06 03:13:27 -03:00
parent 4fb79c2771
commit eded28f70b
10 changed files with 63 additions and 53 deletions

View File

@@ -47,13 +47,20 @@ static const char* MEMBER_TARGET_SELECTION_RANGE = "targetSelectionRange";
// static const char* MEMBER_PREVIOUS_RESULT_ID = "previousResultId";
// static const char* MEMBER_QUERY = "query";
static json newRequest( const std::string& method, const json& params = {} ) {
static json newRequest( const std::string& method, const json& params = json{} ) {
json j;
j[MEMBER_METHOD] = method;
j[MEMBER_PARAMS] = params.empty() ? json() : params;
return j;
}
static json newResponse( const std::string& method, const int& id ) {
json j;
j[MEMBER_METHOD] = method;
j[MEMBER_ID] = id;
return j;
}
static json textDocumentURI( const URI& document ) {
return json{ { MEMBER_URI, document.toString() } };
}
@@ -181,10 +188,10 @@ static void fromJson( std::vector<char>& trigger, const json& json ) {
static void fromJson( LSPCompletionOptions& options, const json& json ) {
if ( !json.empty() && json.is_object() ) {
auto ob = json;
options.provider = true;
options.resolveProvider = ob["resolveProvider"].get<bool>();
fromJson( options.triggerCharacters, ob["triggerCharacters"] );
if ( json.contains( "resolveProvider" ) && !json["resolveProvider"].is_null() )
options.resolveProvider = json["resolveProvider"].get<bool>();
fromJson( options.triggerCharacters, json["triggerCharacters"] );
}
}
@@ -362,15 +369,17 @@ static LSPResponseError parseResponseError( const json& v ) {
return ret;
}
static std::vector<LSPTextEdit> parseTextEdit( const json& result ) {
static LSPTextEdit parseTextEdit( const json& result ) {
LSPTextEdit edit;
edit.text = result.at( "newText" ).get<std::string>();
edit.range = parseRange( result.at( MEMBER_RANGE ) );
return edit;
}
static std::vector<LSPTextEdit> parseTextEditArray( const json& result ) {
std::vector<LSPTextEdit> ret;
const auto textEdits = result;
for ( const auto& redit : textEdits ) {
auto edit = redit;
auto text = edit.at( "newText" ).get<std::string>();
auto range = parseRange( edit.at( MEMBER_RANGE ) );
ret.push_back( { range, text } );
}
for ( const auto& edit : result )
ret.push_back( parseTextEdit( edit ) );
return ret;
}
@@ -386,7 +395,7 @@ static LSPTextDocumentEdit parseTextDocumentEdit( const json& result ) {
LSPTextDocumentEdit ret;
auto ob = result;
fromJson( ret.textDocument, ob.at( "textDocument" ) );
ret.edits = parseTextEdit( ob.at( "edits" ) );
ret.edits = parseTextEditArray( ob.at( "edits" ) );
return ret;
}
@@ -395,7 +404,7 @@ static LSPWorkspaceEdit parseWorkSpaceEdit( const json& result ) {
auto changes = result.at( "changes" );
for ( auto it = changes.begin(); it != changes.end(); ++it ) {
ret.changes.insert( std::pair<URI, std::vector<LSPTextEdit>>(
URI( it.key() ), parseTextEdit( it.value() ) ) );
URI( it.key() ), parseTextEditArray( it.value() ) ) );
}
auto documentChanges = result.at( "documentChanges" );
// resourceOperations not supported for now
@@ -584,40 +593,32 @@ static std::vector<LSPCompletionItem> parseDocumentCompletion( const json& resul
LSPMarkupContent doc = item.contains( MEMBER_DOCUMENTATION )
? parseMarkupContent( item.at( MEMBER_DOCUMENTATION ) )
: LSPMarkupContent{};
auto sortText = item.value( "sortText", "" );
if ( sortText.empty() )
sortText = label;
auto insertText = item.value( "insertText", "" );
if ( insertText.empty() )
insertText = label;
if ( item.contains( "textEdit" ) ) {
const auto& textEdit = item["textEdit"];
if ( !textEdit.empty() ) {
auto newText = textEdit.value( "newText", "" );
insertText = newText;
}
}
auto filterText = item.value( "filterText", label );
auto insertText = item.value( "insertText", label );
auto sortText = item.value( "sortText", label );
LSPTextEdit textEdit;
if ( item.contains( "textEdit" ) )
textEdit = parseTextEdit( item["textEdit"] );
auto kind = static_cast<LSPCompletionItemKind>( item.value( MEMBER_KIND, 1 ) );
const std::vector<LSPTextEdit> additionalTextEdits =
item.contains( "additionalTextEdits" )
? parseTextEdit( item.at( "additionalTextEdits" ) )
? parseTextEditArray( item.at( "additionalTextEdits" ) )
: std::vector<LSPTextEdit>{};
ret.push_back( { label, kind, detail, doc, sortText, insertText,
additionalTextEdits /*, textEdit*/ } );
ret.push_back( { label, kind, detail, doc, sortText, insertText, filterText, textEdit,
additionalTextEdits } );
}
return ret;
}
void LSPClientServer::initialize() {
json codeAction{
{ "codeActionLiteralSupport", json{ { "codeActionKind", json{ { "valueSet", {} } } } } } };
json codeAction{ { "codeActionLiteralSupport",
json{ { "codeActionKind", json{ { "valueSet", json::array() } } } } } };
json semanticTokens{
{ "requests", json{ { "range", true }, { "full", json{ { "delta", true } } } } },
{ "tokenTypes", supportedSemanticTokenTypes() },
{ "tokenModifiers", {} },
{ "tokenModifiers", json::array() },
{ "formats", { "relative" } },
};
@@ -690,7 +691,7 @@ LSPClientServer::~LSPClientServer() {
bool LSPClientServer::start() {
bool ret = mProcess.create( mLSP.command, Process::getDefaultOptions(), {}, mRootPath );
if ( ret ) {
if ( ret && mProcess.isAlive() ) {
mProcess.startAsyncRead(
[this]( const char* bytes, size_t n ) { readStdOut( bytes, n ); },
[this]( const char* bytes, size_t n ) { readStdErr( bytes, n ); } );
@@ -761,6 +762,9 @@ LSPClientServer::RequestHandle LSPClientServer::write( const json& msg, const Js
method = msg[MEMBER_METHOD].get<std::string>();
else if ( msg.contains( MEMBER_MESSAGE ) )
method = msg[MEMBER_MESSAGE];
if ( method == "workspace/didChangeWorkspaceFolders" &&
!mCapabilities.workspaceFolders.supported )
return ret;
Log::info( "LSPClientServer server %s calling %s", mLSP.name.c_str(), method.c_str() );
Log::debug( "LSPClientServer server %s sending message:\n%s", mLSP.name.c_str(),
sjson.c_str() );
@@ -977,6 +981,10 @@ void LSPClientServer::processRequest( const json& msg ) {
auto msgid = msg[MEMBER_ID].get<int>();
// auto params = msg[MEMBER_PARAMS];
// bool handled = false;
if ( method == "window/workDoneProgress/create" || method == "client/registerCapability" ) {
write( newResponse( method, msgid ) );
return;
}
write( newError( LSPErrorCode::MethodNotFound, method ), nullptr, nullptr, msgid );
}