Skip to content

Commit

Permalink
feat(clap-complete): implemented Generator for Clink autocompletions
Browse files Browse the repository at this point in the history
  • Loading branch information
wabo225 committed Feb 28, 2024
1 parent d0028d7 commit 9982a5d
Show file tree
Hide file tree
Showing 6 changed files with 138 additions and 0 deletions.
96 changes: 96 additions & 0 deletions clap_complete/src/shells/clink.rs
@@ -0,0 +1,96 @@
use crate::{generator::utils, Generator};
use clap::*;
use std::fmt::Write;

/// Generate clink completion lua script
#[derive(Copy, Clone, PartialEq, Eq, Debug)]
pub struct Clink;

impl Generator for Clink {
fn file_name(&self, name: &str) -> String {
format!("{name}.lua")
}

fn generate(&self, cmd: &clap::Command, buf: &mut dyn std::io::prelude::Write) {
let bin_name = cmd
.get_bin_name()
.expect("crate::generate should have set the bin_name");

let result = format!(
r#"clink.argmatcher("{bin_name}")
{}"#,
generate_inner(cmd, 0)
);
w!(buf, result.as_bytes());
}
}

fn generate_inner(p: &Command, depth: usize) -> String {
let mut b = String::new();
let indent = " ".repeat(depth * 4);

for opt in p.get_opts() {
writeln!(b, "{}:addarg(\"--{}\")", indent, opt.get_id()).unwrap();
if let Some(help) = opt.get_help() {
writeln!(
b,
"{}:adddescriptions({{\"--{}\", description = \"{}\"}})",
indent,
opt.get_id(),
help
)
.unwrap();
if let Some(short) = opt.get_short() {
writeln!(
b,
"{}:adddescriptions({{\"-{}\", description = \"{}\"}})",
indent, short, help
)
.unwrap()
}
}
}

for flag in utils::flags(p) {
if let Some(shorts) = flag.get_short_and_visible_aliases() {
for short in shorts {
writeln!(b, "{}:addflags(\"-{}\")", indent, short).unwrap();
if let Some(help) = flag.get_help() {
writeln!(
b,
"{}:adddescriptions({{\"-{}\", description = \"{}\"}})",
indent, short, help
)
.unwrap();
}
}
}
if let Some(longs) = flag.get_long_and_visible_aliases() {
for long in longs {
writeln!(b, "{}:addflags(\"--{}\")", indent, long).unwrap();
if let Some(help) = flag.get_help() {
writeln!(
b,
"{}:adddescriptions({{\"--{}\", description = \"{}\"}})",
indent, long, help
)
.unwrap();
}
}
}
}

for sub_cmd in p.get_subcommands() {
writeln!(
b,
"{}:addarg({{ \"{}\" .. clink.argmatcher()\n{}{}}})",
indent,
sub_cmd.get_name(),
generate_inner(sub_cmd, depth + 1),
indent
)
.unwrap();
}

b
}
2 changes: 2 additions & 0 deletions clap_complete/src/shells/mod.rs
Expand Up @@ -6,10 +6,12 @@ mod fish;
mod powershell;
mod shell;
mod zsh;
mod clink;

pub use bash::Bash;
pub use elvish::Elvish;
pub use fish::Fish;
pub use powershell::PowerShell;
pub use shell::Shell;
pub use zsh::Zsh;
pub use clink::Clink;
5 changes: 5 additions & 0 deletions clap_complete/src/shells/shell.rs
Expand Up @@ -22,6 +22,8 @@ pub enum Shell {
PowerShell,
/// Z SHell (zsh)
Zsh,
/// Clink
Clink,
}

impl Display for Shell {
Expand Down Expand Up @@ -65,6 +67,7 @@ impl ValueEnum for Shell {
Shell::Fish => PossibleValue::new("fish"),
Shell::PowerShell => PossibleValue::new("powershell"),
Shell::Zsh => PossibleValue::new("zsh"),
Shell::Clink => PossibleValue::new("clink"),
})
}
}
Expand All @@ -77,6 +80,7 @@ impl Generator for Shell {
Shell::Fish => shells::Fish.file_name(name),
Shell::PowerShell => shells::PowerShell.file_name(name),
Shell::Zsh => shells::Zsh.file_name(name),
Shell::Clink => shells::Clink.file_name(name),
}
}

Expand All @@ -87,6 +91,7 @@ impl Generator for Shell {
Shell::Fish => shells::Fish.generate(cmd, buf),
Shell::PowerShell => shells::PowerShell.generate(cmd, buf),
Shell::Zsh => shells::Zsh.generate(cmd, buf),
Shell::Clink => shells::Clink.generate(cmd, buf),
}
}
}
Expand Down
21 changes: 21 additions & 0 deletions clap_complete/tests/snapshots/basic.lua
@@ -0,0 +1,21 @@
clink.argmatcher("my-app")
:addflags("-c")
:addflags("-v")
:addflags("-h")
:adddescriptions({"-h", description = "Print help"})
:addflags("--help")
:adddescriptions({"--help", description = "Print help"})
:addarg({ "test" .. clink.argmatcher()
:addflags("-d")
:addflags("-c")
:addflags("-h")
:adddescriptions({"-h", description = "Print help"})
:addflags("--help")
:adddescriptions({"--help", description = "Print help"})
})
:addarg({ "help" .. clink.argmatcher()
:addarg({ "test" .. clink.argmatcher()
})
:addarg({ "help" .. clink.argmatcher()
})
})
13 changes: 13 additions & 0 deletions clap_complete/tests/testsuite/clink.rs
@@ -0,0 +1,13 @@
use crate::common;

#[test]
fn basic() {
let name = "my-app";
let cmd = common::basic_command(name);
common::assert_matches(
snapbox::file!["../snapshots/basic.lua"],
clap_complete::shells::Clink,
cmd,
name,
);
}
1 change: 1 addition & 0 deletions clap_complete/tests/testsuite/main.rs
Expand Up @@ -6,3 +6,4 @@ mod fish;
mod general;
mod powershell;
mod zsh;
mod clink;

0 comments on commit 9982a5d

Please sign in to comment.