Cleaned up LSP types, add InitializeResult, no longer use a hardcoded string

This commit is contained in:
Alexandros Naskos 2020-11-06 10:08:20 +02:00
parent 996deb45fe
commit f7eff6632e
No known key found for this signature in database
GPG Key ID: 02BF2E72B0EA32D2
6 changed files with 307 additions and 230 deletions

View File

@ -29,7 +29,7 @@ pub fn getDocComments(
allocator: *std.mem.Allocator, allocator: *std.mem.Allocator,
tree: *ast.Tree, tree: *ast.Tree,
node: *ast.Node, node: *ast.Node,
format: types.MarkupKind, format: types.MarkupContent.Kind,
) !?[]const u8 { ) !?[]const u8 {
if (getDocCommentNode(tree, node)) |doc_comment_node| { if (getDocCommentNode(tree, node)) |doc_comment_node| {
return try collectDocComments(allocator, tree, doc_comment_node, format); return try collectDocComments(allocator, tree, doc_comment_node, format);
@ -41,7 +41,7 @@ pub fn collectDocComments(
allocator: *std.mem.Allocator, allocator: *std.mem.Allocator,
tree: *ast.Tree, tree: *ast.Tree,
doc_comments: *ast.Node.DocComment, doc_comments: *ast.Node.DocComment,
format: types.MarkupKind, format: types.MarkupContent.Kind,
) ![]const u8 { ) ![]const u8 {
var lines = std.ArrayList([]const u8).init(allocator); var lines = std.ArrayList([]const u8).init(allocator);
defer lines.deinit(); defer lines.deinit();

View File

@ -12,6 +12,7 @@ const URI = @import("uri.zig");
const references = @import("references.zig"); const references = @import("references.zig");
const rename = @import("rename.zig"); const rename = @import("rename.zig");
const offsets = @import("offsets.zig"); const offsets = @import("offsets.zig");
const semantic_tokens = @import("semantic_tokens.zig");
const logger = std.log.scoped(.main); const logger = std.log.scoped(.main);
@ -50,8 +51,8 @@ pub fn log(
}; };
send(&arena, types.Notification{ send(&arena, types.Notification{
.method = "window/showMessage", .method = "window/showMessage",
.params = types.NotificationParams{ .params = types.Notification.Params{
.ShowMessageParams = .{ .ShowMessage = .{
.type = message_type, .type = message_type,
.message = message, .message = message,
}, },
@ -67,8 +68,8 @@ pub fn log(
send(&arena, types.Notification{ send(&arena, types.Notification{
.method = "window/logMessage", .method = "window/logMessage",
.params = types.NotificationParams{ .params = types.Notification.Params{
.LogMessageParams = .{ .LogMessage = .{
.type = message_type, .type = message_type,
.message = message, .message = message,
}, },
@ -97,12 +98,6 @@ const ClientCapabilities = struct {
var client_capabilities = ClientCapabilities{}; var client_capabilities = ClientCapabilities{};
var offset_encoding = offsets.Encoding.utf16; var offset_encoding = offsets.Encoding.utf16;
const initialize_capabilities =
\\"capabilities": {"signatureHelpProvider": {"triggerCharacters": ["(",","]},"textDocumentSync": 1,"renameProvider":true,"completionProvider": {"resolveProvider": false,"triggerCharacters": [".",":","@"]},"documentHighlightProvider": false,"hoverProvider": true,"codeActionProvider": false,"declarationProvider": true,"definitionProvider": true,"typeDefinitionProvider": true,"implementationProvider": false,"referencesProvider": true,"documentSymbolProvider": true,"colorProvider": false,"documentFormattingProvider": true,"documentRangeFormattingProvider": false,"foldingRangeProvider": false,"selectionRangeProvider": false,"workspaceSymbolProvider": false,"rangeProvider": false,"documentProvider": true,"workspace": {"workspaceFolders": {"supported": true,"changeNotifications": true}},"semanticTokensProvider": {"documentProvider": true,"legend": {"tokenTypes": ["namespace","type","struct","enum","union","opaque","parameter","variable","tagField","field","errorTag","function","keyword","comment","string","number","operator","builtin","label","keywordLiteral"],"tokenModifiers": ["definition","async","documentation", "generic"]}}}}}
;
const initialize_response = ",\"result\": {" ++ initialize_capabilities;
const not_implemented_response = const not_implemented_response =
\\,"error":{"code":-32601,"message":"NotImplemented"}} \\,"error":{"code":-32601,"message":"NotImplemented"}}
; ;
@ -259,7 +254,7 @@ fn publishDiagnostics(arena: *std.heap.ArenaAllocator, handle: DocumentStore.Han
try send(arena, types.Notification{ try send(arena, types.Notification{
.method = "textDocument/publishDiagnostics", .method = "textDocument/publishDiagnostics",
.params = .{ .params = .{
.PublishDiagnosticsParams = .{ .PublishDiagnostics = .{
.uri = handle.uri(), .uri = handle.uri(),
.diagnostics = diagnostics.items, .diagnostics = diagnostics.items,
}, },
@ -331,7 +326,11 @@ fn nodeToCompletion(
const node = node_handle.node; const node = node_handle.node;
const handle = node_handle.handle; const handle = node_handle.handle;
const doc_kind: types.MarkupKind = if (client_capabilities.completion_doc_supports_md) .Markdown else .PlainText; const doc_kind: types.MarkupContent.Kind = if (client_capabilities.completion_doc_supports_md)
.Markdown
else
.PlainText;
const doc = if (try analysis.getDocComments( const doc = if (try analysis.getDocComments(
list.allocator, list.allocator,
handle.tree, handle.tree,
@ -563,7 +562,7 @@ fn gotoDefinitionSymbol(id: types.RequestId, arena: *std.heap.ArenaAllocator, de
fn hoverSymbol(id: types.RequestId, arena: *std.heap.ArenaAllocator, decl_handle: analysis.DeclWithHandle) (std.os.WriteError || error{OutOfMemory})!void { fn hoverSymbol(id: types.RequestId, arena: *std.heap.ArenaAllocator, decl_handle: analysis.DeclWithHandle) (std.os.WriteError || error{OutOfMemory})!void {
const handle = decl_handle.handle; const handle = decl_handle.handle;
const hover_kind: types.MarkupKind = if (client_capabilities.hover_supports_md) .Markdown else .PlainText; const hover_kind: types.MarkupContent.Kind = if (client_capabilities.hover_supports_md) .Markdown else .PlainText;
const md_string = switch (decl_handle.decl.*) { const md_string = switch (decl_handle.decl.*) {
.ast_node => |node| ast_node: { .ast_node => |node| ast_node: {
if (try analysis.resolveVarDeclAlias(&document_store, arena, .{ .node = node, .handle = handle })) |result| { if (try analysis.resolveVarDeclAlias(&document_store, arena, .{ .node = node, .handle = handle })) |result| {
@ -866,7 +865,7 @@ fn declToCompletion(context: DeclToCompletionContext, decl_handle: analysis.Decl
switch (decl_handle.decl.*) { switch (decl_handle.decl.*) {
.ast_node => |node| try nodeToCompletion(context.arena, context.completions, .{ .node = node, .handle = decl_handle.handle }, null, context.orig_handle, false, context.config.*), .ast_node => |node| try nodeToCompletion(context.arena, context.completions, .{ .node = node, .handle = decl_handle.handle }, null, context.orig_handle, false, context.config.*),
.param_decl => |param| { .param_decl => |param| {
const doc_kind: types.MarkupKind = if (client_capabilities.completion_doc_supports_md) .Markdown else .PlainText; const doc_kind: types.MarkupContent.Kind = if (client_capabilities.completion_doc_supports_md) .Markdown else .PlainText;
const doc = if (param.doc_comments) |doc_comments| const doc = if (param.doc_comments) |doc_comments|
types.MarkupContent{ types.MarkupContent{
.kind = doc_kind, .kind = doc_kind,
@ -1073,7 +1072,6 @@ fn configFromUriOr(uri: []const u8, default: Config) Config {
} }
fn initializeHandler(arena: *std.heap.ArenaAllocator, id: types.RequestId, req: requests.Initialize, config: Config) !void { fn initializeHandler(arena: *std.heap.ArenaAllocator, id: types.RequestId, req: requests.Initialize, config: Config) !void {
var send_encoding = req.params.capabilities.offsetEncoding.value.len != 0;
for (req.params.capabilities.offsetEncoding.value) |encoding| { for (req.params.capabilities.offsetEncoding.value) |encoding| {
if (std.mem.eql(u8, encoding, "utf-8")) { if (std.mem.eql(u8, encoding, "utf-8")) {
offset_encoding = .utf8; offset_encoding = .utf8;
@ -1117,15 +1115,77 @@ fn initializeHandler(arena: *std.heap.ArenaAllocator, id: types.RequestId, req:
try loadWorkspaceConfigs(); try loadWorkspaceConfigs();
} }
if (!send_encoding) { try send(arena, types.Response{
try respondGeneric(id, initialize_response); .id = id,
} else { .result = .{
const response_str = try std.fmt.allocPrint(&arena.allocator, ",\"result\": {{\"offsetEncoding\":\"{}\",{}", .{ .InitializeResult = .{
if (offset_encoding == .utf8) @as([]const u8, "utf-8") else @as([]const u8, "utf-16"), .offsetEncoding = if (offset_encoding == .utf8)
initialize_capabilities, @as([]const u8, "utf-8")
}); else
try respondGeneric(id, response_str); "utf-16",
.serverInfo = .{
.name = "zls",
.version = "0.1.0",
},
.capabilities = .{
.signatureHelpProvider = .{
.triggerCharacters = &[_][]const u8{ "(", "," },
},
.textDocumentSync = .Full,
.renameProvider = true,
.completionProvider = .{
.resolveProvider = false,
.triggerCharacters = &[_][]const u8{ ".", ":", "@" },
},
.documentHighlightProvider = false,
.hoverProvider = true,
.codeActionProvider = false,
.declarationProvider = true,
.definitionProvider = true,
.typeDefinitionProvider = true,
.implementationProvider = false,
.referencesProvider = true,
.documentSymbolProvider = true,
.colorProvider = false,
.documentFormattingProvider = true,
.documentRangeFormattingProvider = false,
.foldingRangeProvider = false,
.selectionRangeProvider = false,
.workspaceSymbolProvider = false,
.rangeProvider = false,
.documentProvider = true,
.workspace = .{
.workspaceFolders = .{
.supported = true,
.changeNotifications = true,
},
},
.semanticTokensProvider = .{
.documentProvider = true,
.legend = .{
.tokenTypes = comptime block: {
const tokTypeFields = std.meta.fields(semantic_tokens.TokenType);
var names: [tokTypeFields.len][]const u8 = undefined;
for (tokTypeFields) |field, i| {
names[i] = field.name;
} }
break :block &names;
},
.tokenModifiers = comptime block: {
const tokModFields = std.meta.fields(semantic_tokens.TokenModifiers);
var names: [tokModFields.len][]const u8 = undefined;
for (tokModFields) |field, i| {
names[i] = field.name;
}
break :block &names;
},
},
},
},
},
},
});
logger.notice("zls initialized", .{}); logger.notice("zls initialized", .{});
logger.info("{}\n", .{client_capabilities}); logger.info("{}\n", .{client_capabilities});
logger.notice("Using offset encoding: {}\n", .{std.meta.tagName(offset_encoding)}); logger.notice("Using offset encoding: {}\n", .{std.meta.tagName(offset_encoding)});
@ -1201,7 +1261,6 @@ fn semanticTokensFullHandler(arena: *std.heap.ArenaAllocator, id: types.RequestI
return try respondGeneric(id, no_semantic_tokens_response); return try respondGeneric(id, no_semantic_tokens_response);
}; };
const semantic_tokens = @import("semantic_tokens.zig");
const token_array = try semantic_tokens.writeAllSemanticTokens(arena, &document_store, handle, offset_encoding); const token_array = try semantic_tokens.writeAllSemanticTokens(arena, &document_store, handle, offset_encoding);
defer allocator.free(token_array); defer allocator.free(token_array);

View File

@ -19,12 +19,12 @@ fn tokenReference(
.uri = handle.uri(), .uri = handle.uri(),
.range = .{ .range = .{
.start = .{ .start = .{
.line = @intCast(types.Integer, loc.line), .line = @intCast(i64, loc.line),
.character = @intCast(types.Integer, loc.column), .character = @intCast(i64, loc.column),
}, },
.end = .{ .end = .{
.line = @intCast(types.Integer, loc.line), .line = @intCast(i64, loc.line),
.character = @intCast(types.Integer, loc.column + offsets.tokenLength(handle.tree, tok, encoding)), .character = @intCast(i64, loc.column + offsets.tokenLength(handle.tree, tok, encoding)),
}, },
}, },
}); });

View File

@ -121,7 +121,7 @@ pub fn fromDynamicTree(arena: *std.heap.ArenaAllocator, comptime T: type, value:
//! Note that the parameter types may be incomplete. //! Note that the parameter types may be incomplete.
//! We only define what we actually use. //! We only define what we actually use.
const MaybeStringArray = Default([]const types.String, &[0]types.String{}); const MaybeStringArray = Default([]const []const u8, &[0][]const u8{});
pub const Initialize = struct { pub const Initialize = struct {
pub const ClientCapabilities = struct { pub const ClientCapabilities = struct {
@ -161,14 +161,14 @@ pub const WorkspaceFoldersChange = struct {
pub const OpenDocument = struct { pub const OpenDocument = struct {
params: struct { params: struct {
textDocument: struct { textDocument: struct {
uri: types.String, uri: []const u8,
text: types.String, text: []const u8,
}, },
}, },
}; };
const TextDocumentIdentifier = struct { const TextDocumentIdentifier = struct {
uri: types.String, uri: []const u8,
}; };
pub const ChangeDocument = struct { pub const ChangeDocument = struct {
@ -205,7 +205,7 @@ pub const Rename = struct {
params: struct { params: struct {
textDocument: TextDocumentIdentifier, textDocument: TextDocumentIdentifier,
position: types.Position, position: types.Position,
newName: types.String, newName: []const u8,
}, },
}; };

View File

@ -4,7 +4,7 @@ const DocumentStore = @import("document_store.zig");
const analysis = @import("analysis.zig"); const analysis = @import("analysis.zig");
const ast = std.zig.ast; const ast = std.zig.ast;
const TokenType = enum(u32) { pub const TokenType = enum(u32) {
namespace, namespace,
type, type,
@"struct", @"struct",
@ -27,7 +27,7 @@ const TokenType = enum(u32) {
keywordLiteral, keywordLiteral,
}; };
const TokenModifiers = packed struct { pub const TokenModifiers = packed struct {
definition: bool = false, definition: bool = false,
@"async": bool = false, @"async": bool = false,
documentation: bool = false, documentation: bool = false,
@ -275,7 +275,12 @@ fn writeNodeTokens(builder: *Builder, arena: *std.heap.ArenaAllocator, store: *D
try await @asyncCall(child_frame, {}, writeNodeTokens, .{ builder, arena, store, child }); try await @asyncCall(child_frame, {}, writeNodeTokens, .{ builder, arena, store, child });
} }
} }
if (node.tag == .Root) {
try gap_highlighter.end(handle.tree.token_ids.len - 1);
} else {
try gap_highlighter.end(node.lastToken()); try gap_highlighter.end(node.lastToken());
}
}, },
.VarDecl => { .VarDecl => {
const var_decl = node.cast(ast.Node.VarDecl).?; const var_decl = node.cast(ast.Node.VarDecl).?;
@ -734,11 +739,11 @@ fn writeNodeTokens(builder: *Builder, arena: *std.heap.ArenaAllocator, store: *D
const pointer_type = node.castTag(.PtrType).?; const pointer_type = node.castTag(.PtrType).?;
const tok_ids = builder.handle.tree.token_ids; const tok_ids = builder.handle.tree.token_ids;
const ptr_info = switch(tok_ids[pointer_type.op_token]) { const ptr_info = switch (tok_ids[pointer_type.op_token]) {
.AsteriskAsterisk => pointer_type.rhs.castTag(.PtrType).?.ptr_info, .AsteriskAsterisk => pointer_type.rhs.castTag(.PtrType).?.ptr_info,
else => pointer_type.ptr_info, else => pointer_type.ptr_info,
}; };
const rhs = switch(tok_ids[pointer_type.op_token]) { const rhs = switch (tok_ids[pointer_type.op_token]) {
.AsteriskAsterisk => pointer_type.rhs.castTag(.PtrType).?.rhs, .AsteriskAsterisk => pointer_type.rhs.castTag(.PtrType).?.rhs,
else => pointer_type.rhs, else => pointer_type.rhs,
}; };

View File

@ -1,25 +1,10 @@
// Collection of JSONRPC and LSP structs, enums, and unions
const std = @import("std"); const std = @import("std");
// LSP types
const json = std.json; const json = std.json;
// JSON Types
pub const String = []const u8;
pub const Integer = i64;
pub const Float = f64;
pub const Bool = bool;
pub const Array = json.Array;
pub const Object = json.ObjectMap;
// pub const Any = @TypeOf(var);
// Basic structures
pub const DocumentUri = String;
pub const Position = struct { pub const Position = struct {
line: Integer, line: i64,
character: Integer, character: i64,
}; };
pub const Range = struct { pub const Range = struct {
@ -28,21 +13,15 @@ pub const Range = struct {
}; };
pub const Location = struct { pub const Location = struct {
uri: DocumentUri, range: Range uri: []const u8,
range: Range,
}; };
/// Id of a request /// Id of a request
pub const RequestId = union(enum) { pub const RequestId = union(enum) {
String: String, String: []const u8,
Integer: Integer, Integer: i64,
Float: Float, Float: f64,
};
/// Params of a request
pub const RequestParams = void;
pub const NotificationParams = union(enum) {
LogMessageParams: LogMessageParams, PublishDiagnosticsParams: PublishDiagnosticsParams, ShowMessageParams: ShowMessageParams
}; };
/// Hover response /// Hover response
@ -60,35 +39,40 @@ pub const ResponseParams = union(enum) {
TextEdits: []TextEdit, TextEdits: []TextEdit,
Locations: []Location, Locations: []Location,
WorkspaceEdit: WorkspaceEdit, WorkspaceEdit: WorkspaceEdit,
}; InitializeResult: InitializeResult,
/// JSONRPC error
pub const Error = struct {
code: Integer,
message: String,
data: String,
};
/// JSONRPC request
pub const Request = struct {
jsonrpc: String = "2.0", method: String, id: ?RequestId = RequestId{ .Integer = 0 }, params: RequestParams
}; };
/// JSONRPC notifications /// JSONRPC notifications
pub const Notification = struct { pub const Notification = struct {
jsonrpc: String = "2.0", method: String, params: NotificationParams pub const Params = union(enum) {
LogMessage: struct {
type: MessageType,
message: []const u8,
},
PublishDiagnostics: struct {
uri: []const u8,
diagnostics: []Diagnostic,
},
ShowMessage: struct {
type: MessageType,
message: []const u8,
},
};
jsonrpc: []const u8 = "2.0",
method: []const u8,
params: Params,
}; };
/// JSONRPC response /// JSONRPC response
pub const Response = struct { pub const Response = struct {
jsonrpc: String = "2.0", jsonrpc: []const u8 = "2.0",
// @"error": ?Error = null,
id: RequestId, id: RequestId,
result: ResponseParams, result: ResponseParams,
}; };
/// Type of a debug message /// Type of a debug message
pub const MessageType = enum(Integer) { pub const MessageType = enum(i64) {
Error = 1, Error = 1,
Warning = 2, Warning = 2,
Info = 3, Info = 3,
@ -103,12 +87,7 @@ pub const MessageType = enum(Integer) {
} }
}; };
/// Params for a LogMessage Notification (window/logMessage) pub const DiagnosticSeverity = enum(i64) {
pub const LogMessageParams = struct {
type: MessageType, message: String
};
pub const DiagnosticSeverity = enum(Integer) {
Error = 1, Error = 1,
Warning = 2, Warning = 2,
Information = 3, Information = 3,
@ -126,19 +105,15 @@ pub const DiagnosticSeverity = enum(Integer) {
pub const Diagnostic = struct { pub const Diagnostic = struct {
range: Range, range: Range,
severity: DiagnosticSeverity, severity: DiagnosticSeverity,
code: String, code: []const u8,
source: String, source: []const u8,
message: String, message: []const u8,
};
pub const PublishDiagnosticsParams = struct {
uri: DocumentUri, diagnostics: []Diagnostic
}; };
pub const TextDocument = struct { pub const TextDocument = struct {
uri: DocumentUri, uri: []const u8,
// This is a substring of mem starting at 0 // This is a substring of mem starting at 0
text: String, text: []const u8,
// This holds the memory that we have actually allocated. // This holds the memory that we have actually allocated.
mem: []u8, mem: []u8,
}; };
@ -172,15 +147,16 @@ pub const WorkspaceEdit = struct {
pub const TextEdit = struct { pub const TextEdit = struct {
range: Range, range: Range,
newText: String, newText: []const u8,
}; };
pub const MarkupKind = enum(u1) { pub const MarkupContent = struct {
PlainText = 0, // plaintext pub const Kind = enum(u1) {
Markdown = 1, // markdown PlainText = 0,
Markdown = 1,
pub fn jsonStringify( pub fn jsonStringify(
value: MarkupKind, value: Kind,
options: json.StringifyOptions, options: json.StringifyOptions,
out_stream: anytype, out_stream: anytype,
) !void { ) !void {
@ -190,37 +166,32 @@ pub const MarkupKind = enum(u1) {
}; };
try json.stringify(str, options, out_stream); try json.stringify(str, options, out_stream);
} }
};
kind: Kind = .Markdown,
value: []const u8,
}; };
pub const MarkupContent = struct {
kind: MarkupKind = MarkupKind.Markdown,
value: String,
};
// pub const TextDocumentIdentifier = struct {
// uri: DocumentUri,
// };
// pub const CompletionTriggerKind = enum(Integer) {
// Invoked = 1,
// TriggerCharacter = 2,
// TriggerForIncompleteCompletions = 3,
// pub fn jsonStringify(
// value: CompletionTriggerKind,
// options: json.StringifyOptions,
// out_stream: var,
// ) !void {
// try json.stringify(@enumToInt(value), options, out_stream);
// }
// };
pub const CompletionList = struct { pub const CompletionList = struct {
isIncomplete: Bool, isIncomplete: bool,
items: []const CompletionItem, items: []const CompletionItem,
}; };
pub const CompletionItemKind = enum(Integer) { pub const InsertTextFormat = enum(i64) {
PlainText = 1,
Snippet = 2,
pub fn jsonStringify(
value: InsertTextFormat,
options: json.StringifyOptions,
out_stream: anytype,
) !void {
try json.stringify(@enumToInt(value), options, out_stream);
}
};
pub const CompletionItem = struct {
const Kind = enum(i64) {
Text = 1, Text = 1,
Method = 2, Method = 2,
Function = 3, Function = 3,
@ -248,40 +219,26 @@ pub const CompletionItemKind = enum(Integer) {
TypeParameter = 25, TypeParameter = 25,
pub fn jsonStringify( pub fn jsonStringify(
value: CompletionItemKind, value: Kind,
options: json.StringifyOptions, options: json.StringifyOptions,
out_stream: anytype, out_stream: anytype,
) !void { ) !void {
try json.stringify(@enumToInt(value), options, out_stream); try json.stringify(@enumToInt(value), options, out_stream);
} }
}; };
pub const InsertTextFormat = enum(Integer) { label: []const u8,
PlainText = 1, kind: Kind,
Snippet = 2,
pub fn jsonStringify(
value: InsertTextFormat,
options: json.StringifyOptions,
out_stream: anytype,
) !void {
try json.stringify(@enumToInt(value), options, out_stream);
}
};
pub const CompletionItem = struct {
label: String,
kind: CompletionItemKind,
textEdit: ?TextEdit = null, textEdit: ?TextEdit = null,
filterText: ?String = null, filterText: ?[]const u8 = null,
insertText: ?String = null, insertText: ?[]const u8 = null,
insertTextFormat: ?InsertTextFormat = InsertTextFormat.PlainText, insertTextFormat: ?InsertTextFormat = .PlainText,
detail: ?String = null, detail: ?[]const u8 = null,
documentation: ?MarkupContent = null, documentation: ?MarkupContent = null,
// filterText: String = .NotDefined,
}; };
const SymbolKind = enum { pub const DocumentSymbol = struct {
const Kind = enum {
File = 1, File = 1,
Module = 2, Module = 2,
Namespace = 3, Namespace = 3,
@ -310,30 +267,86 @@ const SymbolKind = enum {
TypeParameter = 26, TypeParameter = 26,
pub fn jsonStringify( pub fn jsonStringify(
value: SymbolKind, value: Kind,
options: json.StringifyOptions, options: json.StringifyOptions,
out_stream: anytype, out_stream: anytype,
) !void { ) !void {
try json.stringify(@enumToInt(value), options, out_stream); try json.stringify(@enumToInt(value), options, out_stream);
} }
}; };
pub const DocumentSymbol = struct { name: []const u8,
name: String, detail: ?[]const u8 = null,
detail: ?String = null, kind: Kind,
kind: SymbolKind,
deprecated: bool = false, deprecated: bool = false,
range: Range, range: Range,
selectionRange: Range, selectionRange: Range,
children: []const DocumentSymbol = &[_]DocumentSymbol{}, children: []const DocumentSymbol = &[_]DocumentSymbol{},
}; };
pub const ShowMessageParams = struct { pub const WorkspaceFolder = struct {
type: MessageType, uri: []const u8,
message: String, name: []const u8,
}; };
pub const WorkspaceFolder = struct { // Only includes options we set in our initialize result.
uri: DocumentUri, const InitializeResult = struct {
name: String, capabilities: struct {
signatureHelpProvider: struct {
triggerCharacters: []const []const u8,
},
textDocumentSync: enum {
None = 0,
Full = 1,
Incremental = 2,
pub fn jsonStringify(
value: @This(),
options: json.StringifyOptions,
out_stream: anytype,
) !void {
try json.stringify(@enumToInt(value), options, out_stream);
}
},
renameProvider: bool,
completionProvider: struct {
resolveProvider: bool,
triggerCharacters: []const []const u8,
},
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 {
documentProvider: bool,
legend: struct {
tokenTypes: []const []const u8,
tokenModifiers: []const []const u8,
},
},
},
serverInfo: struct {
name: []const u8,
version: ?[]const u8 = null,
},
offsetEncoding: []const u8,
}; };