Shell Completions#
CommandDotNet provides built-in support for generating shell completion scripts for bash, zsh, fish, and PowerShell. This enables tab completion for commands, options, and argument values in your CLI applications.
Quick Start#
Add the CompletionCommand class as a subcommand to your application:
public class MyApp
{
[Subcommand]
public CompletionCommand Completion { get; set; } = new();
// your other commands...
public void Deploy(string environment) { }
}
class Program
{
static int Main(string[] args)
{
return new AppRunner<MyApp>()
.UseDefaultMiddleware() // includes [suggest] directive
.Run(args);
}
}
That's it! Your app now has a completion command that generates shell-specific completion scripts.
Usage#
Generate Completion Scripts#
Users can generate completion scripts for their shell:
# See available shells
myapp completion --help
# Generate bash completion
myapp completion bash
# Generate zsh completion
myapp completion zsh
# Generate fish completion
myapp completion fish
# Generate PowerShell completion
myapp completion powershell
Installation Instructions#
Each shell command includes installation instructions in its help text:
myapp completion bash --help
Shell-Specific Installation#
Bash#
Option 1: Source directly in .bashrc
# Add to ~/.bashrc
source <(myapp completion bash)
Option 2: Save to file
myapp completion bash > ~/.myapp-completion.bash
echo "source ~/.myapp-completion.bash" >> ~/.bashrc
Zsh#
Option 1: Source directly in .zshrc
# Add to ~/.zshrc
source <(myapp completion zsh)
Option 2: Save to fpath
# Save to a directory in your fpath
myapp completion zsh > ~/.zsh/completions/_myapp
# Ensure the directory is in your fpath (add to ~/.zshrc if needed)
fpath=(~/.zsh/completions $fpath)
autoload -U compinit && compinit
Fish#
Option 1: Save to completions directory
myapp completion fish > ~/.config/fish/completions/myapp.fish
Option 2: Source in config.fish
# Add to ~/.config/fish/config.fish
myapp completion fish | source
PowerShell#
Option 1: Add to profile
# Add to your PowerShell profile
myapp completion powershell | Out-String | Invoke-Expression
# Find your profile location
$PROFILE
Option 2: Save and dot-source
myapp completion powershell > ~/myapp-completion.ps1
# Add to your profile
. ~/myapp-completion.ps1
How It Works#
The completion scripts integrate with the [suggest] directive to provide intelligent completions:
- When you press Tab, the shell calls your app with
[suggest]and the current command line - Your app parses the input and returns relevant suggestions
- The shell displays the suggestions
What Gets Completed#
- Commands: All visible commands and subcommands
- Options: Available options for the current command
- Enum values: Automatically suggested for enum parameters
- Allowed values: Values defined via
[AllowedValues]attribute - Context-aware: Suggestions respect arity, parse state, and validation rules
Advanced Configuration#
Custom App Name#
If your executable name differs from the default, configure it in AppSettings:
class ProgramWithCustomName
{
static int Main(string[] args)
{
return new AppRunner<MyApp>(new AppSettings
{
Execution = { UsageAppName = "my-custom-name" }
})
.UseDefaultMiddleware()
.Run(args);
}
}
The completion scripts will use the configured app name.
Conditional Inclusion#
You can conditionally include the completion command:
public class MyAppWithConditionalCompletion
{
[Subcommand]
public CompletionCommand? Completion { get; set; }
#if INCLUDE_COMPLETIONS
= new();
#endif
// your commands...
public void Deploy(string environment) { }
}
Testing Completions#
Test your completions work correctly:
# Test command suggestions
myapp [suggest]
# Test option suggestions for a command
myapp [suggest] deploy
# Test value suggestions for an option
myapp [suggest] deploy --environment
# Test filtering
myapp [suggest] deploy --environment prod
See the [suggest] directive documentation for more details on testing.
Distribution#
Include Installation Instructions#
Add installation instructions to your README or documentation:
## Shell Completion
Enable tab completion by running:
```bash
# Bash
echo 'source <(myapp completion bash)' >> ~/.bashrc
# Zsh
echo 'source <(myapp completion zsh)' >> ~/.zshrc
# Fish
myapp completion fish > ~/.config/fish/completions/myapp.fish
# PowerShell
myapp completion powershell | Out-String | Invoke-Expression
```
Package Managers#
For applications distributed via package managers, you can install completion scripts during package installation:
Homebrew formula example:
def install
bin.install "myapp"
# Install completions
bash_completion.install "completions/myapp.bash"
zsh_completion.install "completions/_myapp"
fish_completion.install "completions/myapp.fish"
end
Generate the completion files during your build:
myapp completion bash > completions/myapp.bash
myapp completion zsh > completions/_myapp
myapp completion fish > completions/myapp.fish
Examples#
Basic App#
public class Calculator
{
[Subcommand]
public CompletionCommand Completion { get; set; } = new();
public void Add(int x, int y) => Console.WriteLine(x + y);
public void Subtract(int x, int y) => Console.WriteLine(x - y);
}
class CalculatorProgram
{
static int Main(string[] args) =>
new AppRunner<Calculator>()
.UseDefaultMiddleware()
.Run(args);
}
Users get completions for commands:
calc [tab] # Shows: Add, Completion, Subtract
calc Add [tab] # Shows: --x, --y
With Enums#
public enum Environment { Dev, Staging, Production }
public class DeployApp
{
[Subcommand]
public CompletionCommand Completion { get; set; } = new();
public void Deploy(
Environment environment,
[Option] bool dryRun = false)
{
// deploy logic
}
}
Users get enum completions:
deploy [tab] # Shows: --environment, --dryRun
deploy --environment [tab] # Shows: Dev, Staging, Production
deploy --environment Pro[tab] # Completes to: Production
Troubleshooting#
Completions Not Working#
-
Verify [suggest] directive is enabled
myapp [suggest] # Should return suggestions -
Check shell integration
- Bash:
complete -p myappshould show the completion function - Zsh:
which _myappshould show the completion function -
Fish: Check
~/.config/fish/completions/myapp.fishexists -
Reload shell configuration
# Bash source ~/.bashrc # Zsh source ~/.zshrc # Fish source ~/.config/fish/config.fish
No Suggestions Appearing#
- Ensure
UseDefaultMiddleware()is called (includes suggest directive) - Or explicitly enable:
appRunner.UseSuggestDirective() - Check for parse errors:
myapp [suggest] <your-command> 2>&1
See Also#
- [suggest] Directive - How suggestions are generated
- Directives - Understanding directives
- Testing Shell Completions - Test your completion scenarios