Skip to content

Commit

Permalink
make semantic token configuration an enum
Browse files Browse the repository at this point in the history
  • Loading branch information
Vexu committed Mar 17, 2023
1 parent 0aacb76 commit 0af5ed6
Show file tree
Hide file tree
Showing 8 changed files with 111 additions and 22 deletions.
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,7 @@ The following options are currently available.
| `enable_ast_check_diagnostics` | `bool` | `true` | Whether to enable ast-check diagnostics |
| `enable_autofix` | `bool` | `true` | Whether to automatically fix errors on save. Currently supports adding and removing discards. |
| `enable_import_embedfile_argument_completions` | `bool` | `true` | Whether to enable import/embedFile argument completions |
| `enable_semantic_tokens` | `bool` | `true` | Enables semantic token support when the client also supports it |
| `semantic_tokens` | `enum` | `.full` | Set level of semantic tokens. Partial only includes information that requires semantic analysis. |
| `enable_inlay_hints` | `bool` | `true` | Enables inlay hint support when the client also supports it |
| `inlay_hints_show_builtin` | `bool` | `true` | Enable inlay hints for builtin functions |
| `inlay_hints_exclude_single_argument` | `bool` | `true` | Don't show inlay hints for single argument calls |
Expand Down
13 changes: 9 additions & 4 deletions schema.json
Original file line number Diff line number Diff line change
Expand Up @@ -24,10 +24,15 @@
"type": "boolean",
"default": "true"
},
"enable_semantic_tokens": {
"description": "Enables semantic token support when the client also supports it",
"type": "boolean",
"default": "true"
"semantic_tokens": {
"description": "Set level of semantic tokens. Partial only includes information that requires semantic analysis.",
"type": "string",
"enum": [
"none",
"partial",
"full"
],
"default": "full"
},
"enable_inlay_hints": {
"description": "Enables inlay hint support when the client also supports it",
Expand Down
18 changes: 16 additions & 2 deletions src/Config.zig
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,22 @@ enable_autofix: bool = true,
/// Whether to enable import/embedFile argument completions
enable_import_embedfile_argument_completions: bool = true,

/// Enables semantic token support when the client also supports it
enable_semantic_tokens: bool = true,
/// Set level of semantic tokens. Partial only includes information that requires semantic analysis.
semantic_tokens: enum {
none,
partial,
full,

pub fn jsonStringify(
value: @This(),
_: anytype,
writer: anytype,
) @TypeOf(writer).Error!void {
try writer.writeByte('"');
try writer.writeAll(@tagName(value));
try writer.writeByte('"');
}
} = .full,

/// Enables inlay hint support when the client also supports it
enable_inlay_hints: bool = true,
Expand Down
35 changes: 31 additions & 4 deletions src/Server.zig
Original file line number Diff line number Diff line change
Expand Up @@ -2178,6 +2178,19 @@ fn handleConfiguration(server: *Server, json: std.json.Value) error{OutOfMemory}
break :blk @field(server.config, field.name);
},
},
.Enum => switch (value) {
.String => |s| blk: {
const trimmed = std.mem.trim(u8, s, " ");
break :blk std.meta.stringToEnum(field.type, trimmed) orelse inner: {
log.warn("Ignoring new value for \"zls.{s}\": the given new value is invalid", .{field.name});
break :inner @field(server.config, field.name);
};
},
else => blk: {
log.warn("Ignoring new value for \"zls.{s}\": the given new value has an invalid type", .{field.name});
break :blk @field(server.config, field.name);
},
},
else => @compileError("Not implemented for " ++ @typeName(ft)),
},
};
Expand Down Expand Up @@ -2282,23 +2295,37 @@ fn semanticTokensFullHandler(server: *Server, request: types.SemanticTokensParam
const tracy_zone = tracy.trace(@src());
defer tracy_zone.end();

if (!server.config.enable_semantic_tokens) return null;
if (server.config.semantic_tokens == .none) return null;

const handle = server.document_store.getHandle(request.textDocument.uri) orelse return null;

return try semantic_tokens.writeSemanticTokens(server.arena.allocator(), &server.analyser, handle, null, server.offset_encoding);
return try semantic_tokens.writeSemanticTokens(
server.arena.allocator(),
&server.analyser,
handle,
null,
server.offset_encoding,
server.config.semantic_tokens == .partial,
);
}

fn semanticTokensRangeHandler(server: *Server, request: types.SemanticTokensRangeParams) Error!?types.SemanticTokens {
const tracy_zone = tracy.trace(@src());
defer tracy_zone.end();

if (!server.config.enable_semantic_tokens) return null;
if (server.config.semantic_tokens == .none) return null;

const handle = server.document_store.getHandle(request.textDocument.uri) orelse return null;
const loc = offsets.rangeToLoc(handle.tree.source, request.range, server.offset_encoding);

return try semantic_tokens.writeSemanticTokens(server.arena.allocator(), &server.analyser, handle, loc, server.offset_encoding);
return try semantic_tokens.writeSemanticTokens(
server.arena.allocator(),
&server.analyser,
handle,
loc,
server.offset_encoding,
server.config.semantic_tokens == .partial,
);
}

pub fn completionHandler(server: *Server, request: types.CompletionParams) Error!?types.CompletionList {
Expand Down
13 changes: 9 additions & 4 deletions src/config_gen/config.json
Original file line number Diff line number Diff line change
Expand Up @@ -25,10 +25,15 @@
"default": "true"
},
{
"name": "enable_semantic_tokens",
"description": "Enables semantic token support when the client also supports it",
"type": "bool",
"default": "true"
"name": "semantic_tokens",
"description": "Set level of semantic tokens. Partial only includes information that requires semantic analysis.",
"type": "enum",
"enum": [
"none",
"partial",
"full"
],
"default": "full"
},
{
"name": "enable_inlay_hints",
Expand Down
23 changes: 17 additions & 6 deletions src/config_gen/config_gen.zig
Original file line number Diff line number Diff line change
Expand Up @@ -39,14 +39,25 @@ const ConfigOption = struct {
_ = options;
if (fmt.len != 0) return std.fmt.invalidFmtError(fmt, ConfigOption);
if (config.@"enum") |enum_members| {
try writer.writeAll("enum {");
if (enum_members.len > 1) try writer.writeByte(' ');
for (enum_members, 0..) |member_name, i| {
if (i != 0) try writer.writeAll(", ");
try writer.writeAll("enum {\n ");
for (enum_members) |member_name| {
try writer.writeAll(member_name);
try writer.writeAll(",\n ");
}
if (enum_members.len > 1) try writer.writeByte(' ');
try writer.writeByte('}');
std.debug.assert(enum_members.len > 1);
try writer.writeAll(
\\
\\ pub fn jsonStringify(
\\ value: @This(),
\\ _: anytype,
\\ writer: anytype,
\\ ) @TypeOf(writer).Error!void {
\\ try writer.writeByte('"');
\\ try writer.writeAll(@tagName(value));
\\ try writer.writeByte('"');
\\ }
\\}
);
return;
}
try writer.writeAll(config.type);
Expand Down
27 changes: 27 additions & 0 deletions src/semantic_tokens.zig
Original file line number Diff line number Diff line change
Expand Up @@ -46,8 +46,21 @@ const Builder = struct {
previous_token: ?Ast.TokenIndex = null,
token_buffer: std.ArrayListUnmanaged(u32) = .{},
encoding: offsets.Encoding,
limited: bool,

fn add(self: *Builder, token: Ast.TokenIndex, token_type: TokenType, token_modifiers: TokenModifiers) !void {
switch (token_type) {
.type,
.parameter,
.variable,
.enumMember,
.field,
.errorTag,
.function,
.label,
=> {},
else => if (self.limited) return,
}
const tree = self.handle.tree;
const starts = tree.tokens.items(.start);

Expand Down Expand Up @@ -158,6 +171,18 @@ const Builder = struct {

fn addDirect(self: *Builder, tok_type: TokenType, tok_mod: TokenModifiers, start: usize, length: usize) !void {
if (start < self.previous_source_index) return;
switch (tok_type) {
.type,
.parameter,
.variable,
.enumMember,
.field,
.errorTag,
.function,
.label,
=> {},
else => if (self.limited) return,
}

const text = self.handle.tree.source[self.previous_source_index..start];
const delta = offsets.indexToPosition(text, text.len, self.encoding);
Expand Down Expand Up @@ -1010,12 +1035,14 @@ pub fn writeSemanticTokens(
handle: *const DocumentStore.Handle,
loc: ?offsets.Loc,
encoding: offsets.Encoding,
limited: bool,
) error{OutOfMemory}!types.SemanticTokens {
var builder = Builder{
.arena = arena,
.analyser = analyser,
.handle = handle,
.encoding = encoding,
.limited = limited,
};

const nodes = if (loc) |l| try ast.nodesAtLoc(arena, handle.tree, l) else handle.tree.rootDecls();
Expand Down
2 changes: 1 addition & 1 deletion tests/context.zig
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ const initialize_msg =

const default_config: Config = .{
.enable_ast_check_diagnostics = false,
.enable_semantic_tokens = true,
.semantic_tokens = .full,
.enable_inlay_hints = true,
.inlay_hints_exclude_single_argument = false,
.inlay_hints_show_builtin = true,
Expand Down

0 comments on commit 0af5ed6

Please sign in to comment.