Skip to content

Commit f3f0da9

Browse files
committed
Make sure commands suggested in REPL shell mode are unique
Often binaries are in the env path more than once, but we obviously only want to suggest them once to the user.
1 parent 2daa2d3 commit f3f0da9

File tree

2 files changed

+30
-6
lines changed

2 files changed

+30
-6
lines changed

base/REPLCompletions.jl

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -133,12 +133,12 @@ function complete_path(path::AbstractString, pos; use_envpath=false)
133133
return UTF8String[], 0:-1, false
134134
end
135135

136-
matches = UTF8String[]
136+
matches = Dict{UTF8String,Bool}()
137137
for file in files
138138
if startswith(file, prefix)
139139
id = try isdir(joinpath(dir, file)) catch; false end
140140
# joinpath is not used because windows needs to complete with double-backslash
141-
push!(matches, id ? file * (@windows? "\\\\" : "/") : file)
141+
matches[id ? file * (@windows? "\\\\" : "/") : file] = true
142142
end
143143
end
144144

@@ -178,18 +178,18 @@ function complete_path(path::AbstractString, pos; use_envpath=false)
178178
# In a perfect world, we would filter on whether the file is executable
179179
# here, or even on whether the current user can execute the file in question.
180180
if startswith(file, prefix) && isfile(joinpath(pathdir, file))
181-
push!(matches, file)
181+
matches[file] = true
182182
end
183183
end
184184
end
185185
end
186186

187-
matches = UTF8String[replace(s, r"\s", "\\ ") for s in matches]
187+
matchList = UTF8String[replace(s, r"\s", "\\ ") for s in keys(matches)]
188188
startpos = pos - endof(prefix) + 1 - length(matchall(r" ", prefix))
189189
# The pos - endof(prefix) + 1 is correct due to `endof(prefix)-endof(prefix)==0`,
190190
# hence we need to add one to get the first index. This is also correct when considering
191191
# pos, because pos is the `endof` a larger string which `endswith(path)==true`.
192-
return matches, startpos:pos, !isempty(matches)
192+
return matchList, startpos:pos, !isempty(matchList)
193193
end
194194

195195
# Determines whether method_complete should be tried. It should only be done if

test/replcompletions.jl

Lines changed: 25 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -434,7 +434,6 @@ c, r, res = test_scomplete(s)
434434
# Pressing tab after having entered "/tmp " should not
435435
# attempt to complete "/tmp" but rather work on the current
436436
# working directory again.
437-
438437
let
439438
file = joinpath(path, "repl completions")
440439
s = "/tmp "
@@ -494,6 +493,31 @@ c, r, res = test_scomplete(s)
494493
ENV["PATH"] = oldpath
495494
end
496495

496+
# Make sure completion results are unique in case things are in the env path twice.
497+
let
498+
file0 = joinpath(tempdir(), "repl-completion")
499+
dir = joinpath(tempdir(), "repl-completion-subdir")
500+
file1 = joinpath(dir, "repl-completion")
501+
502+
try
503+
# Create /tmp/repl-completion and /tmp/repl-completion-subdir/repl-completion
504+
mkdir(dir)
505+
touch(file0)
506+
touch(file1)
507+
508+
withenv("PATH" => string(tempdir(), ":", dir)) do
509+
s = string("repl-completio")
510+
c,r = test_scomplete(s)
511+
@test [utf8("repl-completion")] == c
512+
@test s[r] == "repl-completio"
513+
end
514+
515+
finally
516+
rm(file0)
517+
rm(file1)
518+
rm(dir)
519+
end
520+
end
497521
end
498522

499523
let #test that it can auto complete with spaces in file/path

0 commit comments

Comments
 (0)