Skip to content

Commit 397a49d

Browse files
authored
fix(python): complete filenames for script arguments (#1018)
1 parent 383756c commit 397a49d

File tree

4 files changed

+73
-11
lines changed

4 files changed

+73
-11
lines changed

completions/python

Lines changed: 34 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,38 @@ _comp_cmd_python()
4444
esac
4545

4646
local noargopts='!(-*|*[cmQWX]*)'
47+
48+
# if command, module, or script is already given by [-c command | -m module
49+
# | script], complete all kind of files.
50+
local i has_command=""
51+
for ((i = 1; i < cword; i++)); do
52+
# shellcheck disable=SC2254
53+
case ${words[i]} in
54+
-${noargopts}[QWX])
55+
((i++))
56+
;;
57+
-${noargopts}[cm]?*)
58+
has_command=set
59+
break
60+
;;
61+
-- | -${noargopts}[cm])
62+
if ((i + 1 < cword)); then
63+
has_command=set
64+
break
65+
fi
66+
;;
67+
-*) ;;
68+
*)
69+
has_command=set
70+
break
71+
;;
72+
esac
73+
done
74+
if [[ $has_command ]]; then
75+
_comp_compgen_filedir
76+
return
77+
fi
78+
4779
# shellcheck disable=SC2254
4880
case $prev in
4981
--help | --version | -${noargopts}[?hVc])
@@ -74,19 +106,10 @@ _comp_cmd_python()
74106
_comp_compgen -- -W "help off"
75107
return
76108
;;
77-
!(?(*/)?(micro)python*([0-9.])|?(*/)py@(py|ston)*([0-9.])|-?))
78-
if [[ $cword -lt 2 || ${words[cword - 2]} != -[QWX] ]]; then
79-
_comp_compgen_filedir
80-
return
81-
fi
82-
;;
83109
esac
84110

85-
# if -c or -m is already given, complete all kind of files.
86-
if [[ ${words[*]::cword} == *\ -[cm]\ * ]]; then
87-
_comp_compgen -a filedir
88-
elif [[ $cur != -* ]]; then
89-
_comp_compgen -a filedir '@(py?([cowz])|zip)'
111+
if [[ $prev == -- || $cur != -* ]]; then
112+
_comp_compgen_filedir '@(py?([cowz])|zip)'
90113
else
91114
_comp_compgen_help - <<<"$("$1" -h |
92115
awk '{ sub("\\(-bb:","\n-bb "); print }')"

test/fixtures/python/bar.txt

Whitespace-only changes.

test/fixtures/python/foo.py

Whitespace-only changes.

test/t/test_python.py

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,3 +45,42 @@ def test_9(self, completion):
4545
)
4646
def test_bb(self, completion):
4747
assert "-bb" in completion
48+
49+
@pytest.mark.complete("python foo ", cwd="python")
50+
def test_script_arg(self, completion):
51+
assert "bar.txt" in completion
52+
53+
@pytest.mark.complete("python -- foo ", cwd="python")
54+
def test_script_arg_with_double_hyphen(self, completion):
55+
assert "bar.txt" in completion
56+
57+
@pytest.mark.complete("python -m foo bar -p ", cwd="python")
58+
def test_module_arg(self, completion):
59+
assert "bar.txt" in completion
60+
61+
@pytest.mark.complete("python foo bar -p ", cwd="python")
62+
def test_script_arg_after_option(self, completion):
63+
assert "bar.txt" in completion
64+
65+
@pytest.mark.complete("python -- foo bar -p ", cwd="python")
66+
def test_script_arg_after_option_with_double_hyphen(self, completion):
67+
assert "bar.txt" in completion
68+
69+
@pytest.mark.complete("python -m foo bar -p ", cwd="python")
70+
def test_module_arg_after_option(self, completion):
71+
assert "bar.txt" in completion
72+
73+
@pytest.mark.complete("python -mfoo bar -p ", cwd="python")
74+
def test_module_arg_after_option_with_connected_m_arg(self, completion):
75+
assert "bar.txt" in completion
76+
77+
@pytest.mark.complete("python -- ", cwd="python")
78+
def test_script_name(self, completion):
79+
assert "bar.txt" not in completion
80+
81+
@pytest.mark.complete("python -W -mfoo ", cwd="python")
82+
def test_script_name_with_fake_m_arg(self, completion):
83+
"""In this case, -mfoo looks like an option to specify the module, but
84+
it should not be treated as the module name because it is an option
85+
argument to -W."""
86+
assert "bar.txt" not in completion

0 commit comments

Comments
 (0)