Skip to content

Commit c37911d

Browse files
committed
feat: add shell completions
1 parent a342191 commit c37911d

File tree

3 files changed

+52
-2
lines changed

3 files changed

+52
-2
lines changed

Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ members = [
1919
async-trait = "0.1"
2020
repos-github = { path = "common/repos-github" }
2121
clap = { version = "4.4", features = ["derive"] }
22+
clap_complete = "4.4"
2223
serde = { version = "1.0", features = ["derive"] }
2324
serde_yaml = "0.9"
2425
serde_json = "1.0"

README.md

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,38 @@ cargo build --release
6666
sudo cp target/release/repos /usr/local/bin/
6767
```
6868

69+
### Shell Completions
70+
71+
`repos` can generate shell completions for zsh, bash, fish, PowerShell, and elvish.
72+
73+
#### Zsh
74+
75+
```bash
76+
# Generate completions
77+
repos completions zsh > ~/.zsh/completions/_repos
78+
79+
# Or for Oh My Zsh
80+
mkdir -p ~/.oh-my-zsh/custom/plugins/repos-completions
81+
repos completions zsh > ~/.oh-my-zsh/custom/plugins/repos-completions/_repos
82+
83+
# Add to your .zshrc
84+
fpath=(~/.zsh/completions $fpath)
85+
autoload -Uz compinit && compinit
86+
```
87+
88+
#### Bash
89+
90+
```bash
91+
repos completions bash > ~/.repos-completion.bash
92+
echo 'source ~/.repos-completion.bash' >> ~/.bashrc
93+
```
94+
95+
#### Fish
96+
97+
```bash
98+
repos completions fish > ~/.config/fish/completions/repos.fish
99+
```
100+
69101
## Quick Start
70102

71103
The easiest way to get started is to let `repos` generate a configuration file

src/main.rs

Lines changed: 19 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,9 @@
11
use anyhow::Result;
2-
use clap::{Parser, Subcommand};
2+
use clap::{CommandFactory, Parser, Subcommand};
3+
use clap_complete::{Shell, generate};
34
use repos::commands::validators;
45
use repos::{commands::*, config::Config, constants, plugins};
5-
use std::{env, path::PathBuf};
6+
use std::{env, io, path::PathBuf};
67

78
#[derive(Parser)]
89
#[command(name = "repos")]
@@ -193,6 +194,13 @@ enum Commands {
193194
supplement: bool,
194195
},
195196

197+
/// Generate shell completions
198+
Completions {
199+
/// Shell to generate completions for
200+
#[arg(value_enum)]
201+
shell: Shell,
202+
},
203+
196204
/// External plugin command
197205
#[command(external_subcommand)]
198206
External(Vec<String>),
@@ -221,6 +229,11 @@ async fn main() -> Result<()> {
221229

222230
// Handle commands
223231
match cli.command {
232+
Some(Commands::Completions { shell }) => {
233+
let mut cmd = Cli::command();
234+
generate(shell, &mut cmd, "repos", &mut io::stdout());
235+
return Ok(());
236+
}
224237
Some(Commands::External(args)) => {
225238
if args.is_empty() {
226239
anyhow::bail!("External command provided but no arguments given");
@@ -502,6 +515,10 @@ async fn execute_builtin_command(command: Commands) -> Result<()> {
502515
.execute(&context)
503516
.await?;
504517
}
518+
Commands::Completions { .. } => {
519+
// Handled in main(), this should not be reached
520+
unreachable!("Completions command should be handled in main()")
521+
}
505522
}
506523

507524
Ok(())

0 commit comments

Comments
 (0)