diff --git a/src/Server.zig b/src/Server.zig index f811b24f0..e7827a5be 100644 --- a/src/Server.zig +++ b/src/Server.zig @@ -754,42 +754,9 @@ fn handleConfiguration(server: *Server, json: std.json.Value) error{OutOfMemory} } } - const maybe_root_dir: ?[]const u8 = if (server.workspaces.items.len == 1) dir: { - const uri = std.Uri.parse(server.workspaces.items[0].uri) catch |err| { - log.err("failed to parse root uri for workspace {s}: {!}", .{ - server.workspaces.items[0].uri, err, - }); - break :dir null; - }; - break :dir try uri.path.toRawMaybeAlloc(arena); - } else null; - - check_relative: inline for (&.{ - "zig_exe_path", - "builtin_path", - "build_runner_path", - "zig_lib_path", - "global_cache_path", - }) |fieldName| { - const field: *?[]const u8 = &@field(new_config, fieldName); - if (field.*) |maybe_relative| resolve: { - if (maybe_relative.len == 0) break :resolve; - if (std.fs.path.isAbsolute(maybe_relative)) break :resolve; - - const root_dir = maybe_root_dir orelse { - log.err("relative path only supported for {s} with exactly one workspace", .{fieldName}); - break :check_relative; - }; - - const absolute = try std.fs.path.join(arena, &.{ - root_dir, maybe_relative, - }); - - field.* = absolute; - } - } - - server.updateConfiguration(new_config, .{}) catch |err| { + server.updateConfiguration(new_config, .{ + .allow_relative_paths = true, + }) catch |err| { log.err("failed to update configuration: {}", .{err}); }; } @@ -980,12 +947,15 @@ fn didChangeConfigurationHandler(server: *Server, arena: std.mem.Allocator, noti return error.ParseError; }; - try server.updateConfiguration(new_config, .{}); + try server.updateConfiguration(new_config, .{ + .allow_relative_paths = true, + }); } pub const UpdateConfigurationOptions = struct { resolve: bool = true, leaky_config_arena: bool = false, + allow_relative_paths: bool = false, }; pub fn updateConfiguration2( @@ -1016,6 +986,43 @@ pub fn updateConfiguration( var new_config: configuration.Configuration = param_new_config; + if (options.allow_relative_paths) { + const maybe_root_dir: ?[]const u8 = if (server.workspaces.items.len == 1) dir: { + const uri = std.Uri.parse(server.workspaces.items[0].uri) catch |err| { + log.err("failed to parse root uri for workspace {s}: {!}", .{ + server.workspaces.items[0].uri, err, + }); + break :dir null; + }; + break :dir try uri.path.toRawMaybeAlloc(config_arena); + } else null; + + check_relative: inline for (&.{ + "zig_exe_path", + "builtin_path", + "build_runner_path", + "zig_lib_path", + "global_cache_path", + }) |fieldName| { + const field: *?[]const u8 = &@field(new_config, fieldName); + if (field.*) |maybe_relative| resolve: { + if (maybe_relative.len == 0) break :resolve; + if (std.fs.path.isAbsolute(maybe_relative)) break :resolve; + + const root_dir = maybe_root_dir orelse { + log.err("relative path only supported for {s} with exactly one workspace", .{fieldName}); + break :check_relative; + }; + + const absolute = try std.fs.path.resolve(config_arena, &.{ + root_dir, maybe_relative, + }); + + field.* = absolute; + } + } + } + server.validateConfiguration(&new_config); inline for (std.meta.fields(Config)) |field| { @field(new_config, field.name) = if (@field(new_config, field.name)) |new_value|