Skip to content

Commit

Permalink
Fix Dict key completion for qualified names.
Browse files Browse the repository at this point in the history
  • Loading branch information
yuyichao committed Jul 16, 2016
1 parent 1fd440e commit 2d973d0
Show file tree
Hide file tree
Showing 2 changed files with 76 additions and 64 deletions.
22 changes: 14 additions & 8 deletions base/REPLCompletions.jl
Original file line number Diff line number Diff line change
Expand Up @@ -397,14 +397,20 @@ function dict_identifier_key(str,tag)

frange, end_of_indentifier = find_start_brace(str_close, c_start='[', c_end=']')
isempty(frange) && return (nothing, nothing, nothing)
identifier = Symbol(str[frange[1]:end_of_indentifier])
isdefined(Main,identifier) || return (nothing, nothing, nothing)
obj = Main
for name in split(str[frange[1]:end_of_indentifier], '.')
Base.isidentifier(name) || return (nothing, nothing, nothing)
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 = findnext(x->!in(x,whitespace_chars), str, end_of_indentifier+2)
begin_of_key==0 && return (identifier, nothing, nothing)
begin_of_key==0 && return (true, nothing, nothing)
partial_key = str[begin_of_key:end]
main_id = getfield(Main,identifier)
typeof(main_id) <: Associative && length(main_id)<1e6 || return (identifier, nothing, nothing)
main_id, partial_key, begin_of_key
(isa(obj, Associative) && length(obj) < 1e6) || return (true, nothing, nothing)
return (obj, partial_key, begin_of_key)
end

function completions(string, pos)
Expand All @@ -416,8 +422,8 @@ function completions(string, pos)

# if completing a key in a Dict
identifier, partial_key, loc = dict_identifier_key(partial,inc_tag)
if identifier != nothing
if partial_key != nothing
if identifier !== nothing
if partial_key !== nothing
matches = []
for key in keys(identifier)
rkey = repr(key)
Expand Down
118 changes: 62 additions & 56 deletions test/replcompletions.jl
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,11 @@ module CompletionFoo
const tuple = (1, 2)

test_y_array=[CompletionFoo.Test_y(rand()) for i in 1:10]
test_dict = Dict("abc"=>1, "abcd"=>10, :bar=>2, :bar2=>9, Base=>3,
contains=>4, `ls`=>5, 66=>7, 67=>8, ("q",3)=>11,
"α"=>12, =>13)
end
test_repl_comp_dict = CompletionFoo.test_dict

function temp_pkg_dir(fn::Function)
# Used in tests below to setup and teardown a sandboxed package directory
Expand Down Expand Up @@ -663,59 +667,61 @@ c, r, res = test_complete(s)
@test isempty(c)

# test Dicts
test_dict = Dict("abc"=>1, "abcd"=>10, :bar=>2, :bar2=>9, Base=>3, contains=>4, `ls`=>5,
66=>7, 67=>8, ("q",3)=>11, "α"=>12, =>13)
s="test_dict[\"ab"
c,r = test_complete(s)
@test c == Any["\"abc\"","\"abcd\""]
s="test_dict[\"abcd"
c,r = test_complete(s)
@test c == Any["\"abcd\"]"]
s="test_dict[ \"abcd" # leading whitespace
c,r = test_complete(s)
@test c == Any["\"abcd\"]"]
s="test_dict[\"abcd]" # trailing close bracket
c,r = completions(s,endof(s)-1)
@test c == Any["\"abcd\""]
s="test_dict[:b"
c,r = test_complete(s)
@test c == Any[":bar",":bar2"]
s="test_dict[:bar2"
c,r = test_complete(s)
@test c == Any[":bar2]"]
s="test_dict[Ba"
c,r = test_complete(s)
@test c == Any["Base]"]
s="test_dict[co"
c,r = test_complete(s)
@test c == Any["contains]"]
s="test_dict[`l"
c,r = test_complete(s)
@test c == Any["`ls`]"]
s="test_dict[6"
c,r = test_complete(s)
@test c == Any["66","67"]
s="test_dict[66"
c,r = test_complete(s)
@test c == Any["66]"]
s="test_dict[("
c,r = test_complete(s)
@test c == Any["(\"q\",3)]"]
s="test_dict[\"\\alp"
c,r = test_complete(s)
@test c == String["\\alpha"]
s="test_dict[\"\\alpha"
c,r = test_complete(s)
@test c == String["α"]
s="test_dict[\"α"
c,r = test_complete(s)
@test c == Any["\"α\"]"]
s="test_dict[:\\alp"
c,r = test_complete(s)
@test c == String["\\alpha"]
s="test_dict[:\\alpha"
c,r = test_complete(s)
@test c == String["α"]
s="test_dict[:α"
c,r = test_complete(s)
@test c == Any[":α]"]
function test_dict_completion(dict_name)
s = "$dict_name[\"ab"
c, r = test_complete(s)
@test c == Any["\"abc\"", "\"abcd\""]
s = "$dict_name[\"abcd"
c, r = test_complete(s)
@test c == Any["\"abcd\"]"]
s = "$dict_name[ \"abcd" # leading whitespace
c, r = test_complete(s)
@test c == Any["\"abcd\"]"]
s = "$dict_name[\"abcd]" # trailing close bracket
c, r = completions(s, endof(s) - 1)
@test c == Any["\"abcd\""]
s = "$dict_name[:b"
c, r = test_complete(s)
@test c == Any[":bar", ":bar2"]
s = "$dict_name[:bar2"
c, r = test_complete(s)
@test c == Any[":bar2]"]
s = "$dict_name[Ba"
c, r = test_complete(s)
@test c == Any["Base]"]
s = "$dict_name[co"
c, r = test_complete(s)
@test c == Any["contains]"]
s = "$dict_name[`l"
c, r = test_complete(s)
@test c == Any["`ls`]"]
s = "$dict_name[6"
c, r = test_complete(s)
@test c == Any["66", "67"]
s = "$dict_name[66"
c, r = test_complete(s)
@test c == Any["66]"]
s = "$dict_name[("
c, r = test_complete(s)
@test c == Any["(\"q\",3)]"]
s = "$dict_name[\"\\alp"
c, r = test_complete(s)
@test c == String["\\alpha"]
s = "$dict_name[\"\\alpha"
c, r = test_complete(s)
@test c == String["α"]
s = "$dict_name[\"α"
c, r = test_complete(s)
@test c == Any["\"α\"]"]
s = "$dict_name[:\\alp"
c, r = test_complete(s)
@test c == String["\\alpha"]
s = "$dict_name[:\\alpha"
c, r = test_complete(s)
@test c == String["α"]
s = "$dict_name[:α"
c, r = test_complete(s)
@test c == Any[":α]"]
end
test_dict_completion("CompletionFoo.test_dict")
test_dict_completion("test_repl_comp_dict")

0 comments on commit 2d973d0

Please sign in to comment.