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

@@ -170,10 +170,6 @@ bool AutoCompletePlugin::onKeyDown( UICodeEditor* editor, const KeyEvent& event
return false;
}
bool AutoCompletePlugin::onKeyUp( UICodeEditor*, const KeyEvent& ) {
return false;
}
bool AutoCompletePlugin::onTextInput( UICodeEditor* editor, const TextInputEvent& ) {
std::string partialSymbol( getPartialSymbol( &editor->getDocument() ) );
if ( partialSymbol.size() >= 3 ) {
@@ -252,9 +248,6 @@ void AutoCompletePlugin::update( UICodeEditor* ) {
}
}
void AutoCompletePlugin::preDraw( UICodeEditor*, const Vector2f&, const Float&,
const TextPosition& ) {}
void AutoCompletePlugin::postDraw( UICodeEditor* editor, const Vector2f& startScroll,
const Float& lineHeight, const TextPosition& cursor ) {
std::vector<std::string> suggestions;

View File

@@ -43,10 +43,8 @@ class AutoCompletePlugin : public UICodeEditorPlugin {
void onRegister( UICodeEditor* );
void onUnregister( UICodeEditor* );
bool onKeyDown( UICodeEditor*, const KeyEvent& );
bool onKeyUp( UICodeEditor*, const KeyEvent& );
bool onTextInput( UICodeEditor*, const TextInputEvent& );
void update( UICodeEditor* );
void preDraw( UICodeEditor*, const Vector2f&, const Float&, const TextPosition& );
void postDraw( UICodeEditor*, const Vector2f& startScroll, const Float& lineHeight,
const TextPosition& cursor );
bool onMouseDown( UICodeEditor*, const Vector2i&, const Uint32& );

View File

@@ -295,6 +295,8 @@ struct LSPCompletionItem {
LSPMarkupContent documentation;
std::string sortText;
std::string insertText;
std::string filterText;
LSPTextEdit textEdit;
std::vector<LSPTextEdit> additionalTextEdits;
};

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 );
}

View File

@@ -108,6 +108,13 @@ void PluginManager::setWorkspaceFolder( const std::string& workspaceFolder ) {
json{ { "folder", mWorkspaceFolder } } );
}
void PluginManager::pushNotification( UICodeEditorPlugin* pluginWho, Notification notification,
const nlohmann::json& json ) const {
for ( const auto& plugin : mSubscribedPlugins )
if ( pluginWho->getId() != plugin.first )
plugin.second( notification, json );
}
void PluginManager::subscribeNotifications(
UICodeEditorPlugin* plugin,
std::function<void( Notification, const nlohmann::json& )> cb ) const {

View File

@@ -104,6 +104,9 @@ class PluginManager {
void setWorkspaceFolder( const std::string& workspaceFolder );
void pushNotification( UICodeEditorPlugin* pluginWho, Notification,
const nlohmann::json& ) const;
void
subscribeNotifications( UICodeEditorPlugin* plugin,
std::function<void( Notification, const nlohmann::json& )> cb ) const;