Merge 624c485d68f9bee39d8a34940e87acbae2800c11 into aac7e4dc4570d5e0caf305b738009f2b077da7be

This commit is contained in:
Alex Pasmantier 2025-05-27 15:56:14 -04:00 committed by GitHub
commit 028aa1f277
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
4 changed files with 80 additions and 0 deletions

View File

@ -90,3 +90,7 @@ source_command = "sed '1!G;h;$!d' ${HISTFILE:-${HOME}/.bash_history}"
[[cable_channel]] [[cable_channel]]
name = "fish-history" name = "fish-history"
source_command = "fish -c 'history'" source_command = "fish -c 'history'"
[[cable_channel]]
name = "nu-history"
source_command = "nu -c 'history'"

View File

@ -177,6 +177,7 @@ pub enum Shell {
Fish, Fish,
PowerShell, PowerShell,
Cmd, Cmd,
Nu,
} }
#[allow(clippy::unnecessary_wraps)] #[allow(clippy::unnecessary_wraps)]

View File

@ -12,6 +12,7 @@ pub enum Shell {
Fish, Fish,
PowerShell, PowerShell,
Cmd, Cmd,
Nu,
} }
impl Default for Shell { impl Default for Shell {
@ -78,6 +79,7 @@ impl Shell {
Shell::Fish => "fish", Shell::Fish => "fish",
Shell::PowerShell => "powershell", Shell::PowerShell => "powershell",
Shell::Cmd => "cmd", Shell::Cmd => "cmd",
Shell::Nu => "nu",
} }
} }
} }
@ -90,6 +92,7 @@ impl From<CliShell> for Shell {
CliShell::Fish => Shell::Fish, CliShell::Fish => Shell::Fish,
CliShell::PowerShell => Shell::PowerShell, CliShell::PowerShell => Shell::PowerShell,
CliShell::Cmd => Shell::Cmd, CliShell::Cmd => Shell::Cmd,
CliShell::Nu => Shell::Nu,
} }
} }
} }
@ -102,6 +105,7 @@ impl From<&CliShell> for Shell {
CliShell::Fish => Shell::Fish, CliShell::Fish => Shell::Fish,
CliShell::PowerShell => Shell::PowerShell, CliShell::PowerShell => Shell::PowerShell,
CliShell::Cmd => Shell::Cmd, CliShell::Cmd => Shell::Cmd,
CliShell::Nu => Shell::Nu,
} }
} }
} }
@ -109,6 +113,7 @@ impl From<&CliShell> for Shell {
const COMPLETION_ZSH: &str = include_str!("shell/completion.zsh"); const COMPLETION_ZSH: &str = include_str!("shell/completion.zsh");
const COMPLETION_BASH: &str = include_str!("shell/completion.bash"); const COMPLETION_BASH: &str = include_str!("shell/completion.bash");
const COMPLETION_FISH: &str = include_str!("shell/completion.fish"); const COMPLETION_FISH: &str = include_str!("shell/completion.fish");
const COMPLETION_NU: &str = include_str!("shell/completion.nu");
// create the appropriate key binding for each supported shell // create the appropriate key binding for each supported shell
pub fn ctrl_keybinding(shell: Shell, character: char) -> Result<String> { pub fn ctrl_keybinding(shell: Shell, character: char) -> Result<String> {
@ -116,6 +121,7 @@ pub fn ctrl_keybinding(shell: Shell, character: char) -> Result<String> {
Shell::Bash => Ok(format!(r"\C-{character}")), Shell::Bash => Ok(format!(r"\C-{character}")),
Shell::Zsh => Ok(format!(r"^{character}")), Shell::Zsh => Ok(format!(r"^{character}")),
Shell::Fish => Ok(format!(r"\c{character}")), Shell::Fish => Ok(format!(r"\c{character}")),
Shell::Nu => Ok(format!(r"Ctrl-{character}")),
_ => anyhow::bail!("This shell is not yet supported: {:?}", shell), _ => anyhow::bail!("This shell is not yet supported: {:?}", shell),
} }
} }
@ -125,6 +131,7 @@ pub fn completion_script(shell: Shell) -> Result<&'static str> {
Shell::Bash => Ok(COMPLETION_BASH), Shell::Bash => Ok(COMPLETION_BASH),
Shell::Zsh => Ok(COMPLETION_ZSH), Shell::Zsh => Ok(COMPLETION_ZSH),
Shell::Fish => Ok(COMPLETION_FISH), Shell::Fish => Ok(COMPLETION_FISH),
Shell::Nu => Ok(COMPLETION_NU),
_ => anyhow::bail!("This shell is not yet supported: {:?}", shell), _ => anyhow::bail!("This shell is not yet supported: {:?}", shell),
} }
} }
@ -190,4 +197,13 @@ mod tests {
let result = ctrl_keybinding(shell, character); let result = ctrl_keybinding(shell, character);
assert!(result.is_err()); assert!(result.is_err());
} }
#[test]
fn test_nushell_ctrl_keybinding() {
let character = 's';
let shell = Shell::Nu;
let result = ctrl_keybinding(shell, character);
assert!(result.is_ok());
assert_eq!(result.unwrap(), "Ctrl-s");
}
} }

View File

@ -0,0 +1,59 @@
def tv_smart_autocomplete [] {
let current_prompt = (commandline)
let cursor = (commandline get-cursor)
let current_prompt = ($current_prompt | str substring 0..$cursor)
let output = (tv --autocomplete-prompt $current_prompt | str trim)
if ($output | str length) > 0 {
let needs_space = not ($current_prompt | str ends-with " ")
let new_prompt = if $needs_space { $"($current_prompt) " + $output } else { $current_prompt + $output }
}
# Update the line editor with the new prompt
if ($output | is-not-empty) {
commandline edit --replace $output
commandline set-cursor --end
}
}
def tv_shell_history [] {
let current_prompt = (commandline)
let cursor = (commandline get-cursor)
let current_prompt = ($current_prompt | str substring 0..$cursor)
let output = (tv nu-history --input $current_prompt | str trim)
if ($output | is-not-empty) {
commandline edit --replace $output
commandline set-cursor --end
}
}
# Bind custom keybindings
$env.config = (
$env.config
| upsert keybindings [
{
name: tv_completion,
modifier: Control,
keycode: char_t,
mode: [vi_normal, vi_insert, emacs],
event: {
send: executehostcommand,
cmd: "tv_smart_autocomplete"
}
}
{
name: tv_history,
modifier: Control,
keycode: char_r,
mode: [vi_normal, vi_insert, emacs],
event: {
send: executehostcommand,
cmd: "tv_shell_history"
}
}
]
)