2a17590bf4
* Added textDocument/foldingRange * Added support for code regions * Fixed warning message in foldingRangeHandler Co-authored-by: LucaSas <sas.luca.alex@gmail.com>
529 lines
14 KiB
Zig
529 lines
14 KiB
Zig
const std = @import("std");
|
|
const string = []const u8;
|
|
|
|
// LSP types
|
|
// https://microsoft.github.io/language-server-protocol/specifications/lsp/3.17/specification/
|
|
|
|
pub const Position = struct {
|
|
line: u32,
|
|
character: u32,
|
|
};
|
|
|
|
pub const Range = struct {
|
|
start: Position,
|
|
end: Position,
|
|
};
|
|
|
|
pub const Location = struct {
|
|
uri: string,
|
|
range: Range,
|
|
};
|
|
|
|
/// Id of a request
|
|
pub const RequestId = union(enum) {
|
|
String: string,
|
|
Integer: i32,
|
|
};
|
|
|
|
/// Params of a response (result)
|
|
pub const ResponseParams = union(enum) {
|
|
SignatureHelp: SignatureHelp,
|
|
CompletionList: CompletionList,
|
|
Location: Location,
|
|
Hover: Hover,
|
|
DocumentSymbols: []DocumentSymbol,
|
|
SemanticTokensFull: SemanticTokens,
|
|
InlayHint: []InlayHint,
|
|
TextEdits: []TextEdit,
|
|
Locations: []Location,
|
|
WorkspaceEdit: WorkspaceEdit,
|
|
InitializeResult: InitializeResult,
|
|
ConfigurationParams: ConfigurationParams,
|
|
RegistrationParams: RegistrationParams,
|
|
DocumentHighlight: []DocumentHighlight,
|
|
CodeAction: []CodeAction,
|
|
ApplyEdit: ApplyWorkspaceEditParams,
|
|
FoldingRange: []FoldingRange,
|
|
};
|
|
|
|
pub const Response = struct {
|
|
jsonrpc: string = "2.0",
|
|
id: RequestId,
|
|
result: ResponseParams,
|
|
};
|
|
|
|
pub const Request = struct {
|
|
jsonrpc: string = "2.0",
|
|
id: RequestId,
|
|
method: []const u8,
|
|
params: ?ResponseParams,
|
|
};
|
|
|
|
pub const ResponseError = struct {
|
|
code: i32,
|
|
message: string,
|
|
data: std.json.Value,
|
|
};
|
|
|
|
pub const ErrorCodes = enum(i32) {
|
|
// Defined by JSON-RPC
|
|
ParseError = -32700,
|
|
InvalidRequest = -32600,
|
|
MethodNotFound = -32601,
|
|
InvalidParams = -32602,
|
|
InternalError = -32603,
|
|
|
|
// JSON-RPC reserved error codes
|
|
ServerNotInitialized = -32002,
|
|
UnknownErrorCode = -3200,
|
|
|
|
// LSP reserved error codes
|
|
RequestFailed = -32803,
|
|
ServerCancelled = -32802,
|
|
ContentModified = -32801,
|
|
RequestCancelled = -32800,
|
|
};
|
|
|
|
pub const Notification = struct {
|
|
jsonrpc: string = "2.0",
|
|
method: string,
|
|
params: NotificationParams,
|
|
};
|
|
|
|
pub const NotificationParams = union(enum) {
|
|
LogMessage: struct {
|
|
type: MessageType,
|
|
message: string,
|
|
},
|
|
PublishDiagnostics: struct {
|
|
uri: string,
|
|
diagnostics: []Diagnostic,
|
|
},
|
|
ShowMessage: struct {
|
|
type: MessageType,
|
|
message: string,
|
|
},
|
|
};
|
|
|
|
/// Type of a debug message
|
|
pub const MessageType = enum(i64) {
|
|
Error = 1,
|
|
Warning = 2,
|
|
Info = 3,
|
|
Log = 4,
|
|
|
|
pub fn jsonStringify(value: MessageType, options: std.json.StringifyOptions, out_stream: anytype) !void {
|
|
try std.json.stringify(@enumToInt(value), options, out_stream);
|
|
}
|
|
};
|
|
|
|
pub const DiagnosticSeverity = enum(i64) {
|
|
Error = 1,
|
|
Warning = 2,
|
|
Information = 3,
|
|
Hint = 4,
|
|
|
|
pub fn jsonStringify(value: DiagnosticSeverity, options: std.json.StringifyOptions, out_stream: anytype) !void {
|
|
try std.json.stringify(@enumToInt(value), options, out_stream);
|
|
}
|
|
};
|
|
|
|
pub const DiagnosticRelatedInformation = struct {
|
|
location: Location,
|
|
message: string,
|
|
};
|
|
|
|
pub const Diagnostic = struct {
|
|
range: Range,
|
|
severity: ?DiagnosticSeverity,
|
|
code: ?string,
|
|
source: ?string,
|
|
message: string,
|
|
relatedInformation: ?[]DiagnosticRelatedInformation = null,
|
|
};
|
|
|
|
pub const WorkspaceEdit = struct {
|
|
changes: std.StringHashMapUnmanaged(std.ArrayListUnmanaged(TextEdit)),
|
|
|
|
pub fn jsonStringify(self: WorkspaceEdit, options: std.json.StringifyOptions, writer: anytype) @TypeOf(writer).Error!void {
|
|
try writer.writeAll("{\"changes\": {");
|
|
var it = self.changes.iterator();
|
|
var idx: usize = 0;
|
|
while (it.next()) |entry| : (idx += 1) {
|
|
if (idx != 0) try writer.writeAll(", ");
|
|
|
|
try writer.writeByte('"');
|
|
try writer.writeAll(entry.key_ptr.*);
|
|
try writer.writeAll("\":");
|
|
try std.json.stringify(entry.value_ptr.items, options, writer);
|
|
}
|
|
try writer.writeAll("}}");
|
|
}
|
|
};
|
|
|
|
pub const TextEdit = struct {
|
|
range: Range,
|
|
newText: string,
|
|
};
|
|
|
|
pub const MarkupContent = struct {
|
|
pub const Kind = enum(u1) {
|
|
PlainText = 0,
|
|
Markdown = 1,
|
|
|
|
pub fn jsonStringify(value: Kind, options: std.json.StringifyOptions, out_stream: anytype) !void {
|
|
const str = switch (value) {
|
|
.PlainText => "plaintext",
|
|
.Markdown => "markdown",
|
|
};
|
|
try std.json.stringify(str, options, out_stream);
|
|
}
|
|
};
|
|
|
|
kind: Kind = .Markdown,
|
|
value: string,
|
|
};
|
|
|
|
pub const CompletionList = struct {
|
|
isIncomplete: bool,
|
|
items: []const CompletionItem,
|
|
};
|
|
|
|
pub const InsertTextFormat = enum(i64) {
|
|
PlainText = 1,
|
|
Snippet = 2,
|
|
|
|
pub fn jsonStringify(value: InsertTextFormat, options: std.json.StringifyOptions, out_stream: anytype) !void {
|
|
try std.json.stringify(@enumToInt(value), options, out_stream);
|
|
}
|
|
};
|
|
|
|
pub const Hover = struct {
|
|
contents: MarkupContent,
|
|
};
|
|
|
|
pub const SemanticTokens = struct {
|
|
data: []const u32,
|
|
};
|
|
|
|
pub const CompletionItem = struct {
|
|
pub const Kind = enum(i64) {
|
|
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,
|
|
|
|
pub fn jsonStringify(value: Kind, options: std.json.StringifyOptions, out_stream: anytype) !void {
|
|
try std.json.stringify(@enumToInt(value), options, out_stream);
|
|
}
|
|
};
|
|
|
|
label: string,
|
|
labelDetails: ?CompletionItemLabelDetails = null,
|
|
kind: Kind,
|
|
detail: ?string = null,
|
|
|
|
sortText: ?string = null,
|
|
filterText: ?string = null,
|
|
insertText: ?string = null,
|
|
|
|
insertTextFormat: ?InsertTextFormat = .PlainText,
|
|
documentation: ?MarkupContent = null,
|
|
|
|
// FIXME: i commented this out, because otherwise the vscode client complains about *ranges*
|
|
// and breaks code completion entirely
|
|
// see: https://github.com/zigtools/zls-vscode/pull/33
|
|
// textEdit: ?TextEdit = null,
|
|
};
|
|
|
|
pub const CompletionItemLabelDetails = struct {
|
|
detail: ?string,
|
|
description: ?string,
|
|
sortText: ?string = null,
|
|
};
|
|
|
|
pub const DocumentSymbol = struct {
|
|
const Kind = enum(u32) {
|
|
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,
|
|
|
|
pub fn jsonStringify(value: Kind, options: std.json.StringifyOptions, out_stream: anytype) !void {
|
|
try std.json.stringify(@enumToInt(value), options, out_stream);
|
|
}
|
|
};
|
|
|
|
name: string,
|
|
detail: ?string = null,
|
|
kind: Kind,
|
|
deprecated: bool = false,
|
|
range: Range,
|
|
selectionRange: Range,
|
|
children: []const DocumentSymbol = &[_]DocumentSymbol{},
|
|
};
|
|
|
|
pub const WorkspaceFolder = struct {
|
|
uri: string,
|
|
name: string,
|
|
};
|
|
|
|
pub const SignatureInformation = struct {
|
|
pub const ParameterInformation = struct {
|
|
// TODO Can also send a pair of encoded offsets
|
|
label: string,
|
|
documentation: ?MarkupContent,
|
|
};
|
|
|
|
label: string,
|
|
documentation: ?MarkupContent,
|
|
parameters: ?[]const ParameterInformation,
|
|
activeParameter: ?u32,
|
|
};
|
|
|
|
pub const SignatureHelp = struct {
|
|
signatures: ?[]const SignatureInformation,
|
|
activeSignature: ?u32,
|
|
activeParameter: ?u32,
|
|
};
|
|
|
|
pub const InlayHint = struct {
|
|
position: Position,
|
|
label: string,
|
|
kind: InlayHintKind,
|
|
tooltip: MarkupContent,
|
|
paddingLeft: bool,
|
|
paddingRight: bool,
|
|
|
|
// appends a colon to the label and reduces the output size
|
|
pub fn jsonStringify(value: InlayHint, options: std.json.StringifyOptions, writer: anytype) @TypeOf(writer).Error!void {
|
|
try writer.writeAll("{\"position\":");
|
|
try std.json.stringify(value.position, options, writer);
|
|
try writer.writeAll(",\"label\":\"");
|
|
try writer.writeAll(value.label);
|
|
try writer.writeAll(":\",\"kind\":");
|
|
try std.json.stringify(value.kind, options, writer);
|
|
if (value.tooltip.value.len != 0) {
|
|
try writer.writeAll(",\"tooltip\":");
|
|
try std.json.stringify(value.tooltip, options, writer);
|
|
}
|
|
if (value.paddingLeft) try writer.writeAll(",\"paddingLeft\":true");
|
|
if (value.paddingRight) try writer.writeAll(",\"paddingRight\":true");
|
|
try writer.writeByte('}');
|
|
}
|
|
};
|
|
|
|
pub const InlayHintKind = enum(i64) {
|
|
Type = 1,
|
|
Parameter = 2,
|
|
|
|
pub fn jsonStringify(value: InlayHintKind, options: std.json.StringifyOptions, out_stream: anytype) !void {
|
|
try std.json.stringify(@enumToInt(value), options, out_stream);
|
|
}
|
|
};
|
|
|
|
pub const CodeActionKind = enum {
|
|
Empty,
|
|
QuickFix,
|
|
Refactor,
|
|
RefactorExtract,
|
|
RefactorInline,
|
|
RefactorRewrite,
|
|
Source,
|
|
SourceOrganizeImports,
|
|
SourceFixAll,
|
|
|
|
pub fn jsonStringify(value: CodeActionKind, options: std.json.StringifyOptions, out_stream: anytype) !void {
|
|
const name = switch (value) {
|
|
.Empty => "",
|
|
.QuickFix => "quickfix",
|
|
.Refactor => "refactor",
|
|
.RefactorExtract => "refactor.extract",
|
|
.RefactorInline => "refactor.inline",
|
|
.RefactorRewrite => "refactor.rewrite",
|
|
.Source => "source",
|
|
.SourceOrganizeImports => "source.organizeImports",
|
|
.SourceFixAll => "source.fixAll",
|
|
};
|
|
try std.json.stringify(name, options, out_stream);
|
|
}
|
|
};
|
|
|
|
pub const CodeAction = struct {
|
|
title: string,
|
|
kind: CodeActionKind,
|
|
// diagnostics: []Diagnostic,
|
|
isPreferred: bool,
|
|
edit: WorkspaceEdit,
|
|
};
|
|
|
|
pub const ApplyWorkspaceEditParams = struct {
|
|
label: string,
|
|
edit: WorkspaceEdit,
|
|
};
|
|
|
|
pub const PositionEncodingKind = enum {
|
|
utf8,
|
|
utf16,
|
|
utf32,
|
|
|
|
pub fn jsonStringify(value: PositionEncodingKind, options: std.json.StringifyOptions, out_stream: anytype) !void {
|
|
const str = switch (value) {
|
|
.utf8 => "utf-8",
|
|
.utf16 => "utf-16",
|
|
.utf32 => "utf-32",
|
|
};
|
|
try std.json.stringify(str, options, out_stream);
|
|
}
|
|
};
|
|
|
|
const TextDocumentSyncKind = enum(u32) {
|
|
None = 0,
|
|
Full = 1,
|
|
Incremental = 2,
|
|
|
|
pub fn jsonStringify(value: @This(), options: std.json.StringifyOptions, out_stream: anytype) !void {
|
|
try std.json.stringify(@enumToInt(value), options, out_stream);
|
|
}
|
|
};
|
|
|
|
// Only includes options we set in our initialize result.
|
|
const InitializeResult = struct {
|
|
capabilities: struct {
|
|
positionEncoding: PositionEncodingKind,
|
|
signatureHelpProvider: struct {
|
|
triggerCharacters: []const string,
|
|
retriggerCharacters: []const string,
|
|
},
|
|
textDocumentSync: struct {
|
|
openClose: bool,
|
|
change: TextDocumentSyncKind,
|
|
save: bool,
|
|
},
|
|
renameProvider: bool,
|
|
completionProvider: struct {
|
|
resolveProvider: bool,
|
|
triggerCharacters: []const string,
|
|
completionItem: struct { labelDetailsSupport: bool },
|
|
},
|
|
documentHighlightProvider: bool,
|
|
hoverProvider: bool,
|
|
codeActionProvider: bool,
|
|
declarationProvider: bool,
|
|
definitionProvider: bool,
|
|
typeDefinitionProvider: bool,
|
|
implementationProvider: bool,
|
|
referencesProvider: bool,
|
|
documentSymbolProvider: bool,
|
|
colorProvider: bool,
|
|
documentFormattingProvider: bool,
|
|
documentRangeFormattingProvider: bool,
|
|
foldingRangeProvider: bool,
|
|
selectionRangeProvider: bool,
|
|
workspaceSymbolProvider: bool,
|
|
rangeProvider: bool,
|
|
documentProvider: bool,
|
|
workspace: ?struct {
|
|
workspaceFolders: ?struct {
|
|
supported: bool,
|
|
changeNotifications: bool,
|
|
},
|
|
},
|
|
semanticTokensProvider: struct {
|
|
full: bool,
|
|
range: bool,
|
|
legend: struct {
|
|
tokenTypes: []const string,
|
|
tokenModifiers: []const string,
|
|
},
|
|
},
|
|
inlayHintProvider: bool,
|
|
},
|
|
serverInfo: struct {
|
|
name: string,
|
|
version: ?string = null,
|
|
},
|
|
};
|
|
|
|
pub const ConfigurationParams = struct {
|
|
items: []const ConfigurationItem,
|
|
|
|
pub const ConfigurationItem = struct {
|
|
section: ?[]const u8,
|
|
};
|
|
};
|
|
|
|
pub const RegistrationParams = struct {
|
|
registrations: []const Registration,
|
|
|
|
pub const Registration = struct {
|
|
id: string,
|
|
method: string,
|
|
|
|
// registerOptions?: LSPAny;
|
|
};
|
|
};
|
|
|
|
pub const DocumentHighlightKind = enum(u8) {
|
|
Text = 1,
|
|
Read = 2,
|
|
Write = 3,
|
|
|
|
pub fn jsonStringify(value: DocumentHighlightKind, options: std.json.StringifyOptions, out_stream: anytype) !void {
|
|
try std.json.stringify(@enumToInt(value), options, out_stream);
|
|
}
|
|
};
|
|
|
|
pub const DocumentHighlight = struct {
|
|
range: Range,
|
|
kind: ?DocumentHighlightKind,
|
|
};
|
|
|
|
pub const FoldingRange = struct {
|
|
startLine: usize,
|
|
endLine: usize,
|
|
};
|