Expand description
shellcomp is a deployment layer for shell completion scripts in Rust CLI projects.
It does not generate completions. Instead, it focuses on the operational work around completions:
- choosing managed default install paths,
- writing completion files idempotently,
- wiring shell startup files when necessary,
- detecting current activation state,
- removing managed files and managed startup blocks,
- returning structured reports and structured failures for caller-side rendering.
Pair it with clap_complete or any other generator when you need to render the script bytes.
§Scope And Non-Goals
shellcomp intentionally keeps a narrow scope:
- it is not a shell completion generator;
- it is not a generic shell configuration manager;
- it does not attempt to understand arbitrary user shell customizations;
- it only modifies completion files it was asked to manage and startup blocks it can identify with stable markers.
This is why the crate can stay small while still being production-usable.
§Supported Shells
Production support currently covers Shell::Bash, Shell::Zsh, Shell::Fish,
Shell::Powershell, and Shell::Elvish. Shell::Other remains the explicit escape
hatch for unsupported shells.
Managed behavior for the supported shells:
Shell::Bash: writes to the XDG data completion directory, then prefers a systembash-completionloader and falls back to a managed~/.bashrcblock when no loader is detected.Shell::Zsh: writes_binary-nameinto the managed zsh completion directory and maintains a managed~/.zshrcblock that updatesfpathand runscompinit -iwhen needed.Shell::Fish: writes directly into Fish’s native completions directory and does not manage a shell startup file.Shell::Powershell: writes a managed completion script file and maintains a managedCurrentUserAllHostsprofile block.Shell::Elvish: writes a managed completion script file and maintains a managedrc.elvblock.
§Public API
The crate is intentionally small:
default_install_pathresolves the managed target path for a shell and binary name.installwrites the completion file and returns anInstallReport.install_with_policylets callers opt into or out of managed activation explicitly.detect_activationinspects the managed setup and returns anActivationReport.detect_activation_at_pathinspects activation for an explicit completion file path.uninstallremoves the managed file and returns aRemoveReport.uninstall_with_policylets callers control whether activation cleanup should be managed.migrate_managed_blocksremoves known legacy markers and rewrites the equivalentshellcomp-managed startup block.render_clap_completionis available behind theclapfeature for users who want the crate to render completion bytes fromclap::CommandFactory.clap_completeis re-exported behind theclapfeature so callers can useshellcomp::clap_complete::Shellwithout pulling conflicting top-levelShellnames into the same scope manually.
§Reading Reports
The public report types are designed so callers can render UX without parsing display strings:
InstallReport::file_changetells you whether the completion file was created, updated, or already matched.ActivationReport::modetells you how the shell will load the completion.ActivationReport::availabilitytells you whether it is active now, available after a new shell, available after sourcing a file, or still requires manual work.ActivationPolicylets callers choose whether installation to a custom path should still attempt managed shell wiring when the shell supports it.RemoveReport::cleanupseparates startup wiring cleanup from completion file removal so a caller can preserve partial progress.FailureReportcarries structured failure kind, relevant paths, and suggested next steps.
§Typical Integration Flow
- Render a completion script with your preferred generator.
- Call
installto place the script into a managed location. - Show the returned
ActivationReportto the user. - Optionally call
detect_activationlater to re-check availability. - Call
uninstallto remove both the completion file and any managed activation wiring.
§Install Example
use shellcomp::{InstallRequest, Shell, install};
let script = b"complete -F _demo demo\n";
let report = install(InstallRequest {
shell: Shell::Bash,
program_name: "demo",
script,
path_override: None,
})?;
println!("installed to {}", report.target_path.display());
println!("activation: {:?}", report.activation);§clap Integration Example
With the clap feature enabled, you can keep the generator-facing shell value under
shellcomp::clap_complete::Shell and convert it into Shell only when you call the
deployment API.
use clap::Parser;
use shellcomp::{InstallRequest, install, render_clap_completion};
#[derive(Parser)]
struct Cli {
#[arg(long)]
verbose: bool,
}
let generator_shell = shellcomp::clap_complete::Shell::Zsh;
let script = render_clap_completion::<Cli>(generator_shell, "demo")?;
let report = install(InstallRequest {
shell: generator_shell.into(),
program_name: "demo",
script: &script,
path_override: None,
})?;
println!("installed to {}", report.target_path.display());§Custom Path Example
Passing InstallRequest::path_override usually tells shellcomp to skip startup wiring and
report manual activation explicitly. The one exception is an override that exactly matches the
shell’s managed default path, which still keeps the default activation semantics.
use std::path::PathBuf;
use shellcomp::{ActivationMode, Availability, InstallRequest, Shell, install};
let report = install(InstallRequest {
shell: Shell::Fish,
program_name: "demo",
script: b"complete -c demo\n",
path_override: Some(PathBuf::from("/tmp/demo.fish")),
})?;
assert_eq!(report.activation.mode, ActivationMode::Manual);
assert_eq!(report.activation.availability, Availability::ManualActionRequired);§Structured Error Handling
High-level operational failures are returned as Error::Failure with a stable
FailureKind. That lets callers keep their own presentation layer while still branching on
machine-readable failure categories.
use std::path::PathBuf;
use shellcomp::{Error, FailureKind, InstallRequest, Shell, install};
let error = install(InstallRequest {
shell: Shell::Fish,
program_name: "demo",
script: b"complete -c demo\n",
path_override: Some(PathBuf::from("/")),
})
.expect_err("path without parent should fail structurally");
match error {
Error::Failure(report) => {
assert_eq!(report.kind, FailureKind::InvalidTargetPath);
}
other => panic!("unexpected error: {other}"),
}Not every error becomes Error::Failure: immediate validation problems like
Error::InvalidProgramName are returned directly.
§Idempotency
Repeating the same install or uninstall operation is expected to be safe:
- identical completion file writes return
FileChange::Unchanged; - repeated removals return
FileChange::Absent; - managed startup blocks are updated in place and removed by stable markers.
This makes the crate suitable for CLI commands that users may run multiple times.
Modules§
- clap_
complete clap - Re-exported
clap_completeshell type for callers that want a namespaced integration surface.
Structs§
- Activation
Report - Structured activation status for an installed completion.
- Cleanup
Report - Structured cleanup status for activation wiring removal.
- Failure
Report - Structured failure report for recoverable operational errors.
- Install
Report - Structured result of a completion install operation.
- Install
Request - Input for a completion install operation.
- Legacy
Managed Block - Caller-provided marker pair for a legacy managed shell block.
- Migrate
Managed Blocks Report - Structured result of migrating legacy managed startup blocks into
shellcomp. - Migrate
Managed Blocks Request - Input for managed-block migration into
shellcompmarkers. - Remove
Report - Structured result of a completion uninstall operation.
- Uninstall
Request - Input for a completion uninstall operation.
Enums§
- Activation
Mode - How a completion becomes active for a shell.
- Activation
Policy - Whether
shellcompshould try to manage activation wiring automatically. - Availability
- Availability state for an installed completion.
- Error
- Errors returned by
shellcompoperations. - Failure
Kind - Stable failure kinds for recoverable operational errors.
- File
Change - Result of a file mutation.
- Operation
- High-level operation associated with a structured failure.
- Shell
- Supported shells for completion installation and detection.
Functions§
- default_
install_ path - Returns the default managed install path for a shell and binary name.
- detect_
activation - Detects how a completion would be activated for the current environment.
- detect_
activation_ at_ path - Detects activation state for an explicit completion file path.
- install
- Installs a completion script and returns a structured report.
- install_
with_ policy - Installs a completion script with explicit activation intent.
- migrate_
managed_ blocks - Removes caller-provided legacy managed markers and upserts the equivalent
shellcompblock. - render_
clap_ completion clap - Renders a completion script from a
clap::CommandFactoryimplementation. - uninstall
- Removes a previously managed completion script and any managed activation wiring.
- uninstall_
with_ policy - Removes a completion script with explicit activation cleanup intent.
Type Aliases§
- Result
- Convenience result type used by all public
shellcompAPIs.