Skip to content

Commit

Permalink
REPL: fix closing quote on completing files in a ~ path (#56253)
Browse files Browse the repository at this point in the history
(cherry picked from commit 133051f)
  • Loading branch information
IanButterworth committed Oct 24, 2024
1 parent 7b3408e commit 70f87db
Show file tree
Hide file tree
Showing 2 changed files with 33 additions and 12 deletions.
18 changes: 7 additions & 11 deletions stdlib/REPL/src/REPLCompletions.jl
Original file line number Diff line number Diff line change
Expand Up @@ -899,17 +899,11 @@ function afterusing(string::String, startpos::Int)
return occursin(r"^\b(using|import)\s*((\w+[.])*\w+\s*,\s*)*$", str[fr:end])
end

function close_path_completion(dir, paths, str, pos)
length(paths) == 1 || return false # Only close if there's a single choice...
path = (paths[1]::PathCompletion).path
function close_path_completion(dir, path, str, pos)
path = unescape_string(replace(path, "\\\$"=>"\$"))
path = joinpath(dir, path)
# ...except if it's a directory...
try
isdir(path)
catch e
e isa Base.IOError || rethrow() # `path` cannot be determined to be a file
end && return false
Base.isaccessibledir(path) && return false
# ...and except if there's already a " at the cursor.
return lastindex(str) <= pos || str[nextind(str, pos)] != '"'
end
Expand Down Expand Up @@ -1308,10 +1302,12 @@ function completions(string::String, pos::Int, context_module::Module=Main, shif
if !isnothing(path)
paths, dir, success = complete_path(path::String, string_escape=true)

if close_path_completion(dir, paths, path, pos)
p = (paths[1]::PathCompletion).path * "\""
if length(paths) == 1
p = (paths[1]::PathCompletion).path
hint && was_expanded && (p = contractuser(p))
paths[1] = PathCompletion(p)
if close_path_completion(dir, p, path, pos)
paths[1] = PathCompletion(p * "\"")
end
end

if success && !isempty(dir)
Expand Down
27 changes: 26 additions & 1 deletion stdlib/REPL/test/replcompletions.jl
Original file line number Diff line number Diff line change
Expand Up @@ -1223,7 +1223,7 @@ let current_dir, forbidden
e isa Base.IOError && occursin("ELOOP", e.msg)
end
c, r = test_complete("\"$(escape_string(path))/selfsym")
@test c == ["selfsymlink"]
@test c == ["selfsymlink\""]
end
end

Expand Down Expand Up @@ -1344,6 +1344,31 @@ let (c, r, res) = test_complete("\"~/julia")
c, r, res = test_complete("\"foo~bar")
@test !res
end
if !Sys.iswindows()
# create a dir and file temporarily in the home directory
path = mkpath(joinpath(homedir(), "Zx6Wa0GkC0"))
touch(joinpath(path, "my_file"))
try
let (c, r, res) = test_complete("\"~/Zx6Wa0GkC")
@test res
@test c == String["Zx6Wa0GkC0/"]
end
let (c, r, res) = test_complete("\"~/Zx6Wa0GkC0")
@test res
@test c == String[homedir() * "/Zx6Wa0GkC0"]
end
let (c, r, res) = test_complete("\"~/Zx6Wa0GkC0/my_")
@test res
@test c == String["my_file\""]
end
let (c, r, res) = test_complete("\"~/Zx6Wa0GkC0/my_file")
@test res
@test c == String[homedir() * "/Zx6Wa0GkC0/my_file"]
end
finally
rm(path, recursive=true)
end
end

# Test the completion returns nothing when the folder do not exist
let (c, r) = test_complete("cd(\"folder_do_not_exist_77/file")
Expand Down

0 comments on commit 70f87db

Please sign in to comment.