Shell Integration
The azdw CLI provides comprehensive shell integration for enhanced productivity. Shell integration enables intelligent tab-completion for commands, subcommands, options, and arguments across multiple shell environments, and also installs the azdw PowerShell module for PowerShell sessions.
Overview
Shell completions provide:
- Command name completion: Auto-complete main commands (
connection,query,config, etc.) - Subcommand completion: Complete subcommands for each command (
add,list,remove, etc.) - Option completion: Suggest available options and flags (
--connection,--verbose, etc.) - Context-aware suggestions: Intelligent completion based on command context
- Self-contained: No external tools required - uses System.CommandLine’s built-in
[suggest]directive
Supported Shells
The azdw CLI supports shell completions for the following environments:
macOS / Linux
- Bash - GNU Bourne Again Shell
- Zsh - Z Shell (default on macOS)
- Fish - Friendly Interactive Shell
- Nushell - Modern shell written in Rust
- Sh - POSIX Shell
Windows
- PowerShell 7+ - Cross-platform PowerShell
- Nushell - Modern shell written in Rust (cross-platform)
- Clink - Bash-like completion for Windows cmd.exe
Quick Start
Install Shell Integration for Current Shell
The simplest way to enable shell integration:
azdw config shell-integration
This command:
- Detects your current shell
- Generates appropriate completion scripts (and PowerShell module import for PowerShell)
- Installs them in the correct location
- Configures your shell to load completions
After installation, restart your shell or source your configuration file as instructed.
Install for All Detected Shells
To install shell integration for all shells available on your system:
azdw config shell-integration --all
This is useful if you use multiple shells or want to ensure completions work regardless of which shell you’re using.
Command Reference
Basic Usage
azdw config shell-integration [options]
Options
| Option | Alias | Description |
|---|---|---|
--all | -a | Install for all detected shells (default: current shell only) |
--uninstall | -u | Uninstall shell integration |
--list | -l | List detected shells and their integration status |
Examples
List Available Shells
See which shells are detected on your system:
azdw config shell-integration --list
Example output:
Shell Detection Results:
========================
Current Shell: Zsh (Zsh)
Path: /bin/zsh
Available Shells (3):
PowerShell (PowerShell)
Path: /usr/local/bin/pwsh
Version: 7.5.3
Config: /Users/user/.config/powershell/Microsoft.PowerShell_profile.ps1
Bash (Bash)
Path: /bin/bash
Config: /Users/user/.bashrc
Completions: /Users/user/.bash_completion
→ Zsh (Zsh)
Path: /opt/homebrew/bin/zsh
Config: /Users/user/.zshrc
Completions: /Users/user/.zsh/completions
Uninstall Shell Integration
Remove shell integration from the current shell:
azdw config shell-integration --uninstall
Remove shell integration from all shells:
azdw config shell-integration --uninstall --all
Installation Details
Zsh
Location: ~/.zsh/completions/_azdw
The installer:
- Creates the completion directory if needed
- Generates the
_azdwcompletion function - Updates
~/.zshrcto add the executable directory to PATH persistently (via export statement) - Updates
~/.zshrcto add the completion directory tofpath - Configures autoload for compinit
Activation: Restart zsh or run:
source ~/.zshrc
Bash
Location: ~/.bash_completion.d/azdw
The installer:
- Creates the completion directory if needed
- Generates the bash completion script
- Updates
~/.bashrcto add the executable directory to PATH persistently (via export statement) - Updates
~/.bashrcto source completion scripts
Activation: Restart bash or run:
source ~/.bashrc
PowerShell 7+
Location: PowerShell profile script (typically ~/.config/powershell/Microsoft.PowerShell_profile.ps1)
The installer:
- Creates the profile file if needed
- Adds the executable directory to PATH persistently (on Windows: updates user PATH environment variable; on macOS/Linux: adds export to profile)
- Adds ArgumentCompleter registration for
azdw - Implements tab-completion logic
Activation: Restart PowerShell or run:
. $PROFILE
PATH Configuration: On Windows, the installer uses [Environment]::SetEnvironmentVariable() to add the executable directory to the user’s PATH permanently. On macOS/Linux, it adds an export statement to the profile.
Fish
Location: ~/.config/fish/completions/azdw.fish
The installer:
- Creates the completions directory if needed
- Generates the fish completion script
- Adds the executable directory to PATH persistently using Fish’s universal variables (
set -Ux fish_user_paths)
Activation: Completions are loaded automatically; no restart needed.
PATH Configuration: Fish uses universal variables (fish_user_paths) which persist across all Fish sessions automatically.
Clink (Windows cmd.exe)
Location: Clink completions directory (auto-detected from Clink installation)
The installer:
- Detects Clink installation directory
- Creates the
azdw.luacompletion script - Installs it in the appropriate location
Activation: Restart cmd.exe to reload completions.
Nushell
Location: Nushell config file
- Linux/macOS:
~/.config/nushell/config.nu - Windows:
%APPDATA%\nushell\config.nu
The installer:
- Detects Nushell configuration directory
- Adds external completer configuration to
config.nu - Configures the
[suggest]directive integration
Activation: Restart Nushell or run:
source ~/.config/nushell/config.nu
Note: Nushell uses an “external completer” pattern where completions for external commands are handled by a closure. The installer configures this automatically.
How It Works
Detection
The shell completion service uses multiple detection strategies:
- Environment Variables: Checks
SHELL,PSModulePath,CLINK_DIR - Process Information: Examines parent process names
- File System: Searches for shell executables in standard locations
- Configuration Files: Detects shell configuration file locations
The [suggest] Directive - Modern Completion Approach
azdw uses System.CommandLine 2.0+’s built-in [suggest] directive for shell completions. This is the recommended modern approach for .NET 10+ CLI applications.
How the [suggest] Directive Works
When tab completion is triggered, the shell script calls the CLI directly with a special syntax:
azdw "[suggest:POSITION]" "COMMANDLINE"
Where:
POSITIONis the cursor position (0-based index) in the command lineCOMMANDLINEis the full command line text being completed
Example:
# User types: azdw config <TAB>
# Shell invokes:
azdw "[suggest:12]" "azdw config "
# CLI returns (one per line):
ai
fieldmap
paths
shell-integration
urlmap
--help
--verbose
...
The CLI parses the command line, determines what completions are valid at the cursor position, and outputs them (one per line) to stdout. The shell script captures this output and presents it to the user.
Why [suggest] is the Best Modern Approach
⚠️ Design Decision Reference: This section documents why the direct
[suggest]approach was chosen. Internet searches may show older approaches likedotnet-suggestordotnet complete. Do not revert to those approaches - they have significant drawbacks explained below.
Advantages of the direct [suggest] approach:
| Benefit | Description |
|---|---|
| Self-contained | No external tools required - the CLI handles its own completions |
| No installation complexity | No dotnet tool install -g dotnet-suggest needed |
| No DOTNET_ROOT issues | Works regardless of .NET SDK installation location |
| No registration files | No ~/.dotnet-suggest-registration.txt management |
| No broker process | Direct invocation - no intermediary process overhead |
| Runtime-only | Works with just .NET Runtime (no SDK required on user machines) |
| Cross-platform reliable | No macOS code signing workarounds needed |
| Simpler debugging | Can test directly: azdw "[suggest:12]" "azdw config " |
Approaches to Avoid (and Why)
❌ dotnet-suggest global tool (deprecated approach):
- Requires
dotnet tool install -g dotnet-suggest - Requires proper
DOTNET_ROOTconfiguration (source of many issues) - Requires app registration with
dotnet-suggest register - Acts as broker between shell and CLI (extra process, extra failure modes)
- Suffers from CoreCLR initialization issues on some systems
- Not needed with System.CommandLine 2.0+ which has built-in
[suggest]
❌ dotnet complete / dotnet completions script (not for apps):
- These are for the dotnet CLI itself, not for apps built with System.CommandLine
- Running
dotnet completions script zshgenerates completions fordotnet, not for your app - Common source of confusion - produces German/localized dotnet commands, not app commands
❌ Static completion scripts (limited):
- Pre-generated completion lists become stale
- Cannot adapt to dynamic command structures
- Cannot provide context-aware completions
Shell Script Implementation
Each shell uses a script that:
- Captures the current command line and cursor position
- Invokes
azdw "[suggest:POSITION]" "COMMANDLINE" - Parses the output (newline-separated suggestions)
- Presents suggestions to the user
Zsh example (simplified):
_azdw_completions() {
local commandline="$words"
local position=$((CURSOR))
# Call CLI with [suggest] directive
local completions=$(azdw "[suggest:$position]" "$commandline" 2>/dev/null)
# Present to zsh
local -a suggestions
suggestions=(${(f)completions})
_describe 'suggestions' suggestions
}
compdef _azdw_completions azdw
PowerShell example (simplified):
Register-ArgumentCompleter -Native -CommandName azdw -ScriptBlock {
param($wordToComplete, $commandAst, $cursorPosition)
$commandLine = $commandAst.ToString()
& azdw "[suggest:$cursorPosition]" "$commandLine" 2>$null | ForEach-Object {
[System.Management.Automation.CompletionResult]::new($_, $_, 'ParameterValue', $_)
}
}
Nushell example (simplified):
# Define external completer for azdw
let azdw_completer = {|spans|
let cmd = ($spans | str join " ")
let position = ($cmd | str length)
azdw $"[suggest:($position)]" $cmd | lines | where {|it| $it != ""}
}
# Configure external completions
$env.config.completions.external = {
enable: true
completer: {|spans|
if ($spans.0 == "azdw") {
do $azdw_completer $spans
} else {
null # Fall back to default
}
}
}
System.CommandLine Integration
The [suggest] directive is a built-in feature of System.CommandLine 2.0+:
- Automatic handling: System.CommandLine recognizes the
[suggest:N]pattern - Context-aware: Analyzes the command tree to determine valid completions
- Option awareness: Suggests options, their values, and subcommands appropriately
- Description support: Can include descriptions for richer shell completion UIs
When System.CommandLine sees [suggest:N] as the first argument:
- It does not execute the normal command
- It parses the second argument as the command line to complete
- It outputs valid completions to stdout
- It exits with code 0
Generation
Completions are generated dynamically based on the actual CLI command structure:
- Introspects all commands, subcommands, and options at runtime
- Outputs shell-agnostic completion candidates
- Shell scripts format suggestions for their specific completion system
- Includes help text and descriptions where available in the command model
Installation
The installer:
- Detects appropriate installation paths based on shell conventions
- Creates necessary directories with proper permissions
- Generates shell-specific completion scripts that use the
[suggest]directive - Adds completion configuration to shell profile
- Provides rollback capability via uninstall
- Automatically migrates from old
dotnet-suggestconfiguration if present
Troubleshooting
Completions Not Working After Installation
Zsh:
# Ensure fpath includes completions directory
echo $fpath | grep zsh/completions
# Rebuild completion cache
rm -f ~/.zcompdump
compinit
Bash:
# Check if completion script is sourced
grep -r "bash_completion.d" ~/.bashrc
# Manually source completions
source ~/.bash_completion.d/azdw
PowerShell:
# Check if profile is loaded
Test-Path $PROFILE
# Verify completion is registered
Get-ArgumentCompleter -Native | Where-Object { $_.CommandName -like '*azdw*' }
# Manually reload profile
. $PROFILE
# Test the [suggest] directive directly
azdw '[suggest:12]' 'azdw config '
# Should output completions like:
# ai
# fieldmap
# shell-integration
# ...
Important PowerShell Limitation: Tab completion only works when invoking the command by its base name (azdw, azdw.exe) after the executable directory is in your PATH. The installer automatically adds the directory to PATH persistently in your profile (and on Windows, also updates the user’s PATH environment variable). Tab completion will not work with arbitrary relative/absolute paths like .\publish\azdw.exe or C:\tools\azdw.exe because PowerShell’s native argument completer requires exact command name matches and cannot use pattern matching.
Workaround: The installer automatically adds the azdw executable directory to your PATH persistently. After installation and restarting your shell, you can invoke azdw or azdw.exe from any directory with full tab completion support.
Permission Errors
If installation fails due to permissions:
# Check permissions on config files
ls -la ~/.zshrc ~/.bashrc
# Ensure directories exist with correct ownership
mkdir -p ~/.zsh/completions
chmod 755 ~/.zsh/completions
Multiple Shell Versions
If you have multiple versions of a shell installed, the completion may install for a different version than you’re using. Check:
# See which shell is actually running
echo $SHELL
ps -p $$
# List all installed shells
cat /etc/shells
Advanced Usage
Custom Installation Path
The completion installer uses standard paths, but you can manually move completion files:
Zsh:
# Move to custom location
mv ~/.zsh/completions/_azdw /custom/path/_azdw
# Update fpath in .zshrc
fpath=(/custom/path $fpath)
Bash:
# Move and source from custom location
mv ~/.bash_completion.d/azdw /custom/path/azdw
echo "source /custom/path/azdw" >> ~/.bashrc
Completion Cache
Some shells cache completions for performance:
Zsh:
# Clear cache after updating azdw
rm -f ~/.zcompdump
compinit
Integration with CI/CD
While shell integration is primarily for interactive use, you can include installation in setup scripts:
#!/bin/bash
# setup-dev-environment.sh
# Install azdw
curl -L https://example.com/azdw-installer.sh | bash
# Setup shell integration for all shells
azdw config shell-integration --all
echo "Development environment ready!"
Related Commands
azdw config- Manage all azdw configurationazdw --help- View complete CLI documentationazdw --version- Check azdw version