From 9d9932fc62f502c0e780d9dfffd2956ff393ed88 Mon Sep 17 00:00:00 2001 From: Sam Schweigel Date: Mon, 28 Jul 2025 16:37:53 -0700 Subject: [PATCH] [REPL] Fix keyword arguments completions with do block Fixes #58833. --- stdlib/REPL/src/REPLCompletions.jl | 9 +++++++++ stdlib/REPL/test/replcompletions.jl | 10 ++++++++++ 2 files changed, 19 insertions(+) diff --git a/stdlib/REPL/src/REPLCompletions.jl b/stdlib/REPL/src/REPLCompletions.jl index e05d0435d81d8..385d0fe720b46 100644 --- a/stdlib/REPL/src/REPLCompletions.jl +++ b/stdlib/REPL/src/REPLCompletions.jl @@ -692,6 +692,15 @@ code_typed(CC.typeinf, (REPLInterpreter, CC.InferenceState)) MAX_METHOD_COMPLETIONS::Int = 40 function _complete_methods(ex_org::Expr, context_module::Module, shift::Bool) isempty(ex_org.args) && return 2, nothing, [], Set{Symbol}() + # Desugar do block call into call with lambda + if ex_org.head === :do && length(ex_org.args) >= 2 + ex_call = ex_org.args[1] + ex_args = [x for x in ex_call.args if !(x isa Expr && x.head === :parameters)] + ex_params = findfirst(x -> x isa Expr && x.head === :parameters, ex_call.args) + new_args = [ex_args[1], ex_org.args[end], ex_args[2:end]...] + ex_params !== nothing && push!(new_args, ex_call.args[ex_params]) + ex_org = Expr(:call, new_args...) + end funct = repl_eval_ex(ex_org.args[1], context_module) funct === nothing && return 2, nothing, [], Set{Symbol}() funct = CC.widenconst(funct) diff --git a/stdlib/REPL/test/replcompletions.jl b/stdlib/REPL/test/replcompletions.jl index 2225417ddcec6..7b2b032af77d3 100644 --- a/stdlib/REPL/test/replcompletions.jl +++ b/stdlib/REPL/test/replcompletions.jl @@ -139,6 +139,7 @@ let ex = kwtest4(a::SubString; x23, _something) = pass kwtest5(a::Int, b, x...; somekwarg, somekotherkwarg) = pass kwtest5(a::Char, b; xyz) = pass + kwtest6(f::Function, arg1; somekwarg) = pass const named = (; len2=3) const fmsoebelkv = (; len2=3) @@ -198,6 +199,8 @@ test_scomplete(s) = map_completion_text(@inferred(shell_completions(s, lastinde test_complete_pos(s) = map_completion_text(@inferred(completions(replace(s, '|' => ""), findfirst('|', s)-1))) test_complete_context(s, m=@__MODULE__; shift::Bool=true) = map_completion_text(@inferred(completions(s,lastindex(s), m, shift))) +test_complete_context_pos(s, m=@__MODULE__; shift::Bool=true) = + map_completion_text(@inferred(completions(replace(s, '|' => ""), findfirst('|', s)-1, m, shift))) test_complete_foo(s; shift::Bool=true) = test_complete_context(s, Main.CompletionFoo; shift) test_complete_noshift(s) = map_completion_text(@inferred(completions(s, lastindex(s), Main, false))) @@ -2742,3 +2745,10 @@ let s = "for" @test "foreach" in c @test !("rand" in c) end + +# #58833 - Autocompletion of keyword arguments with do-blocks is broken +let s = "kwtest6(123; som|) do x; x + 3 end" + c, r = test_complete_context_pos(s, Main.CompletionFoo) + @test "somekwarg=" in c + @test r == 14:16 +end