From cad50369b0756958e826d7e964b1a3b7ed1504d5 Mon Sep 17 00:00:00 2001 From: Brad Lewis <22850972+BradLewis@users.noreply.github.com> Date: Sat, 20 Sep 2025 08:50:19 -0400 Subject: Check to see if completion already includes `&` before adding it when matching --- src/server/completion.odin | 28 +++++++++++++++++++++++++--- src/server/position_context.odin | 6 ++++++ tests/completions_test.odin | 40 ++++++++++++++++++++++++++++++++++++++++ 3 files changed, 71 insertions(+), 3 deletions(-) diff --git a/src/server/completion.odin b/src/server/completion.odin index aceff60..38b5cbe 100644 --- a/src/server/completion.odin +++ b/src/server/completion.odin @@ -237,7 +237,7 @@ convert_completion_results :: proc( position_context: ^DocumentPositionContext, results: []CompletionResult, completion_type: Completion_Type, - symbol: Maybe(Symbol), + target_symbol: Maybe(Symbol), config: ^common.Config, ) -> []CompletionItem { for &result in results { @@ -334,7 +334,7 @@ convert_completion_results :: proc( } if config.enable_completion_matching { - if s, ok := symbol.(Symbol); ok && (completion_type == .Selector || completion_type == .Identifier) { + if s, ok := target_symbol.(Symbol); ok && (completion_type == .Selector || completion_type == .Identifier) { handle_matching(ast_context, position_context, result.symbol, s, &item, completion_type) } } @@ -431,6 +431,12 @@ handle_matching :: proc( return false } + if r, ok := result_symbol.value.(SymbolBasicValue); ok { + if a, ok := arg_symbol.value.(SymbolBasicValue); ok { + return r.ident.name != a.ident.name + } + } + if _, ok := arg_symbol.value.(SymbolSliceValue); ok { if _, ok := result_symbol.value.(SymbolDynamicArrayValue); ok { return false @@ -456,6 +462,21 @@ handle_matching :: proc( return false } + contains_unary :: proc(arg: ^ast.Expr) -> bool { + if arg == nil { + return false + } + + #partial switch n in arg.derived { + case ^ast.Unary_Expr: + return true + case ^ast.Field_Value: + return contains_unary(n.value) + } + + return false + } + if should_skip(arg_symbol, result_symbol) { return } @@ -473,7 +494,8 @@ handle_matching :: proc( if diff > 0 { suffix = repeat("^", diff, context.temp_allocator) } - if diff < 0 { + + if diff < 0 && !contains_unary(position_context.call_arg) { prefix = "&" } diff --git a/src/server/position_context.odin b/src/server/position_context.odin index f3f2f68..1aa2ec1 100644 --- a/src/server/position_context.odin +++ b/src/server/position_context.odin @@ -34,6 +34,7 @@ DocumentPositionContext :: struct { tag: ^ast.Node, field: ^ast.Expr, //used for completion call: ^ast.Expr, //used for signature help + call_arg: ^ast.Expr, //used for completion returns: ^ast.Return_Stmt, //used for completion comp_lit: ^ast.Comp_Lit, //used for completion parent_comp_lit: ^ast.Comp_Lit, //used for completion @@ -628,6 +629,11 @@ get_document_position_node :: proc(node: ^ast.Node, position_context: ^DocumentP case ^Call_Expr: position_context.call = n get_document_position(n.expr, position_context) + for arg in n.args { + if position_in_node(arg, position_context.position) { + position_context.call_arg = arg + } + } get_document_position(n.args, position_context) case ^Selector_Call_Expr: position_context.selector = n.expr diff --git a/tests/completions_test.odin b/tests/completions_test.odin index d3a2eb7..7b42568 100644 --- a/tests/completions_test.odin +++ b/tests/completions_test.odin @@ -4698,3 +4698,43 @@ ast_completion_struct_field_value :: proc(t: ^testing.T) { } test.expect_completion_docs(t, &source, "", {"test.Foo: struct {}"}) } + +@(test) +ast_completion_handle_matching_with_unary :: proc(t: ^testing.T) { + source := test.Source { + main = `package test + Foo :: struct{} + + do_foo :: proc(foo: ^Foo){} + + main :: proc() { + foo: Foo + do_foo(&f{*}) + } + `, + config = { + enable_completion_matching = true, + }, + } + test.expect_completion_insert_text(t, &source, "", {"foo"}) +} + +@(test) +ast_completion_handle_matching_field_with_unary :: proc(t: ^testing.T) { + source := test.Source { + main = `package test + Foo :: struct{} + + do_foo :: proc(foo: ^Foo){} + + main :: proc() { + foo: Foo + do_foo(foo = &f{*}) + } + `, + config = { + enable_completion_matching = true, + }, + } + test.expect_completion_insert_text(t, &source, "", {"foo"}) +} -- cgit v1.2.3