Skip to content

Commit b0566e5

Browse files
akinomyogayedayak
andcommitted
fix(java,rsync,ssh): complete syntactically incomplete cur
#1255 (comment) Co-authored-by: Yedaya Katsman <[email protected]>
1 parent e4dfaaa commit b0566e5

File tree

6 files changed

+58
-5
lines changed

6 files changed

+58
-5
lines changed

bash_completion

+22
Original file line numberDiff line numberDiff line change
@@ -251,6 +251,28 @@ _comp_dequote()
251251
fi
252252
}
253253

254+
# Try to reconstruct an incomplete word and apply _comp_dequote.
255+
# @param $1 String to be expanded. The same as _comp_dequote, but
256+
# incomplete backslash, single quotation, and double quotation
257+
# are allowed.
258+
# @var[out] REPLY Result. The same as _comp_dequote.
259+
# @since 2.17
260+
_comp_dequote_incomplete()
261+
{
262+
local _word=${1-}
263+
if ! [[ $_word =~ $_comp_dequote__regex_safe_word ]]; then
264+
# shellcheck disable=SC1003
265+
if [[ ${_word%'\'} =~ $_comp_dequote__regex_safe_word ]]; then
266+
_word=${_word%'\'}
267+
elif [[ $_word\' =~ $_comp_dequote__regex_safe_word ]]; then
268+
_word=$_word\'
269+
elif [[ $_word\" =~ $_comp_dequote__regex_safe_word ]]; then
270+
_word=$_word\"
271+
fi
272+
fi
273+
_comp_dequote "$_word"
274+
}
275+
254276
# Unset the given variables across a scope boundary. Useful for unshadowing
255277
# global scoped variables. Note that simply calling unset on a local variable
256278
# will not unshadow the global variable. Rather, the result will be a local

completions/java

+1-1
Original file line numberDiff line numberDiff line change
@@ -114,7 +114,7 @@ _comp_cmd_java__packages()
114114
local -a sourcepaths=("${REPLY[@]}")
115115

116116
local REPLY
117-
_comp_dequote "$cur"
117+
_comp_dequote_incomplete "$cur"
118118
local cur_val=${REPLY-}
119119

120120
# convert package syntax to path syntax

completions/ssh

+2-2
Original file line numberDiff line numberDiff line change
@@ -534,7 +534,7 @@ _comp_xfunc_scp_compgen_remote_files()
534534
# unescape (3 backslashes to 1 for chars we escaped)
535535
REPLY=$(command sed -e 's/\\\\\\\('"$_comp_cmd_scp__path_esc"'\)/\\\1/g' <<<"$REPLY")
536536
fi
537-
_comp_dequote "$REPLY"
537+
_comp_dequote_incomplete "$REPLY"
538538
local cur_val=${REPLY-}
539539

540540
local _userhost=${cur_val%%:*}
@@ -577,7 +577,7 @@ _comp_xfunc_scp_compgen_local_files()
577577
fi
578578

579579
local REPLY
580-
_comp_dequote "$cur"
580+
_comp_dequote_incomplete "$cur"
581581
local cur_val=${REPLY-}
582582

583583
local files

test/fixtures/scp/local_path/backslash-a b.txt

Whitespace-only changes.

test/fixtures/scp/local_path/backslash-a\ b.txt

Whitespace-only changes.

test/t/test_scp.py

+33-2
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,13 @@ def test_basic(self, hosts, completion):
2828
)
2929
),
3030
# Local filenames
31-
["bin/", "config", "known_hosts", r"spaced\ \ conf"],
31+
[
32+
"bin/",
33+
"config",
34+
"known_hosts",
35+
"local_path/",
36+
r"spaced\ \ conf",
37+
],
3238
)
3339
)
3440
assert completion == expected
@@ -48,7 +54,13 @@ def test_basic_spaced_conf(self, hosts, completion):
4854
)
4955
),
5056
# Local filenames
51-
["bin/", "config", "known_hosts", r"spaced\ \ conf"],
57+
[
58+
"bin/",
59+
"config",
60+
"known_hosts",
61+
"local_path/",
62+
r"spaced\ \ conf",
63+
],
5264
)
5365
)
5466
assert completion == expected
@@ -115,6 +127,19 @@ def test_remote_path_with_spaces(self, bash):
115127
assert_bash_exec(bash, "unset -f ssh")
116128
assert completion == r"\\\ in\\\ filename.txt"
117129

130+
def test_remote_path_with_backslash(self, bash):
131+
assert_bash_exec(
132+
bash, "ssh() { printf '%s\\n' 'abc def.txt' 'abc\ def.txt'; }"
133+
)
134+
completion = assert_complete(bash, "scp remote_host:abc\\")
135+
assert_bash_exec(bash, "unset -f ssh")
136+
137+
# Note: The number of backslash escaping differs depending on the scp
138+
# version.
139+
assert completion == sorted(
140+
[r"abc\ def.txt", r"abc\\\ def.txt"]
141+
) or completion == sorted([r"abc\\\ def.txt", r"abc\\\\\\\ def.txt"])
142+
118143
def test_xfunc_remote_files(self, bash):
119144
with bash_env_saved(bash) as bash_env:
120145
bash_env.save_variable("COMPREPLY")
@@ -193,3 +218,9 @@ def test_local_path_with_spaces_1(self, completion):
193218
@pytest.mark.complete("scp spaced\\ ", cwd="scp")
194219
def test_local_path_with_spaces_2(self, completion):
195220
assert completion == "\\ conf"
221+
222+
@pytest.mark.complete("scp backslash-a\\", cwd="scp/local_path")
223+
def test_local_path_backslash(self, completion):
224+
assert completion == sorted(
225+
[r"backslash-a\ b.txt", r"backslash-a\\\ b.txt"]
226+
)

0 commit comments

Comments
 (0)