diff --git a/src/Config.zig b/src/Config.zig index 62380c3..623ce88 100644 --- a/src/Config.zig +++ b/src/Config.zig @@ -255,3 +255,25 @@ pub fn getZigEnv(allocator: std.mem.Allocator, zig_exe_path: []const u8) ?Env { return null; }; } + +pub const Configuration = Config.getConfigurationType(); +pub const DidChangeConfigurationParams = struct { + settings: ?Configuration, +}; + +// returns a Struct which is the same as `Config` except that every field is optional. +fn getConfigurationType() type { + var config_info: std.builtin.Type = @typeInfo(Config); + var fields: [config_info.Struct.fields.len]std.builtin.Type.StructField = undefined; + for (config_info.Struct.fields) |field, i| { + fields[i] = field; + if (@typeInfo(field.field_type) != .Optional) { + fields[i].field_type = @Type(std.builtin.Type{ + .Optional = .{ .child = field.field_type }, + }); + } + } + config_info.Struct.fields = fields[0..]; + config_info.Struct.decls = &.{}; + return @Type(config_info); +} diff --git a/src/Server.zig b/src/Server.zig index 94c868d..3158d43 100644 --- a/src/Server.zig +++ b/src/Server.zig @@ -2062,23 +2062,25 @@ fn formattingHandler(server: *Server, writer: anytype, id: types.RequestId, req: return try respondGeneric(writer, id, null_result_response); } -fn didChangeConfigurationHandler(server: *Server, writer: anytype, id: types.RequestId, maybe_req: std.json.Value) !void { +fn didChangeConfigurationHandler(server: *Server, writer: anytype, id: types.RequestId, req: Config.DidChangeConfigurationParams) !void { const tracy_zone = tracy.trace(@src()); defer tracy_zone.end(); _ = id; - if (maybe_req.Object.get("params").?.Object.get("settings").? == .Object) { - const req = try requests.fromDynamicTree(&server.arena, requests.Configuration, maybe_req); - inline for (std.meta.fields(Config)) |field| { - if (@field(req.params.settings, field.name)) |value| { - log.debug("setting configuration option '{s}' to '{any}'", .{ field.name, value }); + + // NOTE: VS Code seems to always respond with null + if (req.settings) |configuration| { + inline for (std.meta.fields(Config.Configuration)) |field| { + if (@field(configuration, field.name)) |value| { @field(server.config, field.name) = if (@TypeOf(value) == []const u8) try server.allocator.dupe(u8, value) else value; + log.debug("setting configuration option '{s}' to '{any}'", .{ field.name, value }); } } try server.config.configChanged(server.allocator, null); - } else if (server.client_capabilities.supports_configuration) + } else if (server.client_capabilities.supports_configuration) { try server.requestConfiguration(writer); + } } fn renameHandler(server: *Server, writer: anytype, id: types.RequestId, req: requests.Rename) !void { @@ -2435,7 +2437,7 @@ pub fn processJsonRpc(server: *Server, writer: anytype, json: []const u8) !void .{ "textDocument/references", requests.References, referencesHandler }, .{ "textDocument/documentHighlight", requests.DocumentHighlight, documentHighlightHandler }, .{ "textDocument/codeAction", requests.CodeAction, codeActionHandler }, - .{ "workspace/didChangeConfiguration", std.json.Value, didChangeConfigurationHandler }, + .{ "workspace/didChangeConfiguration", Config.DidChangeConfigurationParams, didChangeConfigurationHandler }, }; if (zig_builtin.zig_backend == .stage1) { diff --git a/src/requests.zig b/src/requests.zig index 371cfcb..9c2ddab 100644 --- a/src/requests.zig +++ b/src/requests.zig @@ -288,30 +288,3 @@ pub const CodeAction = struct { }, }, }; - -pub const Configuration = struct { - params: struct { - settings: struct { - enable_snippets: ?bool, - enable_ast_check_diagnostics: ?bool, - enable_autofix: ?bool, - enable_import_embedfile_argument_completions: ?bool, - zig_lib_path: ?[]const u8, - zig_exe_path: ?[]const u8, - warn_style: ?bool, - build_runner_path: ?[]const u8, - global_cache_path: ?[]const u8, - enable_semantic_tokens: ?bool, - enable_inlay_hints: ?bool, - inlay_hints_show_builtin: ?bool, - inlay_hints_exclude_single_argument: ?bool, - inlay_hints_hide_redundant_param_names: ?bool, - inlay_hints_hide_redundant_param_names_last_token: ?bool, - operator_completions: ?bool, - include_at_in_builtins: ?bool, - max_detail_length: ?usize, - skip_std_references: ?bool, - builtin_path: ?[]const u8, - }, - }, -};