Document Version: 1.0 Last Updated: 2025-12-30 Framework: cli-fp Applies To: PowerShell 5.1+ (Windows, Linux, macOS)
This guide explains how to use PowerShell completion effectively with CLI applications built using the cli-fp framework.
-
Generate the completion script:
.\SubCommandDemo.exe --completion-file-pwsh > subcommanddemo_completion.ps1
-
Source the script in your current session:
. .\subcommanddemo_completion.ps1 -
(Optional) Make it permanent by adding to your PowerShell profile:
# Find your profile location $PROFILE # Add the source command to your profile Add-Content $PROFILE ". C:\path\to\subcommanddemo_completion.ps1"
Press TAB once to cycle through available options:
PS> .\SubCommandDemo.exe repo [TAB]
PS> .\SubCommandDemo.exe repo init # First option
PS> .\SubCommandDemo.exe repo [TAB] # Press again
PS> .\SubCommandDemo.exe repo clone # Second option
PS> .\SubCommandDemo.exe repo [TAB] # Press again
PS> .\SubCommandDemo.exe repo -h # Third optionPress SHIFT+TAB to cycle backwards through options.
Important: The cli-fp completion engine follows a "commands first" design principle:
When you press [TAB] at the root level without any prefix, only commands are shown, not flags:
PS> .\SubCommandDemo.exe [TAB]
PS> .\SubCommandDemo.exe repo # Only the command, cycles to it firstTo see flags, type a dash prefix:
PS> .\SubCommandDemo.exe -[TAB]
PS> .\SubCommandDemo.exe --help # Cycles through all flags
PS> .\SubCommandDemo.exe --[TAB]
PS> .\SubCommandDemo.exe --help # Cycles through long flags onlyWhy this design?
- Reduces cognitive overload by showing the most commonly needed items first (commands)
- Follows the natural workflow: choose a command, then choose flags
- Keeps the initial suggestion list short and focused
- Flags are still easily accessible by typing
-or--
This behavior is intentional and consistent across both Bash and PowerShell completion.
PowerShell behavior differs from Bash:
PowerShell cycles through options one at a time:
PS> .\SubCommandDemo.exe repo [TAB] # Shows: init
PS> .\SubCommandDemo.exe repo [TAB] # Shows: clone
PS> .\SubCommandDemo.exe repo [TAB] # Shows: -h
PS> .\SubCommandDemo.exe repo [TAB] # Shows: --help
# ... continues cyclingBash shows all options at once with double-TAB:
$ ./SubCommandDemo.exe repo [TAB][TAB]
--help -h clone init remote # All shown at onceTip: Press TAB multiple times to see all available completions in PowerShell.
After entering a parameter value, you need to type - or -- to see remaining options:
Won't work:
PS> .\SubCommandDemo.exe repo clone --url https://example.com [TAB]
# No completions shown - PowerShell needs a prefix to match againstWill work:
PS> .\SubCommandDemo.exe repo clone --url https://example.com --[TAB]
PS> .\SubCommandDemo.exe repo clone --url https://example.com --path
# Cycles through remaining flagsThis is standard PowerShell completion behavior - the shell needs something to complete.
Global flags like --help, --version, -h, and -v are available at every command level:
PS> .\SubCommandDemo.exe repo init --[TAB]
# Cycles through: --path, --bare, --help, --versionThis is correct behavior - global flags should always be accessible.
Some commands are "command groups" that contain subcommands but have no flags of their own:
PS> .\SubCommandDemo.exe repo --[TAB]
# Shows only: --help, --version (global flags)
# No repo-specific flags because repo is a command groupTo see subcommands:
PS> .\SubCommandDemo.exe repo [TAB]
# Cycles through: init, clone, remote, -h, --helpPowerShell completion is case-insensitive by default:
PS> .\SubCommandDemo.exe repo INIT --BARE [TAB]
# Works! Completes with: true, falsePS> .\SubCommandDemo.exe r[TAB]
PS> .\SubCommandDemo.exe repoPS> .\SubCommandDemo.exe repo i[TAB]
PS> .\SubCommandDemo.exe repo initPS> .\SubCommandDemo.exe repo init --[TAB]
# Keeps pressing TAB to cycle through all flagsPS> .\SubCommandDemo.exe repo init --bare [TAB]
PS> .\SubCommandDemo.exe repo init --bare false
PS> .\SubCommandDemo.exe repo init --bare t[TAB]
PS> .\SubCommandDemo.exe repo init --bare truePS> .\SubCommandDemo.exe repo remote [TAB]
PS> .\SubCommandDemo.exe repo remote add
PS> .\SubCommandDemo.exe repo remote add --[TAB]
PS> .\SubCommandDemo.exe repo remote add --nameIf you miss the option you want, press SHIFT+TAB to cycle backwards:
PS> .\SubCommandDemo.exe repo [TAB] # init
PS> .\SubCommandDemo.exe repo [TAB] # clone
PS> .\SubCommandDemo.exe repo [SHIFT+TAB] # Goes back to initType the first letter to narrow down options:
PS> .\SubCommandDemo.exe repo i[TAB] # Completes to: init
PS> .\SubCommandDemo.exe repo c[TAB] # Completes to: cloneTyping -- shows only long-form flags:
PS> .\SubCommandDemo.exe repo init --[TAB]
# Shows: --path, --bare, --help, --version (no short flags)Typing - shows both short and long flags:
PS> .\SubCommandDemo.exe repo init -[TAB]
# Shows: --path, -p, --bare, -b, --help, -h, --version, -vProblem: Pressing TAB shows no completions
Solutions:
-
Make sure the completion script is sourced:
. .\subcommanddemo_completion.ps1 -
Verify the script loaded successfully:
Get-Command Register-ArgumentCompleter
-
Check PowerShell version (needs 5.1+):
$PSVersionTable.PSVersion
Problem: TAB shows file names instead of command completions
Solution: The completion script is not loaded. Source it:
. .\subcommanddemo_completion.ps1Problem: Cycling through options one-by-one is slow
Solution: PowerShell behavior is to cycle. To see all options, use --help:
.\SubCommandDemo.exe repo init --helpOr use PSReadLine menu completion (PowerShell 7+):
Set-PSReadLineKeyHandler -Key Tab -Function MenuComplete| Feature | PowerShell | Bash |
|---|---|---|
| TAB Behavior | Cycles through options | Shows all options (double-TAB) |
| Root Completion | Commands only (without prefix) | Commands only (without prefix) |
| Case Sensitivity | Case-insensitive | Case-sensitive |
| Reverse Cycling | SHIFT+TAB | N/A (shows all) |
| Global Flags | Always available | Always available |
| Boolean Values | true/false |
true/false |
Enable menu-style completion for easier navigation:
# Add to your $PROFILE
Set-PSReadLineKeyHandler -Key Tab -Function MenuCompleteNow TAB will show a menu:
PS> .\SubCommandDemo.exe repo [TAB]
init
clone
remote
--help
-h
Use arrow keys to select, ENTER to complete.
Show all completions in a list:
# Add to your $PROFILE
Set-PSReadLineKeyHandler -Key Ctrl+Space -Function CompletePress CTRL+SPACE to see all options.
Key points to remember:
- Commands first: Type
-or--to see flags at root level - TAB cycles: Press TAB multiple times to see all options
- SHIFT+TAB: Goes backwards through options
- Prefix required: Type
-or--after values to see flags - Case-insensitive: Uppercase and lowercase both work
- Global flags:
--help,--version,-h,-valways available
- PowerShell Completion Test Results - Full test suite
- PowerShell Completion Analysis - Technical analysis
- Bash Completion Guide - Bash version
Need Help? Run any command with --help to see detailed usage information.