Skip to content

Commit 0662166

Browse files
pfitzsebKristofferC
authored andcommitted
Improve REPL completions (#30569)
* fix internal repl completion error * fix error with broadcast method completions * method completions for broadcasted functioncalls * better broadcast funcall completions (cherry picked from commit a0474d7)
1 parent efcd50f commit 0662166

File tree

2 files changed

+41
-8
lines changed

2 files changed

+41
-8
lines changed

stdlib/REPL/src/REPLCompletions.jl

Lines changed: 23 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -353,7 +353,7 @@ get_value(sym, fn) = (sym, true)
353353
function get_value_getfield(ex::Expr, fn)
354354
# Example :((top(getfield))(Base,:max))
355355
val, found = get_value_getfield(ex.args[2],fn) #Look up Base in Main and returns the module
356-
found || return (nothing, false)
356+
(found && length(ex.args) >= 3) || return (nothing, false)
357357
return get_value_getfield(ex.args[3], val) #Look up max in Base and returns the function if found.
358358
end
359359
get_value_getfield(sym, fn) = get_value(sym, fn)
@@ -407,7 +407,7 @@ function try_get_type(sym::Expr, fn::Module)
407407
elseif sym.head === :ref
408408
# some simple cases of `expand`
409409
return try_get_type(Expr(:call, GlobalRef(Base, :getindex), sym.args...), fn)
410-
elseif sym.head === :.
410+
elseif sym.head === :. && sym.args[2] isa QuoteNode # second check catches broadcasting
411411
return try_get_type(Expr(:call, GlobalRef(Core, :getfield), sym.args...), fn)
412412
end
413413
return (Any, false)
@@ -432,10 +432,21 @@ function complete_methods(ex_org::Expr, context_module=Main)::Vector{Completion}
432432
args_ex = Any[]
433433
func, found = get_value(ex_org.args[1], context_module)
434434
!found && return Completion[]
435-
for ex in ex_org.args[2:end]
436-
val, found = get_type(ex, context_module)
437-
push!(args_ex, val)
435+
436+
funargs = ex_org.args[2:end]
437+
# handle broadcasting, but only handle number of arguments instead of
438+
# argument types
439+
if ex_org.head === :. && ex_org.args[2] isa Expr
440+
for _ in ex_org.args[2].args
441+
push!(args_ex, Any)
442+
end
443+
else
444+
for ex in funargs
445+
val, found = get_type(ex, context_module)
446+
push!(args_ex, val)
447+
end
438448
end
449+
439450
out = Completion[]
440451
t_in = Tuple{Core.Typeof(func), args_ex...} # Input types
441452
na = length(args_ex)+1
@@ -610,12 +621,16 @@ function completions(string, pos, context_module=Main)::Completions
610621

611622
# Make sure that only bslash_completions is working on strings
612623
inc_tag==:string && return String[], 0:-1, false
613-
614624
if inc_tag == :other && should_method_complete(partial)
615625
frange, method_name_end = find_start_brace(partial)
616626
ex = Meta.parse(partial[frange] * ")", raise=false, depwarn=false)
617-
if isa(ex, Expr) && ex.head==:call
618-
return complete_methods(ex, context_module), first(frange):method_name_end, false
627+
628+
if isa(ex, Expr)
629+
if ex.head==:call
630+
return complete_methods(ex, context_module), first(frange):method_name_end, false
631+
elseif ex.head==:. && ex.args[2] isa Expr && ex.args[2].head==:tuple
632+
return complete_methods(ex, context_module), first(frange):(method_name_end - 1), false
633+
end
619634
end
620635
elseif inc_tag == :comment
621636
return Completion[], 0:-1, false

stdlib/REPL/test/replcompletions.jl

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -960,6 +960,16 @@ let s = "type_test.xx.y"
960960
@test s[r] == "y"
961961
end
962962

963+
let s = ":(function foo(::Int) end).args[1].args[2]."
964+
c, r = test_complete_context(s)
965+
@test c == Any[]
966+
end
967+
968+
let s = "log(log.(x),"
969+
c, r = test_complete_context(s)
970+
@test !isempty(c)
971+
end
972+
963973
let s = "Base.return_types(getin"
964974
c, r = test_complete_context(s)
965975
@test "getindex" in c
@@ -981,6 +991,14 @@ let s = "test(1,1, "
981991
@test s[r] == "test"
982992
end
983993

994+
let s = "test.(1,1, "
995+
c, r, res = test_complete_context(s)
996+
@test !res
997+
@test length(c) == 4
998+
@test r == 1:4
999+
@test s[r] == "test"
1000+
end
1001+
9841002
let s = "prevind(\"θ\",1,"
9851003
c, r, res = test_complete_context(s)
9861004
@test c[1] == string(first(methods(prevind, Tuple{String, Int})))

0 commit comments

Comments
 (0)