diff --git a/src/features/completions.zig b/src/features/completions.zig index 2eadc383b..8dd0d6601 100644 --- a/src/features/completions.zig +++ b/src/features/completions.zig @@ -487,7 +487,6 @@ fn prepareCompletionLoc(tree: *const Ast, source_index: usize) offsets.Loc { std.debug.assert(token_loc.start <= source_index and source_index <= token_loc.end); return offsets.identifierIndexToLoc(tree.source, token_loc.start, if (tag == .builtin) .name else .full); }, - .colon => return fallback_loc, else => { const token_start = tree.tokenStart(token); @@ -498,6 +497,8 @@ fn prepareCompletionLoc(tree: *const Ast, source_index: usize) offsets.Loc { if (token_start + 1 < source_index) return fallback_loc; break :start .{ token_start + 1, token_start + 1 }; } else { + if (!offsets.isSymbolChar(tree.source[token_start])) + return fallback_loc; break :start .{ token_start, token_start }; } }; diff --git a/tests/lsp_features/completion.zig b/tests/lsp_features/completion.zig index c1cdea388..274f3c73f 100644 --- a/tests/lsp_features/completion.zig +++ b/tests/lsp_features/completion.zig @@ -4348,6 +4348,36 @@ test "doctest name" { }); } +test "completions don't replace punctuation" { + try testCompletionTextEdit(.{ + .source = + \\const foo = 0; + \\const bar = foo[]; + , + .label = "foo", + .expected_insert_line = "const bar = foo[foo];", + .expected_replace_line = "const bar = foo[foo];", + }); + try testCompletionTextEdit(.{ + .source = + \\const foo = 0; + \\const bar = foo(); + , + .label = "foo", + .expected_insert_line = "const bar = foo(foo);", + .expected_replace_line = "const bar = foo(foo);", + }); + try testCompletionTextEdit(.{ + .source = + \\const foo = 0; + \\const bar = foo{}; + , + .label = "foo", + .expected_insert_line = "const bar = foo{foo};", + .expected_replace_line = "const bar = foo{foo};", + }); +} + fn testCompletion(source: []const u8, expected_completions: []const Completion) !void { try testCompletionWithOptions(source, expected_completions, .{}); }