From 070901454924023ebf7cf0aee2360353cb746704 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tais=20Hjortsh=C3=B8j?= Date: Sun, 13 Apr 2025 00:46:22 +0200 Subject: [PATCH] scripts: west_commands: Add powershell autocompletion (west -b) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Windows powershell can by default not autocomplete known boards when tapping which can cause frustration when you can't quite remember the exact name or you don't want to type it out. west build .\path\to\application\ -p -b stm will search for available board including 'stm' in their name. Signed-off-by: Tais Hjortshøj --- doc/develop/west/install.rst | 18 +++++++ doc/develop/west/zephyr-cmds.rst | 1 + scripts/west_commands/completion.py | 18 ++++++- .../completion/west-completion.ps1 | 47 +++++++++++++++++++ 4 files changed, 82 insertions(+), 2 deletions(-) create mode 100644 scripts/west_commands/completion/west-completion.ps1 diff --git a/doc/develop/west/install.rst b/doc/develop/west/install.rst index 5ac0f6efaa4..cb207bf3789 100644 --- a/doc/develop/west/install.rst +++ b/doc/develop/west/install.rst @@ -53,6 +53,7 @@ West currently supports shell completion in the following shells: * bash * zsh * fish +* powershell (board qualifiers only) In order to enable shell completion, you will need to obtain the corresponding completion script and have it sourced. @@ -102,5 +103,22 @@ Using the completion scripts: west completion fish > $HOME/.config/fish/completions/west.fish + .. group-tab:: powershell + + *One-time setup*: + + .. code-block:: powershell + + west completion powershell | Out-String | Invoke-Expression + + *Permanent setup*: + + .. code-block:: powershell + + Set-ExecutionPolicy RemoteSigned -Scope CurrentUser + New-item -type file -force $PROFILE + west completion powershell > $HOME/west-completion.ps1 + (Add-Content -Path $PROFILE -Value ". '{$HOME/west-completion.ps1}'") + .. _PyPI: https://pypi.org/project/west/ diff --git a/doc/develop/west/zephyr-cmds.rst b/doc/develop/west/zephyr-cmds.rst index b4ef9532cff..1afd5f9bb7b 100644 --- a/doc/develop/west/zephyr-cmds.rst +++ b/doc/develop/west/zephyr-cmds.rst @@ -40,6 +40,7 @@ It currently supports the following shells: - bash - zsh - fish +- powershell (board qualifiers only) Additional instructions are available in the command's help:: diff --git a/scripts/west_commands/completion.py b/scripts/west_commands/completion.py index 11b9aa44653..0afd69b23fa 100644 --- a/scripts/west_commands/completion.py +++ b/scripts/west_commands/completion.py @@ -36,6 +36,14 @@ to stdout. Using the completion scripts: # permanent west completion fish > $HOME/.config/fish/completions/west.fish + powershell: + # one-time + west completion powershell | Out-String | Invoke-Expression + # permanent + Set-ExecutionPolicy RemoteSigned -Scope CurrentUser + New-item -type file -force $PROFILE + (Add-Content -Path $PROFILE -Value ". '{$HOME/west-completion.ps1}'") + positional arguments: source_dir application source directory cmake_opt extra options to pass to cmake; implies -c @@ -44,6 +52,12 @@ positional arguments: class Completion(WestCommand): + _EXT_MAPPING = { + "bash": "bash", + "fish": "fish", + "powershell": "ps1", + "zsh": "zsh", + } def __init__(self): super().__init__( @@ -62,7 +76,7 @@ class Completion(WestCommand): # Remember to update west-completion.bash if you add or remove # flags - parser.add_argument('shell', nargs=1, choices=['bash', 'zsh', 'fish'], + parser.add_argument('shell', nargs=1, choices=self._EXT_MAPPING.keys(), help='''Shell that which the completion script is intended for.''') return parser @@ -71,7 +85,7 @@ class Completion(WestCommand): cf = os.path.join(os.path.dirname(os.path.realpath(__file__)), *COMPLETION_REL_PATH.split('/')) - cf += '.' + args.shell[0] + cf += '.' + self._EXT_MAPPING[args.shell[0]] try: with open(cf, 'r') as f: diff --git a/scripts/west_commands/completion/west-completion.ps1 b/scripts/west_commands/completion/west-completion.ps1 new file mode 100644 index 00000000000..819b8fe936e --- /dev/null +++ b/scripts/west_commands/completion/west-completion.ps1 @@ -0,0 +1,47 @@ +# Copyright © 2025, Tais Hjortshøj / Mjølner Informatics A/S +# SPDX-License-Identifier: Apache-2.0 + +# region custom west board finder initialize +$s = { + param($wordToComplete, $commandAst, $cursorPosition) + + function Get-MatchingBoards { + param($wordToComplete) + west boards | Out-String | ForEach-Object { + $_ -split '\r?\n' | Where-Object { $_ -CMatch "^$wordToComplete.*" } | Sort-Object + } + } + + $commandDecider = (($commandAst -split ' ') | Select-Object -First 2 -ExpandProperty $_) -join ' ' + if ($commandDecider -eq 'west build') { + + $argDecider = (($commandAst -split ' ') | Select-Object -Last 2) + + if ($argDecider -contains '-b' -or $argDecider -contains '--board') { + $boardsFound = Get-MatchingBoards -wordToComplete $wordToComplete + $output = $boardsFound + } else { + # Fallback to default behavior of suggesting files in the current directory + $output = (Get-NexusRepository).Name + } + } else { + # Fallback to default behavior of suggesting files in the current directory + $output = (Get-NexusRepository).Name + } + + # Uncomment the following lines to log the output for debugging purposes + # @("wordToComplete: $wordToComplete", + # "commandAst: $commandAst", + # "cursorPosition: $cursorPosition", + # "commandDecider: $commandDecider", + # "argDecider: $argDecider", + # "", + # "boardsFound:", + # ($boardsFound | ForEach-Object { $_ -split ' '}) + # ) | Set-Content log.txt + + $output +} +Register-ArgumentCompleter -Native -CommandName west -ScriptBlock $s +echo "West completion tool loaded" +# endregion