diff --git a/stdlib/REPL/src/REPLCompletions.jl b/stdlib/REPL/src/REPLCompletions.jl index c5e3ced9dfb01..9edb6d9e56ccd 100644 --- a/stdlib/REPL/src/REPLCompletions.jl +++ b/stdlib/REPL/src/REPLCompletions.jl @@ -530,14 +530,11 @@ function dict_identifier_key(str,tag) sym = Symbol(name) isdefined(obj, sym) || return (nothing, nothing, nothing) obj = getfield(obj, sym) - # Avoid `isdefined(::Array, ::Symbol)` - isa(obj, Array) && return (nothing, nothing, nothing) end - begin_of_key = first(something(findnext(r"\S", str, nextind(str, end_of_identifier) + 1), 1)) # 1 for [ - begin_of_key==0 && return (true, nothing, nothing) - partial_key = str[begin_of_key:end] - (isa(obj, AbstractDict) && length(obj) < 1e6) || return (true, nothing, nothing) - return (obj, partial_key, begin_of_key) + (isa(obj, AbstractDict) && length(obj) < 1_000_000) || return (nothing, nothing, nothing) + begin_of_key = something(findnext(!isspace, str, nextind(str, end_of_identifier) + 1), # +1 for [ + lastindex(str)+1) + return (obj, str[begin_of_key:end], begin_of_key) end # This needs to be a separate non-inlined function, see #19441 @@ -581,13 +578,9 @@ function completions(string, pos, context_module=Main)::Completions # if completing a key in a Dict identifier, partial_key, loc = dict_identifier_key(partial,inc_tag) if identifier !== nothing - if partial_key !== nothing - matches = find_dict_matches(identifier, partial_key) - length(matches)==1 && (length(string) <= pos || string[pos+1] != ']') && (matches[1]*="]") - length(matches)>0 && return [DictCompletion(identifier, match) for match in sort!(matches)], loc:pos, true - else - return Completion[], 0:-1, false - end + matches = find_dict_matches(identifier, partial_key) + length(matches)==1 && (lastindex(string) <= pos || string[nextind(string,pos)] != ']') && (matches[1]*=']') + length(matches)>0 && return [DictCompletion(identifier, match) for match in sort!(matches)], loc:pos, true end # otherwise... @@ -605,7 +598,7 @@ function completions(string, pos, context_module=Main)::Completions length(paths) == 1 && # Only close if there's a single choice, !isdir(expanduser(replace(string[startpos:prevind(string, first(r))] * paths[1].path, r"\\ " => " "))) && # except if it's a directory - (length(string) <= pos || + (lastindex(string) <= pos || string[nextind(string,pos)] != '"') # or there's already a " at the cursor. paths[1] = PathCompletion(paths[1].path * "\"") end diff --git a/stdlib/REPL/test/replcompletions.jl b/stdlib/REPL/test/replcompletions.jl index eb19f8d60097b..5f3d9e9e57c19 100644 --- a/stdlib/REPL/test/replcompletions.jl +++ b/stdlib/REPL/test/replcompletions.jl @@ -266,6 +266,14 @@ let s = "\"C:\\\\ \\alpha" @test length(c) == 1 end +# test latex symbol completion in getindex expressions (#24705) +let s = "tuple[\\alpha" + c, r, res = test_complete_context(s) + @test c[1] == "α" + @test r == 7:12 + @test length(c) == 1 +end + let s = "\\a" c, r, res = test_complete(s) "\\alpha" in c @@ -863,7 +871,7 @@ function test_dict_completion(dict_name) @test c == Any[":α]"] s = "$dict_name[" c, r = test_complete(s) - @test !isempty(c) + @test c == sort!(repr.(keys(Main.CompletionFoo.test_dict))) end test_dict_completion("CompletionFoo.test_dict") test_dict_completion("CompletionFoo.test_customdict")