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 =>
|
else =>
|
||||||
try zinput.askBool("Should the @ sign be included in completions of builtin functions?\nChange this later if `@inc` completes to `include` or `@@include`")
|
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, .{});
|
var dir = try std.fs.cwd().openDir(builder.exe_dir, .{});
|
||||||
defer dir.close();
|
defer dir.close();
|
||||||
@ -92,6 +98,7 @@ pub fn config(step: *std.build.Step) anyerror!void {
|
|||||||
.enable_semantic_tokens = semantic_tokens,
|
.enable_semantic_tokens = semantic_tokens,
|
||||||
.operator_completions = operator_completions,
|
.operator_completions = operator_completions,
|
||||||
.include_at_in_builtins = include_at_in_builtins,
|
.include_at_in_builtins = include_at_in_builtins,
|
||||||
|
.max_detail_length = max_detail_length,
|
||||||
}, std.json.StringifyOptions{}, out);
|
}, std.json.StringifyOptions{}, out);
|
||||||
|
|
||||||
std.debug.warn("Successfully saved configuration options!\n", .{});
|
std.debug.warn("Successfully saved configuration options!\n", .{});
|
||||||
|
@ -17,7 +17,7 @@ warn_style: bool = false,
|
|||||||
/// Path to the build_runner.zig file.
|
/// Path to the build_runner.zig file.
|
||||||
build_runner_path: ?[]const u8 = null,
|
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,
|
build_runner_cache_path: ?[]const u8 = null,
|
||||||
|
|
||||||
/// Semantic token support
|
/// Semantic token support
|
||||||
@ -29,6 +29,9 @@ operator_completions: bool = true,
|
|||||||
/// Whether the @ sign should be part of the completion of builtins
|
/// Whether the @ sign should be part of the completion of builtins
|
||||||
include_at_in_builtins: bool = false,
|
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.
|
/// Skips references to std. This will improve lookup speeds.
|
||||||
/// Going to definition however will continue to work
|
/// Going to definition however will continue to work
|
||||||
skip_std_references: bool = false,
|
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();
|
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 {
|
fn respondGeneric(id: types.RequestId, response: []const u8) !void {
|
||||||
const id_len = switch (id) {
|
const id_len = switch (id) {
|
||||||
.Integer => |id_val| blk: {
|
.Integer => |id_val| blk: {
|
||||||
@ -998,6 +1008,7 @@ fn completeLabel(arena: *std.heap.ArenaAllocator, id: types.RequestId, pos_index
|
|||||||
.orig_handle = handle,
|
.orig_handle = handle,
|
||||||
};
|
};
|
||||||
try analysis.iterateLabels(handle, pos_index, declToCompletion, context);
|
try analysis.iterateLabels(handle, pos_index, declToCompletion, context);
|
||||||
|
truncateCompletions(completions.items, config.max_detail_length);
|
||||||
|
|
||||||
try send(arena, types.Response{
|
try send(arena, types.Response{
|
||||||
.id = id,
|
.id = id,
|
||||||
@ -1039,6 +1050,7 @@ fn completeBuiltin(arena: *std.heap.ArenaAllocator, id: types.RequestId, config:
|
|||||||
else
|
else
|
||||||
insert_text[1..];
|
insert_text[1..];
|
||||||
}
|
}
|
||||||
|
truncateCompletions(builtin_completions.?, config.max_detail_length);
|
||||||
}
|
}
|
||||||
|
|
||||||
try send(arena, types.Response{
|
try send(arena, types.Response{
|
||||||
@ -1062,6 +1074,7 @@ fn completeGlobal(arena: *std.heap.ArenaAllocator, id: types.RequestId, pos_inde
|
|||||||
.orig_handle = handle,
|
.orig_handle = handle,
|
||||||
};
|
};
|
||||||
try analysis.iterateSymbolsGlobal(&document_store, arena, handle, pos_index, declToCompletion, context);
|
try analysis.iterateSymbolsGlobal(&document_store, arena, handle, pos_index, declToCompletion, context);
|
||||||
|
truncateCompletions(completions.items, config.max_detail_length);
|
||||||
|
|
||||||
try send(arena, types.Response{
|
try send(arena, types.Response{
|
||||||
.id = id,
|
.id = id,
|
||||||
@ -1087,6 +1100,7 @@ fn completeFieldAccess(
|
|||||||
if (try analysis.getFieldAccessType(&document_store, arena, handle, position.absolute_index, &tokenizer)) |result| {
|
if (try analysis.getFieldAccessType(&document_store, arena, handle, position.absolute_index, &tokenizer)) |result| {
|
||||||
try typeToCompletion(arena, &completions, result, handle, config);
|
try typeToCompletion(arena, &completions, result, handle, config);
|
||||||
}
|
}
|
||||||
|
truncateCompletions(completions.items, config.max_detail_length);
|
||||||
|
|
||||||
try send(arena, types.Response{
|
try send(arena, types.Response{
|
||||||
.id = id,
|
.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 {
|
fn documentSymbol(arena: *std.heap.ArenaAllocator, id: types.RequestId, handle: *DocumentStore.Handle) !void {
|
||||||
try send(arena, types.Response{
|
try send(arena, types.Response{
|
||||||
.id = id,
|
.id = id,
|
||||||
@ -1117,6 +1171,9 @@ fn loadConfig(folder_path: []const u8) ?Config {
|
|||||||
};
|
};
|
||||||
defer allocator.free(file_buf);
|
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.
|
// 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| {
|
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});
|
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 doc_position = try offsets.documentPosition(handle.document, req.params.position, offset_encoding);
|
||||||
const pos_context = try analysis.documentPositionContext(arena, handle.document, doc_position);
|
const pos_context = try analysis.documentPositionContext(arena, handle.document, doc_position);
|
||||||
const use_snippets = config.enable_snippets and client_capabilities.supports_snippets;
|
const use_snippets = config.enable_snippets and client_capabilities.supports_snippets;
|
||||||
|
|
||||||
switch (pos_context) {
|
switch (pos_context) {
|
||||||
.builtin => try completeBuiltin(arena, id, config),
|
.builtin => try completeBuiltin(arena, id, config),
|
||||||
.var_access, .empty => try completeGlobal(arena, id, doc_position.absolute_index, handle, 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),
|
.field_access => |range| try completeFieldAccess(arena, id, handle, doc_position, range, config),
|
||||||
.global_error_set => try send(arena, types.Response{
|
.global_error_set => try completeError(arena, id, handle, config),
|
||||||
.id = id,
|
.enum_literal => try completeDot(arena, id, handle, config),
|
||||||
.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),
|
|
||||||
},
|
|
||||||
},
|
|
||||||
}),
|
|
||||||
.label => try completeLabel(arena, id, doc_position.absolute_index, handle, config),
|
.label => try completeLabel(arena, id, doc_position.absolute_index, handle, config),
|
||||||
else => try respondGeneric(id, no_completions_response),
|
else => try respondGeneric(id, no_completions_response),
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user