From 54561068e6847bf4d964526d112f4bd761d120cf Mon Sep 17 00:00:00 2001 From: Anton Vasiljev Date: Fri, 22 May 2026 17:59:54 +0300 Subject: [PATCH 1/2] =?UTF-8?q?=F0=9F=8E=89:=20add=20`codanna=20completion?= =?UTF-8?q?s`=20subcommand?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Generate bash/zsh/fish/elvish/powershell scripts via clap_complete - Emit before any config/index setup runs - Surface previously-hidden `profile` + new `completions` in help --- Cargo.lock | 10 ++++++++++ Cargo.toml | 1 + src/cli/args.rs | 15 +++++++++++++++ src/main.rs | 13 +++++++++++++ 4 files changed, 39 insertions(+) diff --git a/Cargo.lock b/Cargo.lock index d1cbc7b..26a5bc7 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -753,6 +753,15 @@ dependencies = [ "strsim", ] +[[package]] +name = "clap_complete" +version = "4.6.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e0a7a9bfdb35811f9e59832f0f05975114d2251b415fb534108e6f34060fd772" +dependencies = [ + "clap", +] + [[package]] name = "clap_derive" version = "4.6.1" @@ -782,6 +791,7 @@ dependencies = [ "bitflags 2.11.0", "chrono", "clap", + "clap_complete", "comfy-table", "console 0.16.3", "criterion", diff --git a/Cargo.toml b/Cargo.toml index 62cb5cf..95d5e28 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -39,6 +39,7 @@ bin-dir = "{ name }-{ version }-windows-x64/{ bin }{ binary-ext }" anyhow = "1.0.102" bitflags = "2.11.0" clap = { version = "4.6.1", features = ["derive", "color", "env"] } +clap_complete = "4.6" crossbeam-channel = "0.5.15" dashmap = "6.2.1" dirs = "6.0.0" diff --git a/src/cli/args.rs b/src/cli/args.rs index bacdadb..2281826 100644 --- a/src/cli/args.rs +++ b/src/cli/args.rs @@ -6,6 +6,7 @@ use clap::{ Parser, Subcommand, builder::styling::{AnsiColor, Effects, Styles}, }; +use clap_complete::Shell; use std::path::PathBuf; fn clap_cargo_style() -> Styles { @@ -69,6 +70,8 @@ fn create_custom_help() -> String { help.push_str(" parse Output AST nodes in JSONL format\n"); help.push_str(" plugin Manage Claude Code plugins\n"); help.push_str(" documents Index and search document collections\n"); + help.push_str(" profile Initialize and manage project profiles\n"); + help.push_str(" completions Generate shell completion scripts\n"); help.push_str(" help Print this message or the help of the given subcommand(s)\n\n"); help.push_str("See 'codanna help ' for more information on a specific command.\n\n"); @@ -349,6 +352,18 @@ pub enum Commands { #[command(subcommand)] action: crate::profiles::commands::ProfileAction, }, + + /// Generate shell completion scripts + #[command( + about = "Generate shell completion scripts", + long_about = "Generate a shell completion script for the given shell and print it to stdout.\n\nRedirect the output to your shell's completion directory, or source it directly in the current session.", + after_help = "Examples:\n codanna completions bash > ~/.local/share/bash-completion/completions/codanna\n codanna completions zsh > ~/.zsh/completions/_codanna\n codanna completions fish > ~/.config/fish/completions/codanna.fish\n source <(codanna completions bash) # current session only" + )] + Completions { + /// Shell to generate completions for + #[arg(value_enum)] + shell: Shell, + }, } /// Plugin management actions diff --git a/src/main.rs b/src/main.rs index 38e76bd..60acf25 100644 --- a/src/main.rs +++ b/src/main.rs @@ -197,6 +197,16 @@ fn seed_indexer_with_config_paths( async fn main() { let cli = Cli::parse(); + // Shell completions are pure stdout output: emit and exit before any + // config loading, index opening, or provider setup runs. + if let Commands::Completions { shell } = &cli.command { + use clap::CommandFactory; + let mut cmd = Cli::command(); + let bin_name = cmd.get_name().to_string(); + clap_complete::generate(*shell, &mut cmd, bin_name, &mut std::io::stdout()); + return; + } + // For index command, auto-initialize if needed (but not when using --config) if matches!(cli.command, Commands::Index { .. }) && cli.config.is_none() { if Settings::check_init().is_err() { @@ -785,6 +795,9 @@ async fn main() { Commands::Profile { action } => { codanna::cli::commands::profile::run(action); } + + // Handled immediately after argument parsing, before any setup runs. + Commands::Completions { .. } => unreachable!("completions are emitted before dispatch"), } } From b221af526875a092e45727e97c3870629dd63046 Mon Sep 17 00:00:00 2001 From: Anton Vasiljev Date: Fri, 22 May 2026 18:00:01 +0300 Subject: [PATCH 2/2] =?UTF-8?q?=E2=9C=A8:=20ship=20shell=20completions=20f?= =?UTF-8?q?rom=20the=20nix=20package?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - postInstall installs bash/zsh/fish completions via installShellFiles - bump rust-overlay to rustc 1.95 (Cargo.lock sysinfo 0.39.2 needs >=1.95) --- flake.lock | 6 +++--- flake.nix | 13 ++++++++++++- 2 files changed, 15 insertions(+), 4 deletions(-) diff --git a/flake.lock b/flake.lock index fe87324..41c6248 100644 --- a/flake.lock +++ b/flake.lock @@ -109,11 +109,11 @@ ] }, "locked": { - "lastModified": 1774062094, - "narHash": "sha256-ba3c+hS7KzEiwtZRGHagIAYdcmdY3rCSWVCyn64rx7s=", + "lastModified": 1779419951, + "narHash": "sha256-dMX0PUslUHPajP6o8FEoRdFv9afq/dec4POR0vVfjK4=", "owner": "oxalica", "repo": "rust-overlay", - "rev": "c807e83cc2e32adc35f51138b3bdef722c0812ab", + "rev": "5b5c521d6cae9ef4aa32f888eb2c0ce595c9be52", "type": "github" }, "original": { diff --git a/flake.nix b/flake.nix index 381c3df..6c7d763 100644 --- a/flake.nix +++ b/flake.nix @@ -58,7 +58,10 @@ # ABI mismatch causes silent runtime corruption. Verify after nixpkgs updates. pkgs.onnxruntime ]; - nativeBuildInputs = [ pkgs.pkg-config ]; + nativeBuildInputs = [ + pkgs.pkg-config + pkgs.installShellFiles + ]; cargoBuildOptions = x: x @@ -67,6 +70,14 @@ "codanna" ]; ORT_SKIP_DOWNLOAD = "1"; + # Generate shell completions from the just-built binary (naersk runs + # postInstall only on the top-level build, not the deps build). + postInstall = '' + installShellCompletion --cmd codanna \ + --bash <($out/bin/codanna completions bash) \ + --zsh <($out/bin/codanna completions zsh) \ + --fish <($out/bin/codanna completions fish) + ''; }; } );