Skip to content

Commit 6a1ed5c

Browse files
authored
Add completion script for powershell (#9025)
1 parent 2e1112a commit 6a1ed5c

File tree

4 files changed

+64
-4
lines changed

4 files changed

+64
-4
lines changed

docs/html/user_guide.rst

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -496,6 +496,10 @@ To setup for fish::
496496

497497
python -m pip completion --fish > ~/.config/fish/completions/pip.fish
498498

499+
To setup for powershell::
500+
501+
python -m pip completion --powershell | Out-File -Encoding default -Append $PROFILE
502+
499503
Alternatively, you can use the result of the ``completion`` command directly
500504
with the eval function of your shell, e.g. by adding the following to your
501505
startup file::

news/9024.feature.rst

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
Add support for Powershell autocompletion.

src/pip/_internal/commands/completion.py

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,28 @@
4343
end
4444
complete -fa "(__fish_complete_pip)" -c {prog}
4545
""",
46+
"powershell": """
47+
if ((Test-Path Function:\\TabExpansion) -and -not `
48+
(Test-Path Function:\\_pip_completeBackup)) {{
49+
Rename-Item Function:\\TabExpansion _pip_completeBackup
50+
}}
51+
function TabExpansion($line, $lastWord) {{
52+
$lastBlock = [regex]::Split($line, '[|;]')[-1].TrimStart()
53+
if ($lastBlock.StartsWith("{prog} ")) {{
54+
$Env:COMP_WORDS=$lastBlock
55+
$Env:COMP_CWORD=$lastBlock.Split().Length - 1
56+
$Env:PIP_AUTO_COMPLETE=1
57+
(& {prog}).Split()
58+
Remove-Item Env:COMP_WORDS
59+
Remove-Item Env:COMP_CWORD
60+
Remove-Item Env:PIP_AUTO_COMPLETE
61+
}}
62+
elseif (Test-Path Function:\\_pip_completeBackup) {{
63+
# Fall back on existing tab expansion
64+
_pip_completeBackup $line $lastWord
65+
}}
66+
}}
67+
""",
4668
}
4769

4870

@@ -76,6 +98,14 @@ def add_options(self) -> None:
7698
dest="shell",
7799
help="Emit completion code for fish",
78100
)
101+
self.cmd_opts.add_option(
102+
"--powershell",
103+
"-p",
104+
action="store_const",
105+
const="powershell",
106+
dest="shell",
107+
help="Emit completion code for powershell",
108+
)
79109

80110
self.parser.insert_option_group(0, self.cmd_opts)
81111

tests/functional/test_completion.py

Lines changed: 29 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,30 @@
5454
}
5555
compctl -K _pip_completion pip""",
5656
),
57+
(
58+
"powershell",
59+
"""\
60+
if ((Test-Path Function:\\TabExpansion) -and -not `
61+
(Test-Path Function:\\_pip_completeBackup)) {
62+
Rename-Item Function:\\TabExpansion _pip_completeBackup
63+
}
64+
function TabExpansion($line, $lastWord) {
65+
$lastBlock = [regex]::Split($line, '[|;]')[-1].TrimStart()
66+
if ($lastBlock.StartsWith("pip ")) {
67+
$Env:COMP_WORDS=$lastBlock
68+
$Env:COMP_CWORD=$lastBlock.Split().Length - 1
69+
$Env:PIP_AUTO_COMPLETE=1
70+
(& pip).Split()
71+
Remove-Item Env:COMP_WORDS
72+
Remove-Item Env:COMP_CWORD
73+
Remove-Item Env:PIP_AUTO_COMPLETE
74+
}
75+
elseif (Test-Path Function:\\_pip_completeBackup) {
76+
# Fall back on existing tab expansion
77+
_pip_completeBackup $line $lastWord
78+
}
79+
}""",
80+
),
5781
)
5882

5983

@@ -141,9 +165,10 @@ def test_completion_alone(autocomplete_script: PipTestEnvironment) -> None:
141165
Test getting completion for none shell, just pip completion
142166
"""
143167
result = autocomplete_script.pip("completion", allow_stderr_error=True)
144-
assert "ERROR: You must pass --bash or --fish or --zsh" in result.stderr, (
145-
"completion alone failed -- " + result.stderr
146-
)
168+
assert (
169+
"ERROR: You must pass --bash or --fish or --powershell or --zsh"
170+
in result.stderr
171+
), ("completion alone failed -- " + result.stderr)
147172

148173

149174
def test_completion_for_un_snippet(autocomplete: DoAutocomplete) -> None:
@@ -362,7 +387,7 @@ def test_completion_path_after_option(
362387
)
363388

364389

365-
@pytest.mark.parametrize("flag", ["--bash", "--zsh", "--fish"])
390+
@pytest.mark.parametrize("flag", ["--bash", "--zsh", "--fish", "--powershell"])
366391
def test_completion_uses_same_executable_name(
367392
autocomplete_script: PipTestEnvironment, flag: str, deprecated_python: bool
368393
) -> None:

0 commit comments

Comments
 (0)