From 424a06b7ee46c546ea15e3f9cc34c419eb6ea4dd Mon Sep 17 00:00:00 2001 From: nullptrdevs <16590917+nullptrdevs@users.noreply.github.com> Date: Wed, 22 Feb 2023 08:30:21 -0800 Subject: [PATCH] `completeBuiltin` fixes (#1015) - Always return a copy to avoid memory corruption (most operations assume an arena allocated copy) - label_details were only generated for the first (pre-fix) disposable copy - Correct use_snippets logic (send only if configured and client supports them) --- src/Server.zig | 52 +++++++++++++++++++++++++------------------------- 1 file changed, 26 insertions(+), 26 deletions(-) diff --git a/src/Server.zig b/src/Server.zig index e0d864e..020584e 100644 --- a/src/Server.zig +++ b/src/Server.zig @@ -1364,31 +1364,33 @@ fn completeBuiltin(server: *Server) error{OutOfMemory}!?[]types.CompletionItem { const allocator = server.arena.allocator(); - const builtin_completions = if (server.builtin_completions) |completions| - return completions.items - else blk: { - server.builtin_completions = try std.ArrayListUnmanaged(types.CompletionItem).initCapacity(server.allocator, data.builtins.len); - break :blk &server.builtin_completions.?; + const builtin_completions = blk: { + if (server.builtin_completions) |completions| { + break :blk completions; + } else { + server.builtin_completions = try std.ArrayListUnmanaged(types.CompletionItem).initCapacity(server.allocator, data.builtins.len); + for (data.builtins) |builtin| { + const use_snippets = server.config.enable_snippets and server.client_capabilities.supports_snippets; + const insert_text = if (use_snippets) builtin.snippet else builtin.name; + server.builtin_completions.?.appendAssumeCapacity(.{ + .label = builtin.name, + .kind = .Function, + .filterText = builtin.name[1..], + .detail = builtin.signature, + .insertText = if (server.config.include_at_in_builtins) insert_text else insert_text[1..], + .insertTextFormat = if (use_snippets) .Snippet else .PlainText, + .documentation = .{ + .MarkupContent = .{ + .kind = .markdown, + .value = builtin.documentation, + }, + }, + }); + } + break :blk server.builtin_completions.?; + } }; - for (data.builtins) |builtin| { - const insert_text = if (server.config.enable_snippets) builtin.snippet else builtin.name; - builtin_completions.appendAssumeCapacity(.{ - .label = builtin.name, - .kind = .Function, - .filterText = builtin.name[1..], - .detail = builtin.signature, - .insertText = if (server.config.include_at_in_builtins) insert_text else insert_text[1..], - .insertTextFormat = if (server.config.enable_snippets) .Snippet else .PlainText, - .documentation = .{ - .MarkupContent = .{ - .kind = .markdown, - .value = builtin.documentation, - }, - }, - }); - } - var completions = try builtin_completions.clone(allocator); if (server.client_capabilities.label_details_support) { @@ -1984,11 +1986,9 @@ fn initializedHandler(server: *Server, notification: types.InitializedParams) Er try server.requestConfiguration(); } -fn shutdownHandler(server: *Server, _: void) Error!?void { +fn shutdownHandler(server: *Server, _: void) Error!void { defer server.status = .shutdown; if (server.status != .initialized) return error.InvalidRequest; // received a shutdown request but the server is not initialized! - - return null; } fn exitHandler(server: *Server, _: void) Error!void {