mirror of
https://github.com/SpartanJ/eepp.git
synced 2026-05-30 18:16:31 +03:00
eepp: Added a new flag to UIWindow to create ephemeral windows (windows that close on focus loss).
629 lines
15 KiB
C++
629 lines
15 KiB
C++
#ifndef ECODE_LSPCLIENTPROTOCOL_HPP
|
|
#define ECODE_LSPCLIENTPROTOCOL_HPP
|
|
|
|
#include <eepp/ui/doc/textdocument.hpp>
|
|
#include <nlohmann/json.hpp>
|
|
#include <string>
|
|
|
|
using namespace EE;
|
|
using namespace EE::UI::Doc;
|
|
using namespace EE::Network;
|
|
|
|
// The LSP protocol will be consumed by any plugin, and it's not exclusive to the LSP plugin
|
|
// The protocol should be taken as a reference on how to implement the comunication between plugins
|
|
|
|
namespace ecode {
|
|
|
|
enum class LSPErrorCode {
|
|
// Defined by JSON RPC
|
|
ParseError = -32700,
|
|
InvalidRequest = -32600,
|
|
MethodNotFound = -32601,
|
|
InvalidParams = -32602,
|
|
InternalError = -32603,
|
|
serverErrorStart = -32099,
|
|
serverErrorEnd = -32000,
|
|
ServerNotInitialized = -32002,
|
|
UnknownErrorCode = -32001,
|
|
|
|
// Defined by the protocol.
|
|
RequestCancelled = -32800,
|
|
ContentModified = -32801
|
|
};
|
|
|
|
struct LSPPosition {
|
|
URI uri;
|
|
TextPosition pos;
|
|
};
|
|
|
|
struct LSPLocation {
|
|
URI uri;
|
|
TextRange range;
|
|
};
|
|
|
|
struct LSPWorkspaceFolder {
|
|
URI uri;
|
|
std::string name;
|
|
|
|
bool isEmpty() { return uri.empty(); }
|
|
};
|
|
|
|
enum class LSPDocumentSyncKind { None = 0, Full = 1, Incremental = 2 };
|
|
|
|
struct LSPSaveOptions {
|
|
bool includeText = false;
|
|
};
|
|
|
|
struct LSPTextDocumentSyncOptions {
|
|
LSPDocumentSyncKind change = LSPDocumentSyncKind::None;
|
|
LSPSaveOptions save;
|
|
};
|
|
|
|
struct LSPCompletionOptions {
|
|
bool provider = false;
|
|
bool resolveProvider = false;
|
|
std::vector<char> triggerCharacters;
|
|
};
|
|
|
|
struct LSPSignatureHelpOptions {
|
|
bool provider = false;
|
|
std::vector<char> triggerCharacters;
|
|
};
|
|
|
|
struct LSPDocumentOnTypeFormattingOptions : public LSPSignatureHelpOptions {};
|
|
|
|
struct SemanticTokenTypes {
|
|
enum : Uint32 {
|
|
Unknown = String::hash( "unknown" ),
|
|
Namespace = String::hash( "namespace" ),
|
|
Type = String::hash( "type" ),
|
|
Class = String::hash( "class" ),
|
|
Enum = String::hash( "enum" ),
|
|
Interface = String::hash( "interface" ),
|
|
Struct = String::hash( "struct" ),
|
|
TypeParameter = String::hash( "typeParameter" ),
|
|
Parameter = String::hash( "parameter" ),
|
|
Variable = String::hash( "variable" ),
|
|
Property = String::hash( "property" ),
|
|
EnumMember = String::hash( "enumMember" ),
|
|
Event = String::hash( "event" ),
|
|
Function = String::hash( "function" ),
|
|
Method = String::hash( "method" ),
|
|
Macro = String::hash( "macro" ),
|
|
Keyword = String::hash( "keyword" ),
|
|
Modifier = String::hash( "modifier" ),
|
|
Comment = String::hash( "comment" ),
|
|
Str = String::hash( "string" ),
|
|
Number = String::hash( "number" ),
|
|
Regexp = String::hash( "regexp" ),
|
|
Operator = String::hash( "operator" ),
|
|
Decorator = String::hash( "decorator" ),
|
|
Member = String::hash( "member" ),
|
|
};
|
|
};
|
|
|
|
// Ref:
|
|
// https://microsoft.github.io/language-server-protocol/specification#textDocument_semanticTokens
|
|
struct SemanticTokensLegend {
|
|
/**
|
|
* The token types a server uses.
|
|
*/
|
|
std::vector<std::string> tokenTypes;
|
|
|
|
/**
|
|
* The token modifiers a server uses.
|
|
*/
|
|
std::vector<std::string> tokenModifiers;
|
|
};
|
|
|
|
struct LSPSemanticTokensOptions {
|
|
bool full = false;
|
|
bool fullDelta = false;
|
|
bool range = false;
|
|
SemanticTokensLegend legend;
|
|
};
|
|
|
|
struct LSPWorkspaceFoldersServerCapabilities {
|
|
bool supported = false;
|
|
bool changeNotifications = false;
|
|
};
|
|
|
|
struct LSPCodeLensOptions {
|
|
bool supported = false;
|
|
bool resolveProvider = false;
|
|
};
|
|
|
|
struct LSPServerCapabilities {
|
|
bool ready = false;
|
|
std::vector<std::string> languages;
|
|
LSPTextDocumentSyncOptions textDocumentSync;
|
|
bool hoverProvider = false;
|
|
LSPCompletionOptions completionProvider;
|
|
LSPSignatureHelpOptions signatureHelpProvider;
|
|
bool astProvider = false;
|
|
bool definitionProvider = false;
|
|
// official extension as of 3.14.0
|
|
bool declarationProvider = false;
|
|
bool typeDefinitionProvider = false;
|
|
bool referencesProvider = false;
|
|
bool implementationProvider = false;
|
|
bool documentSymbolProvider = false;
|
|
bool documentHighlightProvider = false;
|
|
bool documentFormattingProvider = false;
|
|
bool documentRangeFormattingProvider = false;
|
|
bool foldingRangeProvider = false;
|
|
LSPCodeLensOptions codeLensProvider;
|
|
bool workspaceSymbolProvider = false;
|
|
LSPDocumentOnTypeFormattingOptions documentOnTypeFormattingProvider;
|
|
bool renameProvider = false;
|
|
// CodeActionOptions not useful/considered at present
|
|
bool codeActionProvider = false;
|
|
LSPSemanticTokensOptions semanticTokenProvider;
|
|
// workspace caps flattened
|
|
// (other parts not useful/considered at present)
|
|
LSPWorkspaceFoldersServerCapabilities workspaceFolders;
|
|
bool selectionRangeProvider = false;
|
|
bool executeCommandProvider = false;
|
|
};
|
|
|
|
enum class LSPMessageType { Error = 1, Warning = 2, Info = 3, Log = 4 };
|
|
|
|
struct LSPMessageActionItem {
|
|
std::string title;
|
|
};
|
|
|
|
struct LSPShowMessageParams {
|
|
LSPMessageType type{ LSPMessageType::Log };
|
|
std::string message;
|
|
std::vector<LSPMessageActionItem> actions;
|
|
bool allowCopy{ false };
|
|
};
|
|
|
|
struct LSPTextDocumentContentChangeEvent {
|
|
TextRange range;
|
|
std::string text;
|
|
};
|
|
|
|
enum class LSPDiagnosticSeverity {
|
|
Unknown = 0,
|
|
Error = 1,
|
|
Warning = 2,
|
|
Information = 3,
|
|
Hint = 4,
|
|
};
|
|
|
|
using LSPTextEdit = LSPTextDocumentContentChangeEvent;
|
|
|
|
struct LSPVersionedTextDocumentIdentifier {
|
|
URI uri;
|
|
int version = -1;
|
|
};
|
|
|
|
struct LSPTextDocumentEdit {
|
|
LSPVersionedTextDocumentIdentifier textDocument;
|
|
std::vector<LSPTextEdit> edits;
|
|
};
|
|
|
|
struct LSPWorkspaceEdit {
|
|
// supported part for now
|
|
std::map<URI, std::vector<LSPTextEdit>> changes;
|
|
std::vector<LSPTextDocumentEdit> documentChanges;
|
|
};
|
|
|
|
struct LSPDiagnosticRelatedInformation {
|
|
// empty url / invalid range when absent
|
|
LSPLocation location;
|
|
std::string message;
|
|
};
|
|
|
|
struct LSPDiagnosticsCodeAction {
|
|
std::string title;
|
|
std::string kind;
|
|
bool isPreferred{ false };
|
|
LSPWorkspaceEdit edit;
|
|
};
|
|
|
|
struct LSPDiagnostic {
|
|
TextRange range;
|
|
LSPDiagnosticSeverity severity{ LSPDiagnosticSeverity::Unknown };
|
|
std::string code;
|
|
std::string source;
|
|
std::string message;
|
|
std::vector<LSPDiagnosticRelatedInformation> relatedInformation;
|
|
std::vector<LSPDiagnosticsCodeAction> codeActions;
|
|
nlohmann::json data;
|
|
};
|
|
|
|
struct LSPPublishDiagnosticsParams {
|
|
URI uri;
|
|
std::vector<LSPDiagnostic> diagnostics;
|
|
};
|
|
|
|
struct LSPCommand {
|
|
std::string title;
|
|
std::string command;
|
|
// pretty opaque
|
|
nlohmann::json arguments;
|
|
};
|
|
|
|
struct LSPCodeAction {
|
|
std::string title;
|
|
std::string kind;
|
|
std::vector<LSPDiagnostic> diagnostics;
|
|
LSPWorkspaceEdit edit;
|
|
LSPCommand command;
|
|
bool isPreferred{ false };
|
|
};
|
|
|
|
struct LSPCodeLens {
|
|
TextRange range;
|
|
LSPCommand command;
|
|
nlohmann::json data;
|
|
};
|
|
|
|
enum class LSPWorkDoneProgressKind { Begin, Report, End };
|
|
|
|
struct LSPWorkDoneProgressValue {
|
|
LSPWorkDoneProgressKind kind;
|
|
std::string title;
|
|
std::string message;
|
|
bool cancellable;
|
|
unsigned percentage;
|
|
};
|
|
template <typename T> struct LSPProgressParams {
|
|
// number or string
|
|
nlohmann::json token;
|
|
T value;
|
|
};
|
|
|
|
enum class LSPSymbolKind {
|
|
File = 1,
|
|
Module = 2,
|
|
Namespace = 3,
|
|
Package = 4,
|
|
Class = 5,
|
|
Method = 6,
|
|
Property = 7,
|
|
Field = 8,
|
|
Constructor = 9,
|
|
Enum = 10,
|
|
Interface = 11,
|
|
Function = 12,
|
|
Variable = 13,
|
|
Constant = 14,
|
|
String = 15,
|
|
Number = 16,
|
|
Boolean = 17,
|
|
Array = 18,
|
|
Object = 19,
|
|
Key = 20,
|
|
Null = 21,
|
|
EnumMember = 22,
|
|
Struct = 23,
|
|
Event = 24,
|
|
Operator = 25,
|
|
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,
|
|
const std::string& _detail ) :
|
|
name( _name ), detail( _detail ), kind( _kind ), range( _range ) {}
|
|
std::string name;
|
|
std::string detail;
|
|
LSPSymbolKind kind{ LSPSymbolKind::File };
|
|
URI url;
|
|
TextRange range;
|
|
TextRange selectionRange;
|
|
double score = 0.0;
|
|
std::vector<LSPSymbolInformation> children;
|
|
LSPSymbolInformation* parent{ nullptr };
|
|
|
|
void updateParentsRefs() {
|
|
for ( auto& child : children ) {
|
|
child.parent = this;
|
|
child.updateParentsRefs();
|
|
}
|
|
}
|
|
};
|
|
|
|
using LSPSymbolInformationList = std::vector<LSPSymbolInformation>;
|
|
|
|
struct LSPSymbolInformationListHelper {
|
|
static bool isFlat( const LSPSymbolInformationList& list ) {
|
|
for ( const auto& l : list )
|
|
if ( !l.children.empty() )
|
|
return false;
|
|
return true;
|
|
}
|
|
|
|
static LSPSymbolInformationList flatten( const LSPSymbolInformationList& list ) {
|
|
LSPSymbolInformationList newList;
|
|
for ( const auto& l : list ) {
|
|
if ( l.children.empty() ) {
|
|
newList.push_back( l );
|
|
} else {
|
|
auto nl = l;
|
|
nl.children.clear();
|
|
newList.push_back( nl );
|
|
auto clist = flatten( l.children );
|
|
for ( const auto& cl : clist )
|
|
newList.push_back( cl );
|
|
}
|
|
}
|
|
return newList;
|
|
}
|
|
};
|
|
|
|
using LSPWorkDoneProgressParams = LSPProgressParams<LSPWorkDoneProgressValue>;
|
|
|
|
struct LSPResponseError {
|
|
LSPErrorCode code{};
|
|
std::string message;
|
|
nlohmann::json data;
|
|
};
|
|
|
|
enum class LSPMarkupKind { None = 0, PlainText = 1, MarkDown = 2 };
|
|
|
|
struct LSPMarkupContent {
|
|
LSPMarkupKind kind = LSPMarkupKind::None;
|
|
std::string value;
|
|
};
|
|
|
|
struct LSPHover {
|
|
std::vector<LSPMarkupContent> contents;
|
|
TextRange range;
|
|
};
|
|
|
|
enum class LSPCompletionItemKind {
|
|
Text = 1,
|
|
Method = 2,
|
|
Function = 3,
|
|
Constructor = 4,
|
|
Field = 5,
|
|
Variable = 6,
|
|
Class = 7,
|
|
Interface = 8,
|
|
Module = 9,
|
|
Property = 10,
|
|
Unit = 11,
|
|
Value = 12,
|
|
Enum = 13,
|
|
Keyword = 14,
|
|
Snippet = 15,
|
|
Color = 16,
|
|
File = 17,
|
|
Reference = 18,
|
|
Folder = 19,
|
|
EnumMember = 20,
|
|
Constant = 21,
|
|
Struct = 22,
|
|
Event = 23,
|
|
Operator = 24,
|
|
TypeParameter = 25,
|
|
};
|
|
|
|
class LSPCompletionItemHelper {
|
|
public:
|
|
static std::string toIconString( const LSPCompletionItemKind& kind ) {
|
|
switch ( kind ) {
|
|
case LSPCompletionItemKind::Text:
|
|
return "symbol-text";
|
|
case LSPCompletionItemKind::Method:
|
|
return "symbol-method";
|
|
case LSPCompletionItemKind::Function:
|
|
return "symbol-function";
|
|
case LSPCompletionItemKind::Constructor:
|
|
return "symbol-constructor";
|
|
case LSPCompletionItemKind::Field:
|
|
return "symbol-field";
|
|
case LSPCompletionItemKind::Variable:
|
|
return "symbol-variable";
|
|
case LSPCompletionItemKind::Class:
|
|
return "symbol-class";
|
|
case LSPCompletionItemKind::Interface:
|
|
return "symbol-interface";
|
|
case LSPCompletionItemKind::Module:
|
|
return "symbol-module";
|
|
case LSPCompletionItemKind::Property:
|
|
return "symbol-property";
|
|
case LSPCompletionItemKind::Unit:
|
|
return "symbol-unit";
|
|
case LSPCompletionItemKind::Value:
|
|
return "symbol-value";
|
|
case LSPCompletionItemKind::Enum:
|
|
return "symbol-enum";
|
|
case LSPCompletionItemKind::Keyword:
|
|
return "symbol-keyword";
|
|
case LSPCompletionItemKind::Snippet:
|
|
return "symbol-snippet";
|
|
case LSPCompletionItemKind::Color:
|
|
return "symbol-color";
|
|
case LSPCompletionItemKind::File:
|
|
return "symbol-file";
|
|
case LSPCompletionItemKind::Reference:
|
|
return "symbol-reference";
|
|
case LSPCompletionItemKind::Folder:
|
|
return "symbol-folder";
|
|
case LSPCompletionItemKind::EnumMember:
|
|
return "symbol-enum-member";
|
|
case LSPCompletionItemKind::Constant:
|
|
return "symbol-constant";
|
|
case LSPCompletionItemKind::Struct:
|
|
return "symbol-struct";
|
|
case LSPCompletionItemKind::Event:
|
|
return "symbol-event";
|
|
case LSPCompletionItemKind::Operator:
|
|
return "symbol-operator";
|
|
case LSPCompletionItemKind::TypeParameter:
|
|
return "symbol-type-parameter";
|
|
}
|
|
return "symbol-text";
|
|
}
|
|
};
|
|
|
|
struct LSPCompletionItem {
|
|
std::string label;
|
|
LSPCompletionItemKind kind;
|
|
std::string detail;
|
|
LSPMarkupContent documentation;
|
|
std::string sortText;
|
|
std::string insertText;
|
|
std::string filterText;
|
|
LSPTextEdit textEdit;
|
|
std::vector<LSPTextEdit> additionalTextEdits;
|
|
};
|
|
|
|
struct LSPCompletionList {
|
|
bool isIncomplete{ false };
|
|
std::vector<LSPCompletionItem> items;
|
|
};
|
|
|
|
struct LSPSelectionRange {
|
|
TextRange range;
|
|
std::shared_ptr<LSPSelectionRange> parent;
|
|
};
|
|
|
|
struct LSPParameterInformation {
|
|
// offsets into overall signature label
|
|
// (-1 if invalid)
|
|
int start{ -1 };
|
|
int end{ -1 };
|
|
};
|
|
|
|
struct LSPSignatureInformation {
|
|
std::string label;
|
|
LSPMarkupContent documentation;
|
|
std::vector<LSPParameterInformation> parameters;
|
|
};
|
|
|
|
struct LSPSignatureHelp {
|
|
std::vector<LSPSignatureInformation> signatures;
|
|
int activeSignature{ 0 };
|
|
int activeParameter{ 0 };
|
|
};
|
|
|
|
struct LSPConverter {
|
|
static TextPosition parsePosition( const nlohmann::json& data ) {
|
|
if ( data.contains( "line" ) && data.contains( "character" ) )
|
|
return { data["line"].get<Int64>(), data["character"].get<Int64>() };
|
|
return {};
|
|
}
|
|
|
|
static TextRange parseRange( const nlohmann::json& range ) {
|
|
if ( !range.contains( "start" ) || !range.contains( "end" ) )
|
|
return {};
|
|
auto startpos = parsePosition( range["start"] );
|
|
auto endpos = parsePosition( range["end"] );
|
|
return { startpos, endpos };
|
|
}
|
|
};
|
|
|
|
struct LSPShowDocumentParams {
|
|
URI uri;
|
|
bool external{ true };
|
|
bool takeFocus{ false };
|
|
TextRange selection;
|
|
};
|
|
|
|
struct LSPApplyWorkspaceEditParams {
|
|
std::string label;
|
|
LSPWorkspaceEdit edit;
|
|
};
|
|
|
|
struct LSPApplyWorkspaceEditResponse {
|
|
bool applied;
|
|
std::string failureReason;
|
|
};
|
|
|
|
struct LSPSemanticTokensEdit {
|
|
Uint32 start = 0;
|
|
Uint32 deleteCount = 0;
|
|
std::vector<Int32> data;
|
|
};
|
|
|
|
struct LSPSemanticTokensDelta {
|
|
std::string resultId;
|
|
std::vector<LSPSemanticTokensEdit> edits;
|
|
std::vector<Int32> data;
|
|
};
|
|
|
|
enum class LSPFoldingRangeKind : String::HashType {
|
|
Comment = String::hash( "comment" ),
|
|
Imports = String::hash( "imports" ),
|
|
Region = String::hash( "region" ),
|
|
};
|
|
|
|
struct LSPFoldingRange {
|
|
unsigned int startLine;
|
|
unsigned int endLine;
|
|
LSPFoldingRangeKind kind{ LSPFoldingRangeKind::Region };
|
|
};
|
|
|
|
} // namespace ecode
|
|
|
|
#endif // ECODE_LSPCLIENTPROTOCOL_HPP
|