Skip to content

Commit

Permalink
completions: fix switch on tagged union completion (#1807)
Browse files Browse the repository at this point in the history
  • Loading branch information
llogick authored Mar 1, 2024
1 parent 7c2728f commit 80ddf7b
Show file tree
Hide file tree
Showing 2 changed files with 22 additions and 4 deletions.
9 changes: 5 additions & 4 deletions src/features/completions.zig
Original file line number Diff line number Diff line change
Expand Up @@ -1039,7 +1039,7 @@ fn globalSetCompletions(builder: *Builder, kind: enum { error_set, enum_set }) e

const EnumLiteralContext = struct {
const Likely = enum { // TODO: better name, tagged union?
/// `mye: Enum = .`, `abc.field = .`, `f(.{.field = .`, `switch` case
/// `mye: Enum = .`, `abc.field = .`, `f(.{.field = .`
enum_literal,
/// Same as above, but`f() = .` or `identifier.f() = .` are ignored, ie lhs of `=` is a fn call
enum_assignment,
Expand All @@ -1049,6 +1049,7 @@ const EnumLiteralContext = struct {
enum_arg,
/// `S{.`, `var s:S = .{.`, `f(.{.` or `a.f(.{.`
struct_field,
switch_case,
// TODO Abort, don't list any enums
// - lhs of `=` is a fn call
// - able to resolve the type of a switch condition, but it is a struct
Expand Down Expand Up @@ -1179,7 +1180,7 @@ fn getSwitchOrStructInitContext(
if (parens_depth == one_opening)
switch (token_tags[token_index - 1]) {
.keyword_switch => {
likely = .enum_literal;
likely = .switch_case;
upper_index -= 1; // eat the switch's .r_paren
break :find_identifier;
},
Expand Down Expand Up @@ -1244,7 +1245,7 @@ pub fn collectContainerFields(
for (container_decl.ast.members) |member| {
const field = handle.tree.fullContainerField(member) orelse continue;
const name = handle.tree.tokenSlice(field.ast.main_token);
if (likely != .struct_field and likely != .enum_comparison and !field.ast.tuple_like) {
if (likely != .struct_field and likely != .enum_comparison and likely != .switch_case and !field.ast.tuple_like) {
try builder.completions.append(builder.arena, .{
.label = name,
.kind = if (field.ast.tuple_like) .EnumMember else .Field,
Expand All @@ -1259,7 +1260,7 @@ pub fn collectContainerFields(
.label = name,
.kind = if (field.ast.tuple_like) .EnumMember else .Field,
.detail = Analyser.getContainerFieldSignature(handle.tree, field),
.insertText = if (field.ast.tuple_like or likely == .enum_comparison)
.insertText = if (field.ast.tuple_like or likely == .enum_comparison or likely == .switch_case)
name
else
try std.fmt.allocPrint(builder.arena, "{s} = ", .{name}),
Expand Down
17 changes: 17 additions & 0 deletions tests/lsp_features/completion.zig
Original file line number Diff line number Diff line change
Expand Up @@ -2884,6 +2884,23 @@ test "insert replace behaviour - tagged union" {
.expected_insert_line = "const boolean = u == .alpha",
.expected_replace_line = "const boolean = u == .alpha",
});
try testCompletionTextEdit(.{
.source =
\\const E = union(enum) {
\\ foo: []const u8,
\\ bar,
\\};
\\
\\test {
\\ var e: E = undefined;
\\ switch (e) {.<cursor>}
\\}
,
.label = "foo",
.expected_insert_line = " switch (e) {.foo}",
.expected_replace_line = " switch (e) {.foo}",
.enable_snippets = true,
});
}

test "insert replace behaviour - doc test name" {
Expand Down

0 comments on commit 80ddf7b

Please sign in to comment.