diff --git a/src/DocumentStore.zig b/src/DocumentStore.zig index bf4b662..eef7316 100644 --- a/src/DocumentStore.zig +++ b/src/DocumentStore.zig @@ -190,6 +190,8 @@ fn loadPackages(context: LoadPackagesContext) !void { }; } } + } else { + return error.RunFailed; } }, else => return error.RunFailed, @@ -268,7 +270,7 @@ fn newDocument(self: *DocumentStore, uri: []const u8, text: [:0]u8) anyerror!*Ha .cache_root = self.zig_cache_root, .global_cache_root = self.zig_global_cache_root, }) catch |err| { - log.debug("Failed to load packages of build file {s} (error: {})", .{ build_file.uri, err }); + log.warn("Failed to load packages of build file {s} (error: {})", .{ build_file.uri, err }); }; try self.build_files.append(self.allocator, build_file); @@ -537,7 +539,7 @@ pub fn applySave(self: *DocumentStore, handle: *Handle) !void { .cache_root = self.zig_cache_root, .global_cache_root = self.zig_global_cache_root, }) catch |err| { - log.debug("Failed to load packages of build file {s} (error: {})", .{ build_file.uri, err }); + log.warn("Failed to load packages of build file {s} (error: {})", .{ build_file.uri, err }); }; } } diff --git a/src/main.zig b/src/main.zig index 8fd812d..ada5ae5 100644 --- a/src/main.zig +++ b/src/main.zig @@ -1081,7 +1081,7 @@ fn completeLabel(arena: *std.heap.ArenaAllocator, id: types.RequestId, pos_index .orig_handle = handle, }; try analysis.iterateLabels(handle, pos_index, declToCompletion, context); - sortCompletionItems(completions.items, config); + sortCompletionItems(completions.items, config, arena.allocator()); truncateCompletions(completions.items, config.max_detail_length); try send(arena, types.Response{ @@ -1154,7 +1154,7 @@ fn completeGlobal(arena: *std.heap.ArenaAllocator, id: types.RequestId, pos_inde .orig_handle = handle, }; try analysis.iterateSymbolsGlobal(&document_store, arena, handle, pos_index, declToCompletion, context); - sortCompletionItems(completions.items, config); + sortCompletionItems(completions.items, config, arena.allocator()); truncateCompletions(completions.items, config.max_detail_length); if (client_capabilities.label_details_support) { @@ -1188,7 +1188,7 @@ fn completeFieldAccess(arena: *std.heap.ArenaAllocator, id: types.RequestId, han if (try analysis.getFieldAccessType(&document_store, arena, handle, position.absolute_index, &tokenizer)) |result| { held_range.release(); try typeToCompletion(arena, &completions, result, handle, config); - sortCompletionItems(completions.items, config); + sortCompletionItems(completions.items, config, arena.allocator()); truncateCompletions(completions.items, config.max_detail_length); if (client_capabilities.label_details_support) { for (completions.items) |*item| { @@ -1397,7 +1397,10 @@ fn completeError(arena: *std.heap.ArenaAllocator, id: types.RequestId, handle: * } fn kindToSortScore(kind: types.CompletionItem.Kind) [] const u8 { - return switch (kind) { + return switch (kind) + { + .Constant => "1_", + .Variable => "2_", .Field => "3_", .Function => "4_", @@ -1415,10 +1418,16 @@ fn kindToSortScore(kind: types.CompletionItem.Kind) [] const u8 { }; } -fn sortCompletionItems(completions: []types.CompletionItem, _: *const Config) void { +fn sortCompletionItems(completions: []types.CompletionItem, _: *const Config, alloc: std.mem.Allocator) void { // TODO: config for sorting rule? for (completions) |*c| { c.sortText = kindToSortScore(c.kind); + + if (alloc.alloc(u8, 2 + c.label.len)) |it| { + std.mem.copy(u8, it, c.sortText.?); + std.mem.copy(u8, it[2 .. ], c.label); + c.sortText = it; + } else |_| {} } } @@ -1427,7 +1436,7 @@ fn completeDot(arena: *std.heap.ArenaAllocator, id: types.RequestId, handle: *Do defer tracy_zone.end(); var completions = try document_store.enumCompletionItems(arena, handle); - sortCompletionItems(completions, config); + sortCompletionItems(completions, config, arena.allocator()); truncateCompletions(completions, config.max_detail_length); try send(arena, types.Response{ @@ -2094,6 +2103,8 @@ pub fn main() anyerror!void { if (!args_it.skip()) @panic("Could not find self argument"); var config_path: ?[]const u8 = null; + defer if (config_path) |path| allocator.free(path); + var next_arg_config_path = false; while (args_it.next()) |arg| { if (next_arg_config_path) { @@ -2133,13 +2144,14 @@ pub fn main() anyerror!void { config_read: { if (config_path) |path| { - defer allocator.free(path); if (loadConfigFile(path)) |conf| { config = conf; break :config_read; } std.debug.print("Could not open configuration file '{s}'\n", .{path}); std.debug.print("Falling back to a lookup in the local and global configuration folders\n", .{}); + allocator.free(path); + config_path = null; } if (try known_folders.getPath(allocator, .local_configuration)) |path| { config_path = path; diff --git a/src/types.zig b/src/types.zig index 4a00a52..9dcca6e 100644 --- a/src/types.zig +++ b/src/types.zig @@ -261,6 +261,7 @@ pub const CompletionItem = struct { pub const CompletionItemLabelDetails = struct { detail: ?string, description: ?string, + sortText: ?string = null, }; pub const DocumentSymbol = struct { diff --git a/tests/sessions.zig b/tests/sessions.zig index 9c5a350..5f4d84a 100644 --- a/tests/sessions.zig +++ b/tests/sessions.zig @@ -186,7 +186,7 @@ test "Request completion with no trailing whitespace" { try server.request("textDocument/completion", \\{"textDocument":{"uri":"file:///test.zig"}, "position":{"line":1,"character":1}} , - \\{"isIncomplete":false,"items":[{"label":"std","kind":21,"textEdit":null,"filterText":null,"insertText":"std","insertTextFormat":1,"detail":"const std = @import(\"std\")","documentation":null}]} + \\{"isIncomplete":false,"items":[{"label":"std","kind":21,"textEdit":null,"filterText":null,"insertText":"std","insertTextFormat":1,"detail":"const std = @import(\"std\")","documentation":null,"sortText":"1_std"}]} ); }