Skip to content

Commit

Permalink
Add completions for tuple fields
Browse files Browse the repository at this point in the history
  • Loading branch information
FnControlOption committed Feb 9, 2025
1 parent 771e1cf commit 0c335bd
Show file tree
Hide file tree
Showing 2 changed files with 52 additions and 1 deletion.
30 changes: 29 additions & 1 deletion src/features/completions.zig
Original file line number Diff line number Diff line change
Expand Up @@ -90,7 +90,21 @@ fn typeToCompletion(builder: *Builder, ty: Analyser.Type) error{OutOfMemory}!voi
.kind = .Field,
});
},
.tuple => {}, // TODO
.tuple => |elem_ty_slice| {
if (ty.is_type_val) return;
try builder.completions.ensureUnusedCapacity(builder.arena, elem_ty_slice.len);
for (elem_ty_slice, 0..) |elem_ty, i| {
builder.completions.appendAssumeCapacity(.{
.label = try std.fmt.allocPrint(builder.arena, "@\"{}\"", .{i}),
.kind = .Field,
.detail = try std.fmt.allocPrint(
builder.arena,
"{}",
.{elem_ty.fmt(builder.analyser, .{ .truncate_container_decls = false })},
),
});
}
},
.optional => |child_ty| {
if (ty.is_type_val) return;
builder.completions.appendAssumeCapacity(.{
Expand All @@ -112,6 +126,20 @@ fn typeToCompletion(builder: *Builder, ty: Analyser.Type) error{OutOfMemory}!voi
.parent_container_ty = ty,
});
}

if (ty.is_type_val) return;
var i: usize = 0;
while (try builder.analyser.resolveTupleFieldType(ty, i)) |elem_ty| : (i += 1) {
try builder.completions.append(builder.arena, .{
.label = try std.fmt.allocPrint(builder.arena, "@\"{}\"", .{i}),
.kind = .Field,
.detail = try std.fmt.allocPrint(
builder.arena,
"{}",
.{elem_ty.fmt(builder.analyser, .{ .truncate_container_decls = false })},
),
});
}
},
.other => |node_handle| switch (node_handle.handle.tree.nodes.items(.tag)[node_handle.node]) {
.merge_error_sets => {
Expand Down
23 changes: 23 additions & 0 deletions tests/lsp_features/completion.zig
Original file line number Diff line number Diff line change
Expand Up @@ -823,6 +823,29 @@ test "array type" {
, &.{});
}

test "tuple fields" {
try testCompletion(
\\fn foo() void {
\\ var a: f32 = 0;
\\ var b: i64 = 1;
\\ const foo = .{ b, a };
\\ const bar = foo.<cursor>
\\}
, &.{
.{ .label = "@\"0\"", .kind = .Field, .detail = "i64" },
.{ .label = "@\"1\"", .kind = .Field, .detail = "f32" },
});
try testCompletion(
\\fn foo() void {
\\ const foo: struct { i64, f32 } = .{ 1, 0 };
\\ const bar = foo.<cursor>
\\}
, &.{
.{ .label = "@\"0\"", .kind = .Field, .detail = "i64" },
.{ .label = "@\"1\"", .kind = .Field, .detail = "f32" },
});
}

test "if/for/while/catch scopes" {
try testCompletion(
\\const S = struct { pub const T = u32; };
Expand Down

0 comments on commit 0c335bd

Please sign in to comment.