Skip to content

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);
    }
}
snippet source | anchor

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:

  1. When you press Tab, the shell calls your app with [suggest] and the current command line
  2. Your app parses the input and returns relevant suggestions
  3. 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);
    }
}
snippet source | anchor

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) { }
}
snippet source | anchor

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);
}
snippet source | anchor

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
    }
}
snippet source | anchor

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#

  1. Verify [suggest] directive is enabled

    myapp [suggest]  # Should return suggestions
    

  2. Check shell integration

  3. Bash: complete -p myapp should show the completion function
  4. Zsh: which _myapp should show the completion function
  5. Fish: Check ~/.config/fish/completions/myapp.fish exists

  6. 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#