Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(clap-complete): implemented Generator for Clink autocompletions #5379

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
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;