From ba7b445348382c7788cae2309968842c14d40be2 Mon Sep 17 00:00:00 2001 From: Ajeet D'Souza <98ajeet@gmail.com> Date: Sun, 31 Oct 2021 20:16:40 +0530 Subject: [PATCH] Improved completions for Fish --- CHANGELOG.md | 2 +- build.rs | 2 +- src/shell.rs | 27 +++++++++++++++++++++++---- templates/bash.txt | 2 +- templates/fish.txt | 34 +++++++++++----------------------- templates/posix.txt | 2 +- 6 files changed, 38 insertions(+), 31 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index a8836bd..156c119 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -11,7 +11,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Changed -- Bash: improved completions for `z` command. +- Bash/Fish: improved completions for `z` command. ### Fixed diff --git a/build.rs b/build.rs index aef6d7f..deeedc6 100644 --- a/build.rs +++ b/build.rs @@ -22,7 +22,7 @@ fn main() { fn git_version() -> Option { let dir = env!("CARGO_MANIFEST_DIR"); let mut git = Command::new("git"); - git.args(&["-C", &dir, "describe", "--tags", "--match=v*.*.*", "--always", "--broken"]); + git.args(&["-C", dir, "describe", "--tags", "--match=v*.*.*", "--always", "--broken"]); let output = git.output().ok()?; if !output.status.success() || output.stdout.is_empty() || !output.stderr.is_empty() { diff --git a/src/shell.rs b/src/shell.rs index fd9a28e..ce588cf 100644 --- a/src/shell.rs +++ b/src/shell.rs @@ -162,9 +162,8 @@ mod tests { let tempdir = tempfile::tempdir().unwrap(); let tempdir = tempdir.path().to_str().unwrap(); - Command::new("fish") + Command::new("fish_indent") .env("HOME", tempdir) - .args(&["--command", "fish_indent", "--private"]) .write_stdin(source.to_string()) .assert() .success() @@ -193,6 +192,26 @@ mod tests { } } + #[rstest] + fn posix_bash( + #[values(None, Some("z"))] cmd: Option<&str>, + #[values(InitHook::None, InitHook::Prompt, InitHook::Pwd)] hook: InitHook, + #[values(false, true)] echo: bool, + #[values(false, true)] resolve_symlinks: bool, + ) { + let opts = Opts { cmd, hook, echo, resolve_symlinks }; + let source = Posix(&opts).render().unwrap(); + + let assert = Command::new("bash") + .args(&["--posix", "--noprofile", "--norc", "-e", "-u", "-o", "pipefail", "-c", &source]) + .assert() + .success() + .stderr(""); + if opts.hook != InitHook::Pwd { + assert.stdout(""); + } + } + #[rstest] fn posix_dash( #[values(None, Some("z"))] cmd: Option<&str>, @@ -203,7 +222,7 @@ mod tests { let opts = Opts { cmd, hook, echo, resolve_symlinks }; let source = Posix(&opts).render().unwrap(); - let assert = Command::new("dash").args(&["-c", &source]).assert().success().stderr(""); + let assert = Command::new("dash").args(&["-c", &source, "-e", "-u"]).assert().success().stderr(""); if opts.hook != InitHook::Pwd { assert.stdout(""); } @@ -361,7 +380,7 @@ mod tests { let source = Zsh(&opts).render().unwrap(); Command::new("zsh") - .args(&["-c", &source, "--no-globalrcs", "--no-rcs"]) + .args(&["-c", &source, "-e", "-u", "-o", "pipefail", "--no-globalrcs", "--no-rcs"]) .assert() .success() .stdout("") diff --git a/templates/bash.txt b/templates/bash.txt index 9a41a04..19ac804 100644 --- a/templates/bash.txt +++ b/templates/bash.txt @@ -124,7 +124,7 @@ if [[ :"${SHELLOPTS}": =~ :(vi|emacs): && ${TERM} != 'dumb' ]]; then # If there is only one argument, use `cd` completions. if [[ {{ "${#COMP_WORDS[@]}" }} -eq 2 ]]; then \builtin mapfile -t COMPREPLY < <(compgen -A directory -S / -- "${COMP_WORDS[-1]}") - # Otherwise, use interactive selection. + # If there is a space after the last word, use interactive selection. elif [[ -z ${COMP_WORDS[-1]} ]]; then \local result result="$( diff --git a/templates/fish.txt b/templates/fish.txt index f081360..c8e8e5a 100644 --- a/templates/fish.txt +++ b/templates/fish.txt @@ -74,31 +74,19 @@ end # Completions for `z`. function __zoxide_z_complete - set -l trigger '**' - set -l trigger_length (string length $trigger) + set -l tokens (commandline -op) + set -l curr_tokens (commandline -cop) - set -l line (commandline -op) - set -l interactive 0 - if test (string sub -s "-$trigger_length" $line[-1]) = $trigger - set line[-1] (string sub -e "-$trigger_length" $line[-1]) - set interactive 1 + if test (count $tokens) -le 2 -a (count $curr_tokens) -eq 1 + # If there is only one argument, use `cd` completions. + __fish_complete_directories "$tokens[2]" '' + else + # Otherwise, use interactive selection. + set -l query $tokens[2..-1] + set -l result (_ZO_FZF_OPTS='{{ crate::shell::FZF_COMPLETE_OPTS }}' zoxide query -i -- $query) + and commandline -p "$tokens[1] "(string escape $result) + commandline -f repaint end - - set -l query $line[2..-1] - if test $interactive -eq 0 -a (count (commandline -cop)) -le 1 - __fish_complete_directories "$query" '' - return - end - set -l result (_ZO_FZF_OPTS='{{ crate::shell::FZF_COMPLETE_OPTS }}' zoxide query -i -- $query) - set -l exit $status - if test $exit -ne 0 - test $exit -eq 130 - and commandline -p "$line" - return - end - - set -l cmd $line[1] - commandline -p "$cmd "(string escape $result) end # Jump to a directory using interactive search. diff --git a/templates/posix.txt b/templates/posix.txt index 8598a5d..65b356d 100644 --- a/templates/posix.txt +++ b/templates/posix.txt @@ -35,7 +35,7 @@ __zoxide_hook() { } # Initialize hook. -if [ "${PS1#*\$(__zoxide_hook)}" = "${PS1}" ]; then +if [ "${PS1:=}" = "${PS1#*\$(__zoxide_hook)}" ]; then PS1="${PS1}\$(__zoxide_hook)" fi