@import and @embedFile completions!
This commit is contained in:
parent
bb89c3518b
commit
43c61b3da6
@ -1398,6 +1398,8 @@ pub const SourceRange = std.zig.Token.Loc;
|
||||
pub const PositionContext = union(enum) {
|
||||
builtin: SourceRange,
|
||||
comment,
|
||||
import_string_literal: SourceRange,
|
||||
embedfile_string_literal: SourceRange,
|
||||
string_literal: SourceRange,
|
||||
field_access: SourceRange,
|
||||
var_access: SourceRange,
|
||||
@ -1412,6 +1414,8 @@ pub const PositionContext = union(enum) {
|
||||
return switch (self) {
|
||||
.builtin => |r| r,
|
||||
.comment => null,
|
||||
.import_string_literal => |r| r,
|
||||
.embedfile_string_literal => |r| r,
|
||||
.string_literal => |r| r,
|
||||
.field_access => |r| r,
|
||||
.var_access => |r| r,
|
||||
@ -1485,7 +1489,27 @@ pub fn documentPositionContext(arena: *std.heap.ArenaAllocator, document: types.
|
||||
// State changes
|
||||
var curr_ctx = try peek(&stack);
|
||||
switch (tok.tag) {
|
||||
.string_literal, .multiline_string_literal_line => curr_ctx.ctx = .{ .string_literal = tok.loc },
|
||||
.string_literal, .multiline_string_literal_line => string_lit_block: {
|
||||
if (curr_ctx.stack_id == .Paren and stack.items.len >= 2) {
|
||||
const perhaps_builtin = stack.items[stack.items.len - 2];
|
||||
|
||||
switch (perhaps_builtin.ctx) {
|
||||
.builtin => |loc| {
|
||||
const builtin_name = tokenizer.buffer[loc.start..loc.end];
|
||||
if (std.mem.eql(u8, builtin_name, "@import")) {
|
||||
curr_ctx.ctx = .{ .import_string_literal = tok.loc };
|
||||
break :string_lit_block;
|
||||
}
|
||||
if (std.mem.eql(u8, builtin_name, "@embedFile")) {
|
||||
curr_ctx.ctx = .{ .embedfile_string_literal = tok.loc };
|
||||
break :string_lit_block;
|
||||
}
|
||||
},
|
||||
else => {},
|
||||
}
|
||||
}
|
||||
curr_ctx.ctx = .{ .string_literal = tok.loc };
|
||||
},
|
||||
.identifier => switch (curr_ctx.ctx) {
|
||||
.empty, .pre_label => curr_ctx.ctx = .{ .var_access = tok.loc },
|
||||
.label => |filled| if (!filled) {
|
||||
|
70
src/main.zig
70
src/main.zig
@ -17,6 +17,7 @@ const shared = @import("./shared.zig");
|
||||
const Ast = std.zig.Ast;
|
||||
const known_folders = @import("known-folders");
|
||||
const tracy = @import("./tracy.zig");
|
||||
const uri_utils = @import("./uri.zig");
|
||||
|
||||
const data = switch (build_options.data_version) {
|
||||
.master => @import("data/master.zig"),
|
||||
@ -1853,6 +1854,73 @@ fn completionHandler(arena: *std.heap.ArenaAllocator, id: types.RequestId, req:
|
||||
.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),
|
||||
.import_string_literal, .embedfile_string_literal => |loc| {
|
||||
const line_mem_start = @ptrToInt(doc_position.line.ptr) - @ptrToInt(handle.document.mem.ptr);
|
||||
const completing = handle.tree.source[line_mem_start + loc.start + 1 .. line_mem_start + loc.end];
|
||||
|
||||
var subpath_present = false;
|
||||
var fsl_completions = std.ArrayList(types.CompletionItem).init(allocator);
|
||||
|
||||
fsc: {
|
||||
var document_path = try uri_utils.parse(arena.allocator(), handle.uri());
|
||||
var document_dir_path = std.fs.openDirAbsolute(std.fs.path.dirname(document_path) orelse break :fsc, .{ .iterate = true }) catch break :fsc;
|
||||
defer document_dir_path.close();
|
||||
|
||||
if (std.mem.lastIndexOfScalar(u8, completing, '/')) |subpath_index| {
|
||||
var subpath = completing[0..subpath_index];
|
||||
|
||||
if (std.mem.startsWith(u8, subpath, "./") and subpath_index > 2) {
|
||||
subpath = completing[2..subpath_index];
|
||||
} else if (std.mem.startsWith(u8, subpath, ".") and subpath_index > 1) {
|
||||
subpath = completing[1..subpath_index];
|
||||
}
|
||||
|
||||
var old = document_dir_path;
|
||||
document_dir_path = document_dir_path.openDir(subpath, .{ .iterate = true }) catch break :fsc // NOTE: Is this even safe lol?
|
||||
old.close();
|
||||
|
||||
subpath_present = true;
|
||||
}
|
||||
|
||||
var dir_iterator = document_dir_path.iterate();
|
||||
while (try dir_iterator.next()) |entry| {
|
||||
if (std.mem.startsWith(u8, entry.name, ".")) continue;
|
||||
if (entry.kind == .File and pos_context == .import_string_literal and !std.mem.endsWith(u8, entry.name, ".zig")) continue;
|
||||
|
||||
const l = try arena.allocator().dupe(u8, entry.name);
|
||||
try fsl_completions.append(types.CompletionItem{
|
||||
.label = l,
|
||||
.insertText = l,
|
||||
.kind = if (entry.kind == .File) .File else .Folder,
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
if (!subpath_present and pos_context == .import_string_literal) {
|
||||
if (handle.associated_build_file) |bf| {
|
||||
try fsl_completions.ensureUnusedCapacity(bf.packages.items.len);
|
||||
|
||||
for (bf.packages.items) |pkg| {
|
||||
try fsl_completions.append(.{
|
||||
.label = pkg.name,
|
||||
.kind = .Module,
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
truncateCompletions(fsl_completions.items, config.max_detail_length);
|
||||
|
||||
try send(arena, types.Response{
|
||||
.id = id,
|
||||
.result = .{
|
||||
.CompletionList = .{
|
||||
.isIncomplete = false,
|
||||
.items = fsl_completions.items,
|
||||
},
|
||||
},
|
||||
});
|
||||
},
|
||||
else => try respondGeneric(id, no_completions_response),
|
||||
}
|
||||
}
|
||||
@ -1910,7 +1978,7 @@ fn gotoHandler(arena: *std.heap.ArenaAllocator, id: types.RequestId, req: reques
|
||||
switch (pos_context) {
|
||||
.var_access => try gotoDefinitionGlobal(arena, id, doc_position.absolute_index, handle, config, resolve_alias),
|
||||
.field_access => |range| try gotoDefinitionFieldAccess(arena, id, handle, doc_position, range, config, resolve_alias),
|
||||
.string_literal => try gotoDefinitionString(arena, id, doc_position.absolute_index, handle, config),
|
||||
.import_string_literal => try gotoDefinitionString(arena, id, doc_position.absolute_index, handle, config),
|
||||
.label => try gotoDefinitionLabel(arena, id, doc_position.absolute_index, handle, config),
|
||||
else => try respondGeneric(id, null_result_response),
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user