Skip to content

Commit 9e75960

Browse files
authored
fix string completion with cursor in the middle of text (#60082)
1 parent d8b5662 commit 9e75960

File tree

2 files changed

+40
-1
lines changed

2 files changed

+40
-1
lines changed

stdlib/REPL/src/REPLCompletions.jl

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1047,7 +1047,7 @@ function completions(string::String, pos::Int, context_module::Module=Main, shif
10471047
# "~/example.txt TAB => "/home/user/example.txt"
10481048
r, closed = find_str(cur)
10491049
if r !== nothing
1050-
s = do_string_unescape(string[r])
1050+
s = do_string_unescape(string[intersect(r, 1:pos)])
10511051
ret, success = complete_path_string(s, hint; string_escape=true,
10521052
dirsep=Sys.iswindows() ? '\\' : '/')
10531053
if length(ret) == 1 && !closed && close_path_completion(ret[1].path)

stdlib/REPL/test/replcompletions.jl

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1458,6 +1458,45 @@ let (c, r) = test_complete("cd(\"folder_do_not_exist_77/file")
14581458
@test length(c) == 0
14591459
end
14601460

1461+
# Test path completion in the middle of a line (issue #60050)
1462+
mktempdir() do path
1463+
# Create test directory structure
1464+
foo_dir = joinpath(path, "foo_dir")
1465+
mkpath(foo_dir)
1466+
touch(joinpath(path, "foo_file.txt"))
1467+
1468+
# On Windows, use backslashes; on Unix, use forward slashes
1469+
sep = Sys.iswindows() ? "\\\\" : "/"
1470+
# On Windows, completion results have escaped backslashes
1471+
path_expected = Sys.iswindows() ? replace(path, "\\" => "\\\\") : path
1472+
1473+
# Completion at end of line should work
1474+
let (c, r, res) = test_complete("\"$(path)$(sep)foo")
1475+
@test res
1476+
@test length(c) == 2
1477+
@test "$(path_expected)$(sep)foo_dir$(sep)" in c
1478+
@test "$(path_expected)$(sep)foo_file.txt" in c
1479+
end
1480+
1481+
# Completion in middle of line should also work (regression in 1.12)
1482+
let (c, r, res) = test_complete_pos("\"$(path)$(sep)foo|$(sep)bar.toml\"")
1483+
@test res
1484+
@test length(c) == 2
1485+
@test "$(path_expected)$(sep)foo_dir$(sep)" in c
1486+
@test "$(path_expected)$(sep)foo_file.txt" in c
1487+
# Check that the range covers only the part before the cursor
1488+
@test findfirst("$(sep)bar", "\"$(path)$(sep)foo$(sep)bar.toml\"")[1] - 1 in r
1489+
end
1490+
1491+
# Completion in middle of function call with trailing arguments
1492+
let (c, r, res) = test_complete_pos("run_something(\"$(path)$(sep)foo|$(sep)bar.toml\"; kwarg=true)")
1493+
@test res
1494+
@test length(c) == 2
1495+
@test "$(path_expected)$(sep)foo_dir$(sep)" in c
1496+
@test "$(path_expected)$(sep)foo_file.txt" in c
1497+
end
1498+
end
1499+
14611500
if Sys.iswindows()
14621501
tmp = tempname()
14631502
touch(tmp)

0 commit comments

Comments
 (0)