Shell Completions
Overview
Section titled “Overview”Generate shell completions for enhanced command-line UX using clap_complete.
Add Dependencies
Section titled “Add Dependencies”[dependencies]clap = { version = "4.5", features = ["derive"] }clap_complete = "4.5"Implement Completions
Section titled “Implement Completions”crates/cli.rs:
use clap::{Parser, CommandFactory};use clap_complete::{generate, Shell};use std::io;
#[derive(Parser, Debug)]#[command(name = "rust-template")]#[command(about = "Modern Rust project template")]#[command(version)]pub struct Cli { /// Configuration file path #[arg(short, long, value_name = "FILE")] pub config: Option<String>,
/// Verbose output #[arg(short, long)] pub verbose: bool,
/// Generate shell completions #[arg(long, value_name = "SHELL")] pub completions: Option<Shell>,}
impl Cli { pub fn generate_completions(shell: Shell) { let mut cmd = Self::command(); generate(shell, &mut cmd, "rust-template", &mut io::stdout()); }}crates/main.rs:
use clap::Parser;use cli::Cli;
fn main() { let cli = Cli::parse();
// Handle completion generation if let Some(shell) = cli.completions { Cli::generate_completions(shell); return; }
// Normal application logic run(cli);}Installation
Section titled “Installation”# Generate completionsrust-template --completions bash > ~/.local/share/bash-completion/completions/rust-template
# Or system-widesudo rust-template --completions bash > /etc/bash_completion.d/rust-template
# Reloadsource ~/.bashrcTest:
rust-template --<TAB># Shows: --config --verbose --help --version --completions# Generate completionsrust-template --completions zsh > ~/.zsh/completions/_rust-template
# Add to .zshrc if not alreadyecho 'fpath=(~/.zsh/completions $fpath)' >> ~/.zshrcecho 'autoload -Uz compinit && compinit' >> ~/.zshrc
# Reloadsource ~/.zshrcTest:
rust-template --<TAB># Shows completion menu with descriptions# Generate completionsrust-template --completions fish > ~/.config/fish/completions/rust-template.fish
# Reload (automatic in most cases)fish -c 'fish_update_completions'Test:
rust-template --<TAB># Shows completions with descriptionsPowerShell
Section titled “PowerShell”# Generate completionsrust-template --completions powershell | Out-File -FilePath $PROFILE\..\rust-template.ps1
# Add to profileAdd-Content $PROFILE '. "$PSScriptRoot\rust-template.ps1"'
# Reload. $PROFILETest:
rust-template --<TAB># Shows completion suggestionsElvish
Section titled “Elvish”# Generate completionsrust-template --completions elvish > ~/.elvish/lib/rust-template.elv
# Add to rc.elvecho 'use rust-template' >> ~/.elvish/rc.elvPackage Integration
Section titled “Package Integration”Homebrew
Section titled “Homebrew”Formula includes completions:
def install system "cargo", "install", *std_cargo_args
# Generate completions bash_completion.install "completions/rust-template.bash" zsh_completion.install "completions/_rust-template" fish_completion.install "completions/rust-template.fish"endOr generate during install:
def install system "cargo", "install", *std_cargo_args
# Generate at install time generate_completions_from_executable(bin/"rust-template", "--completions")endDebian Package
Section titled “Debian Package”Cargo.toml:
[package.metadata.deb]assets = [ ["target/release/rust-template", "usr/bin/", "755"], ["completions/rust-template.bash", "usr/share/bash-completion/completions/", "644"], ["completions/_rust-template", "usr/share/zsh/vendor-completions/", "644"], ["completions/rust-template.fish", "usr/share/fish/vendor_completions.d/", "644"],]Build Script
Section titled “Build Script”build.rs:
use clap::CommandFactory;use clap_complete::{generate_to, Shell};use std::env;use std::path::PathBuf;
include!("crates/cli.rs");
fn main() { let outdir = PathBuf::from(env::var_os("OUT_DIR").unwrap()); let mut cmd = Cli::command();
for shell in [Shell::Bash, Shell::Zsh, Shell::Fish, Shell::PowerShell] { generate_to(shell, &mut cmd, "rust-template", &outdir).unwrap(); }
println!("cargo:rerun-if-changed=crates/cli.rs");}Advanced Features
Section titled “Advanced Features”Subcommands
Section titled “Subcommands”#[derive(Parser)]enum Commands { /// Initialize a new project Init { /// Project name name: String, }, /// Build the project Build { /// Release mode #[arg(short, long)] release: bool, },}
#[derive(Parser)]struct Cli { #[command(subcommand)] command: Commands,}Completions automatically include subcommands:
rust-template <TAB># Shows: init, build, helpDynamic Completions
Section titled “Dynamic Completions”use clap::ValueHint;
#[derive(Parser)]struct Cli { /// Input file #[arg(value_hint = ValueHint::FilePath)] input: String,
/// Output directory #[arg(value_hint = ValueHint::DirPath)] output: String,
/// Command to run #[arg(value_hint = ValueHint::CommandName)] command: String,}Hints enable:
- File/directory path completion
- Command name completion
- URL completion
- Username completion
Custom Completions
Section titled “Custom Completions”use clap::builder::PossibleValue;
#[derive(Parser)]struct Cli { /// Log level #[arg(value_parser = ["debug", "info", "warn", "error"])] level: String,
/// Or with descriptions #[arg(value_parser = [ PossibleValue::new("debug").help("Detailed debug information"), PossibleValue::new("info").help("General information"), PossibleValue::new("warn").help("Warning messages"), PossibleValue::new("error").help("Error messages only"), ])] level_detailed: String,}Testing Completions
Section titled “Testing Completions”Manual Testing
Section titled “Manual Testing”# Bashcomplete -p rust-template
# Zshwhich _rust-template
# Fishcomplete -C rust-templateAutomated Testing
Section titled “Automated Testing”#[cfg(test)]mod tests { use super::*; use clap_complete::generate; use std::io;
#[test] fn verify_completions() { let mut cmd = Cli::command();
for shell in [Shell::Bash, Shell::Zsh, Shell::Fish] { let mut buf = Vec::new(); generate(shell, &mut cmd, "rust-template", &mut buf); assert!(!buf.is_empty(), "Generated empty completions for {:?}", shell); } }}Troubleshooting
Section titled “Troubleshooting”Completions Not Working
Section titled “Completions Not Working”Bash:
# Check if bash-completion is installeddpkg -l bash-completion # Debian/Ubunturpm -q bash-completion # Fedora/RHEL
# Verify completion filecat ~/.local/share/bash-completion/completions/rust-templateZsh:
# Check fpathecho $fpath
# Verify compinit loadedwhich compinit
# Rebuild completion cacherm -f ~/.zcompdump && compinitFish:
# Check completions directoryls ~/.config/fish/completions/
# Reload completionsfish_update_completionsWrong Completions Shown
Section titled “Wrong Completions Shown”# Clear shell completion cache
# Bashhash -r
# Zshrehash
# Fishcommandline -f repaintBest Practices
Section titled “Best Practices”- Generate at install time - Use build.rs or post-install scripts
- Include in packages - Add to .deb, .rpm, Homebrew formula
- Document installation - Provide clear user instructions
- Test all shells - Verify bash, zsh, fish work correctly
- Use value hints - Improve path/file completion UX
- Provide subcommand help - Add descriptions to all commands