Fix server capabilities, add semantic tokens config option, fix semantic tokens basic implementation

This commit is contained in:
Alexandros Naskos 2020-06-16 14:27:00 +03:00
parent bed05b6601
commit fc921f10a4
5 changed files with 28 additions and 18 deletions

View File

@ -52,11 +52,12 @@ The following options are currently available.
| Option | Type | Default value | What it Does |
| --- | --- | --- | --- |
| `enable_snippets` | `bool` | `false` | Enables snippet completion, set to false for compatibility with language clients that do not support snippets (such as ale). |
| `enable_snippets` | `bool` | `false` | Enables snippet completions when the client also supports them. |
| `zig_lib_path` | `?[]const u8` | `null` | zig library path, e.g. `/path/to/zig/lib/zig`, used to analyze std library imports. |
| `zig_exe_path` | `?[]const u8` | `null` | zig executable path, e.g. `/path/to/zig/zig`, used to run the custom build runner. If `null`, zig is looked up in `PATH`. Will be used to infer the zig standard library path if none is provided. |
| `warn_style` | `bool` | `false` | Enables warnings for style *guideline* mismatches |
| `build_runner_path` | `?[]const u8` | `null` | Path to the build_runner.zig file provided by zls. This option must be present in one of the global configuration files to have any effect. `null` is equivalent to `${executable_directory}/build_runner.zig` |
| `enable_semantic_tokens` | `bool` | false | Enables semantic token support when the client also supports it. |
## Usage

View File

@ -17,3 +17,6 @@ warn_style: bool = false,
/// Path to the build_runner.zig file. This option must be present in one of
/// the global configuration directories to have any effect.
build_runner_path: ?[]const u8 = null,
/// Semantic token support
enable_semantic_tokens: bool = false,

View File

@ -28,7 +28,7 @@ const ClientCapabilities = struct {
var client_capabilities = ClientCapabilities{};
const initialize_response =
\\,"result":{"capabilities":{"signatureHelpProvider":{"triggerCharacters":["(",","]},"textDocumentSync":1,"completionProvider":{"resolveProvider":false,"triggerCharacters":[".",":","@"]},"documentHighlightProvider":false,"hoverProvider":true,"codeActionProvider":false,"declarationProvider":true,"definitionProvider":true,"typeDefinitionProvider":true,"implementationProvider":false,"referencesProvider":false,"documentSymbolProvider":true,"colorProvider":false,"documentFormattingProvider":false,"documentRangeFormattingProvider":false,"foldingRangeProvider":false,"selectionRangeProvider":false,"workspaceSymbolProvider":false,"rangeProvider":false,"documentProvider":true},"workspace":{"workspaceFolders":{"supported":true,"changeNotifications":true}},"semanticTokensProvider":{"documentProvider":true, "legend":{"tokenTypes":["type","struct","enum","union","parameter","variable","tagField","field","function","keyword","modifier","comment","string","number","operator","builtin"],"tokenModifiers":["definition","async","documentation"]}}}}
\\,"result": {"capabilities": {"signatureHelpProvider": {"triggerCharacters": ["(",","]},"textDocumentSync": 1,"completionProvider": {"resolveProvider": false,"triggerCharacters": [".",":","@"]},"documentHighlightProvider": false,"hoverProvider": true,"codeActionProvider": false,"declarationProvider": true,"definitionProvider": true,"typeDefinitionProvider": true,"implementationProvider": false,"referencesProvider": false,"documentSymbolProvider": true,"colorProvider": false,"documentFormattingProvider": false,"documentRangeFormattingProvider": false,"foldingRangeProvider": false,"selectionRangeProvider": false,"workspaceSymbolProvider": false,"rangeProvider": false,"documentProvider": true,"workspace": {"workspaceFolders": {"supported": true,"changeNotifications": true}},"semanticTokensProvider": {"documentProvider": true,"legend": {"tokenTypes": ["type","struct","enum","union","parameter","variable","tagField","field","function","keyword","modifier","comment","string","number","operator","builtin"],"tokenModifiers": ["definition","async","documentation"]}}}}}
;
const not_implemented_response =
@ -50,6 +50,9 @@ const edit_not_applied_response =
const no_completions_response =
\\,"result":{"isIncomplete":false,"items":[]}}
;
const no_semantic_tokens_response =
\\,"result":{"data":[]}}
;
/// Sends a request or response
fn send(reqOrRes: var) !void {
@ -997,20 +1000,23 @@ fn processJsonRpc(parser: *std.json.Parser, json: []const u8, config: Config) !v
const document = params.getValue("textDocument").?.Object;
const uri = document.getValue("uri").?.String;
const handle = document_store.getHandle(uri) orelse {
std.debug.warn("Trying to complete in non existent document {}", .{uri});
return try respondGeneric(id, no_completions_response);
};
const this_config = configFromUriOr(uri, config);
if (this_config.enable_semantic_tokens) {
const handle = document_store.getHandle(uri) orelse {
std.debug.warn("Trying to complete in non existent document {}", .{uri});
return try respondGeneric(id, no_semantic_tokens_response);
};
// TODO Actually test this in some editor, VSCode won't send me requests -_-'.
const semantic_tokens = @import("semantic_tokens.zig");
const token_array = try semantic_tokens.writeAllSemanticTokens(allocator, handle.*);
defer allocator.free(token_array);
const semantic_tokens = @import("semantic_tokens.zig");
const token_array = try semantic_tokens.writeAllSemanticTokens(allocator, handle.*);
defer allocator.free(token_array);
return try send(types.Response{
.id = id,
.result = .{ .SemanticTokens = .{ .data = token_array } },
});
return try send(types.Response{
.id = id,
.result = .{ .SemanticTokens = .{ .data = token_array } },
});
} else
return try respondGeneric(id, no_semantic_tokens_response);
}
// Autocomplete / Signatures
else if (std.mem.eql(u8, method, "textDocument/completion")) {

View File

@ -54,15 +54,15 @@ const Builder = struct {
fn add(self: *Builder, token: ast.TokenIndex, token_type: TokenType, token_modifiers: TokenModifiers) !void {
const start_idx = if (self.current_token) |current_token|
self.tree.token_locs[current_token].start + 1
self.tree.token_locs[current_token].start
else
0;
const token_loc = self.tree.token_locs[token];
const delta_loc = self.tree.tokenLocationLoc(start_idx, token_loc);
try self.arr.appendSlice(&[_]u32{
@truncate(u32, if (self.current_token == null) delta_loc.line + 1 else delta_loc.line),
@truncate(u32, delta_loc.column + 1),
@truncate(u32, delta_loc.line),
@truncate(u32, delta_loc.column),
@truncate(u32, token_loc.end - token_loc.start),
@enumToInt(token_type),
token_modifiers.toInt(),

View File

@ -59,7 +59,7 @@ pub const ResponseParams = union(enum) {
Location: Location,
Hover: Hover,
DocumentSymbols: []DocumentSymbol,
SemanticTokens: struct { data: []u32 },
SemanticTokens: struct { data: []const u32 },
};
/// JSONRPC error