mirror of
https://github.com/alexpasmantier/television.git
synced 2025-07-28 22:01:39 +00:00
feat: implement tv option autocompletion
This commit is contained in:
parent
39610e145d
commit
e588610b18
10
Cargo.lock
generated
10
Cargo.lock
generated
@ -305,6 +305,15 @@ dependencies = [
|
||||
"strsim",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "clap_complete"
|
||||
version = "4.5.55"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a5abde44486daf70c5be8b8f8f1b66c49f86236edf6fa2abadb4d961c4c6229a"
|
||||
dependencies = [
|
||||
"clap",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "clap_derive"
|
||||
version = "4.5.40"
|
||||
@ -1989,6 +1998,7 @@ dependencies = [
|
||||
"base64",
|
||||
"better-panic",
|
||||
"clap",
|
||||
"clap_complete",
|
||||
"clap_mangen",
|
||||
"clipboard-win",
|
||||
"colored",
|
||||
|
@ -51,6 +51,7 @@ serde_json = "1.0.140"
|
||||
colored = "3.0.0"
|
||||
serde_with = "3.13.0"
|
||||
which = "8.0.0"
|
||||
clap_complete = "4.5.55"
|
||||
|
||||
|
||||
# target specific dependencies
|
||||
|
@ -1,10 +1,11 @@
|
||||
use crate::{
|
||||
cli::args::Shell as CliShell,
|
||||
cli::args::{Cli, Shell as CliShell},
|
||||
config::shell_integration::ShellIntegrationConfig,
|
||||
};
|
||||
use anyhow::Result;
|
||||
use clap::CommandFactory;
|
||||
use std::fmt::Display;
|
||||
use tracing::debug;
|
||||
use tracing::{debug, warn};
|
||||
|
||||
#[derive(Debug, Clone, Copy, PartialEq)]
|
||||
pub enum Shell {
|
||||
@ -28,6 +29,31 @@ impl Default for Shell {
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub enum ShellError {
|
||||
UnsupportedShell(String),
|
||||
}
|
||||
|
||||
impl TryFrom<Shell> for clap_complete::Shell {
|
||||
type Error = ShellError;
|
||||
|
||||
fn try_from(value: Shell) -> std::result::Result<Self, Self::Error> {
|
||||
match value {
|
||||
Shell::Bash => Ok(clap_complete::Shell::Bash),
|
||||
Shell::Zsh => Ok(clap_complete::Shell::Zsh),
|
||||
Shell::Fish => Ok(clap_complete::Shell::Fish),
|
||||
Shell::PowerShell => Ok(clap_complete::Shell::PowerShell),
|
||||
Shell::Cmd => Err(ShellError::UnsupportedShell(
|
||||
"Cmd shell is not supported for completion scripts"
|
||||
.to_string(),
|
||||
)),
|
||||
Shell::Nu => Err(ShellError::UnsupportedShell(
|
||||
"Nu shell is not supported for completion scripts".to_string(),
|
||||
)),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Display for Shell {
|
||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||
match self {
|
||||
@ -143,6 +169,7 @@ pub fn render_autocomplete_script_template(
|
||||
template: &str,
|
||||
config: &ShellIntegrationConfig,
|
||||
) -> Result<String> {
|
||||
// Custom autocomplete
|
||||
let script = template
|
||||
.replace(
|
||||
"{tv_smart_autocomplete_keybinding}",
|
||||
@ -158,7 +185,33 @@ pub fn render_autocomplete_script_template(
|
||||
config.get_command_history_keybinding_character(),
|
||||
)?,
|
||||
);
|
||||
Ok(script)
|
||||
|
||||
let clap_autocomplete =
|
||||
render_clap_autocomplete(shell).unwrap_or_default();
|
||||
|
||||
Ok(clap_autocomplete + &script)
|
||||
}
|
||||
|
||||
fn render_clap_autocomplete(shell: Shell) -> Option<String> {
|
||||
// Clap autocomplete
|
||||
let mut clap_autocomplete = vec![];
|
||||
let mut cmd = Cli::command();
|
||||
let clap_shell: clap_complete::Shell = match shell.try_into() {
|
||||
Ok(shell) => shell,
|
||||
Err(err) => {
|
||||
warn!("Failed to convert shell {:?}: {:?}", shell, err);
|
||||
return None;
|
||||
}
|
||||
};
|
||||
|
||||
clap_complete::aot::generate(
|
||||
clap_shell,
|
||||
&mut cmd,
|
||||
"tv", // the command defines the name as "television"
|
||||
&mut clap_autocomplete,
|
||||
);
|
||||
|
||||
String::from_utf8(clap_autocomplete).ok()
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
@ -208,4 +261,30 @@ mod tests {
|
||||
assert!(result.is_ok());
|
||||
assert_eq!(result.unwrap(), "Ctrl-s");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_zsh_clap_completion() {
|
||||
let shell = Shell::Zsh;
|
||||
let result = render_autocomplete_script_template(
|
||||
shell,
|
||||
"",
|
||||
&ShellIntegrationConfig::default(),
|
||||
);
|
||||
assert!(result.is_ok());
|
||||
let result = result.unwrap();
|
||||
assert!(result.contains("compdef _tv tv"));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_unsupported_clap_completion() {
|
||||
let shell = Shell::Nu;
|
||||
let result = render_autocomplete_script_template(
|
||||
shell,
|
||||
"",
|
||||
&ShellIntegrationConfig::default(),
|
||||
);
|
||||
assert!(result.is_ok());
|
||||
let result = result.unwrap();
|
||||
assert!(result.is_empty());
|
||||
}
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user