Add option to truncate long completions
The detail entries for big structs such as std.zig.CrossTarget were bricking the preview window in Sublime Text.
This commit is contained in:
parent
3e300e4d74
commit
b33e26612a
@ -74,6 +74,12 @@ pub fn config(step: *std.build.Step) anyerror!void {
|
||||
else =>
|
||||
try zinput.askBool("Should the @ sign be included in completions of builtin functions?\nChange this later if `@inc` completes to `include` or `@@include`")
|
||||
};
|
||||
const max_detail_length: usize = switch (editor) {
|
||||
.Sublime =>
|
||||
256,
|
||||
else =>
|
||||
1024 * 1024
|
||||
};
|
||||
|
||||
var dir = try std.fs.cwd().openDir(builder.exe_dir, .{});
|
||||
defer dir.close();
|
||||
@ -92,6 +98,7 @@ pub fn config(step: *std.build.Step) anyerror!void {
|
||||
.enable_semantic_tokens = semantic_tokens,
|
||||
.operator_completions = operator_completions,
|
||||
.include_at_in_builtins = include_at_in_builtins,
|
||||
.max_detail_length = max_detail_length,
|
||||
}, std.json.StringifyOptions{}, out);
|
||||
|
||||
std.debug.warn("Successfully saved configuration options!\n", .{});
|
||||
|
@ -17,7 +17,7 @@ warn_style: bool = false,
|
||||
/// Path to the build_runner.zig file.
|
||||
build_runner_path: ?[]const u8 = null,
|
||||
|
||||
/// Path to a directory that will be used as cache when `zig run`ing the build runner
|
||||
/// Path to a directory that will be used as cache when `zig run`ning the build runner
|
||||
build_runner_cache_path: ?[]const u8 = null,
|
||||
|
||||
/// Semantic token support
|
||||
@ -29,6 +29,9 @@ operator_completions: bool = true,
|
||||
/// Whether the @ sign should be part of the completion of builtins
|
||||
include_at_in_builtins: bool = false,
|
||||
|
||||
/// The detail field of completions is truncated to be no longer than this (in bytes).
|
||||
max_detail_length: usize = 1024 * 1024,
|
||||
|
||||
/// Skips references to std. This will improve lookup speeds.
|
||||
/// Going to definition however will continue to work
|
||||
skip_std_references: bool = false,
|
||||
|
78
src/main.zig
78
src/main.zig
@ -138,6 +138,16 @@ fn send(arena: *std.heap.ArenaAllocator, reqOrRes: anytype) !void {
|
||||
try stdout.flush();
|
||||
}
|
||||
|
||||
fn truncateCompletions(list: []types.CompletionItem, max_detail_length: usize) void {
|
||||
for (list) |*item| {
|
||||
if (item.detail) |det| {
|
||||
if (det.len > max_detail_length) {
|
||||
item.detail = det[0..max_detail_length];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn respondGeneric(id: types.RequestId, response: []const u8) !void {
|
||||
const id_len = switch (id) {
|
||||
.Integer => |id_val| blk: {
|
||||
@ -998,6 +1008,7 @@ fn completeLabel(arena: *std.heap.ArenaAllocator, id: types.RequestId, pos_index
|
||||
.orig_handle = handle,
|
||||
};
|
||||
try analysis.iterateLabels(handle, pos_index, declToCompletion, context);
|
||||
truncateCompletions(completions.items, config.max_detail_length);
|
||||
|
||||
try send(arena, types.Response{
|
||||
.id = id,
|
||||
@ -1039,6 +1050,7 @@ fn completeBuiltin(arena: *std.heap.ArenaAllocator, id: types.RequestId, config:
|
||||
else
|
||||
insert_text[1..];
|
||||
}
|
||||
truncateCompletions(builtin_completions.?, config.max_detail_length);
|
||||
}
|
||||
|
||||
try send(arena, types.Response{
|
||||
@ -1062,6 +1074,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);
|
||||
truncateCompletions(completions.items, config.max_detail_length);
|
||||
|
||||
try send(arena, types.Response{
|
||||
.id = id,
|
||||
@ -1087,6 +1100,7 @@ fn completeFieldAccess(
|
||||
if (try analysis.getFieldAccessType(&document_store, arena, handle, position.absolute_index, &tokenizer)) |result| {
|
||||
try typeToCompletion(arena, &completions, result, handle, config);
|
||||
}
|
||||
truncateCompletions(completions.items, config.max_detail_length);
|
||||
|
||||
try send(arena, types.Response{
|
||||
.id = id,
|
||||
@ -1099,6 +1113,46 @@ fn completeFieldAccess(
|
||||
});
|
||||
}
|
||||
|
||||
fn completeError(
|
||||
arena: *std.heap.ArenaAllocator,
|
||||
id: types.RequestId,
|
||||
handle: *DocumentStore.Handle,
|
||||
config: Config
|
||||
) !void {
|
||||
const completions = try document_store.errorCompletionItems(arena, handle);
|
||||
truncateCompletions(completions, config.max_detail_length);
|
||||
|
||||
try send(arena, types.Response{
|
||||
.id = id,
|
||||
.result = .{
|
||||
.CompletionList = .{
|
||||
.isIncomplete = false,
|
||||
.items = completions,
|
||||
},
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
fn completeDot(
|
||||
arena: *std.heap.ArenaAllocator,
|
||||
id: types.RequestId,
|
||||
handle: *DocumentStore.Handle,
|
||||
config: Config
|
||||
) !void {
|
||||
var completions = try document_store.enumCompletionItems(arena, handle);
|
||||
truncateCompletions(completions, config.max_detail_length);
|
||||
|
||||
try send(arena, types.Response{
|
||||
.id = id,
|
||||
.result = .{
|
||||
.CompletionList = .{
|
||||
.isIncomplete = false,
|
||||
.items = completions,
|
||||
},
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
fn documentSymbol(arena: *std.heap.ArenaAllocator, id: types.RequestId, handle: *DocumentStore.Handle) !void {
|
||||
try send(arena, types.Response{
|
||||
.id = id,
|
||||
@ -1117,6 +1171,9 @@ fn loadConfig(folder_path: []const u8) ?Config {
|
||||
};
|
||||
defer allocator.free(file_buf);
|
||||
|
||||
// TODO: Uh oh. Profile the actual build time impact
|
||||
// of adding config options and consider alternatives (TOML?)
|
||||
@setEvalBranchQuota(2000);
|
||||
// TODO: Better errors? Doesn't seem like std.json can provide us positions or context.
|
||||
var config = std.json.parse(Config, &std.json.TokenStream.init(file_buf), std.json.ParseOptions{ .allocator = allocator }) catch |err| {
|
||||
logger.warn("Error while parsing configuration file: {}", .{err});
|
||||
@ -1304,28 +1361,13 @@ fn completionHandler(arena: *std.heap.ArenaAllocator, id: types.RequestId, req:
|
||||
const doc_position = try offsets.documentPosition(handle.document, req.params.position, offset_encoding);
|
||||
const pos_context = try analysis.documentPositionContext(arena, handle.document, doc_position);
|
||||
const use_snippets = config.enable_snippets and client_capabilities.supports_snippets;
|
||||
|
||||
switch (pos_context) {
|
||||
.builtin => try completeBuiltin(arena, id, config),
|
||||
.var_access, .empty => try completeGlobal(arena, id, doc_position.absolute_index, handle, config),
|
||||
.field_access => |range| try completeFieldAccess(arena, id, handle, doc_position, range, config),
|
||||
.global_error_set => try send(arena, types.Response{
|
||||
.id = id,
|
||||
.result = .{
|
||||
.CompletionList = .{
|
||||
.isIncomplete = false,
|
||||
.items = try document_store.errorCompletionItems(arena, handle),
|
||||
},
|
||||
},
|
||||
}),
|
||||
.enum_literal => try send(arena, types.Response{
|
||||
.id = id,
|
||||
.result = .{
|
||||
.CompletionList = .{
|
||||
.isIncomplete = false,
|
||||
.items = try document_store.enumCompletionItems(arena, handle),
|
||||
},
|
||||
},
|
||||
}),
|
||||
.global_error_set => try completeError(arena, id, handle, config),
|
||||
.enum_literal => try completeDot(arena, id, handle, config),
|
||||
.label => try completeLabel(arena, id, doc_position.absolute_index, handle, config),
|
||||
else => try respondGeneric(id, no_completions_response),
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user