Add bash/elvish completions for z (#257)

This commit is contained in:
Ajeet D'Souza 2021-09-04 16:01:50 +05:30 committed by GitHub
parent a80f20520e
commit ecc64be909
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
7 changed files with 113 additions and 54 deletions

View File

@ -9,6 +9,10 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
## Unreleased
### Added
- Bash/Elvish: completions for `z` command.
### Changed
- Nushell: upgrade minimum supported version to v0.36.0.

View File

@ -35,29 +35,29 @@ function __zoxide_cd() {
{%- when InitHook::Prompt %}
function __zoxide_hook() {
\builtin local -r __zoxide_retval="$?"
\builtin local -r retval="$?"
zoxide add -- "$(__zoxide_pwd)"
return "${__zoxide_retval}"
return "${retval}"
}
{%- when InitHook::Pwd %}
function __zoxide_hook() {
\builtin local -r __zoxide_retval="$?"
\builtin local -r __zoxide_pwd_tmp="$(__zoxide_pwd)"
\builtin local -r retval="$?"
\builtin local -r pwd_tmp="$(__zoxide_pwd)"
if [ -z "${__zoxide_pwd_old}" ]; then
__zoxide_pwd_old="${__zoxide_pwd_tmp}"
elif [ "${__zoxide_pwd_old}" != "${__zoxide_pwd_tmp}" ]; then
__zoxide_pwd_old="${__zoxide_pwd_tmp}"
__zoxide_pwd_old="${pwd_tmp}"
elif [ "${__zoxide_pwd_old}" != "${pwd_tmp}" ]; then
__zoxide_pwd_old="${pwd_tmp}"
zoxide add -- "${__zoxide_pwd_old}"
fi
return "${__zoxide_retval}"
return "${retval}"
}
{%- endmatch %}
{# bash throws an error if $PROMPT_COMMAND contains two semicolons in sequence.
# This is hard to avoid perfectly, but adding __zoxide_hook to the front of
# $PROMPT_COMMAND rather than the back makes this scenario unlikely. -#}
{# $PROMPT_COMMAND cannot contain two semicolons in sequence. It can end with a
# semicolon, but it cannot start with one. Therefore, always put the hook
# at the start of $PROMPT_COMMAND. -#}
# Initialize hook.
if [ "${__zoxide_hooked}" != '1' ]; then
@ -93,15 +93,15 @@ function __zoxide_z() {
elif [ "$#" -eq 1 ] && [ -d "$1" ]; then
__zoxide_cd "$1"
else
\builtin local __zoxide_result
__zoxide_result="$(zoxide query --exclude "$(__zoxide_pwd)" -- "$@")" && __zoxide_cd "${__zoxide_result}"
\builtin local result
result="$(zoxide query --exclude "$(__zoxide_pwd)" -- "$@")" && __zoxide_cd "${result}"
fi
}
# Jump to a directory using interactive search.
function __zoxide_zi() {
\builtin local __zoxide_result
__zoxide_result="$(zoxide query -i -- "$@")" && __zoxide_cd "${__zoxide_result}"
\builtin local result
result="$(zoxide query -i -- "$@")" && __zoxide_cd "${result}"
}
{{ section }}
@ -128,6 +128,39 @@ function {{cmd}}i() {
__zoxide_zi "$@"
}
# Load completions.
{# This requires line editing. Since Bash supports only two modes of line
# editing (`vim` and `emacs`), we check if one of them is enabled. -#}
if [[ :"${SHELLOPTS}": =~ :(vi|emacs): ]] && [ "${TERM}" != 'dumb' ]; then
{# Use `printf '\e[5n'` to redraw line after fzf closes. -#}
\builtin bind '"\e[0n": redraw-current-line' &>/dev/null
function __zoxide_z_complete() {
[ {{ "${#COMP_WORDS[@]}" }} -eq 2 ] || return
\builtin local -r trigger='**'
\builtin local query="${COMP_WORDS[1]}"
if [[ ${query} == *"${trigger}" ]]; then
query="${query:0:$(({{ "${#query} - ${#trigger}" }}))}"
COMPREPLY=("$(_ZO_FZF_OPTS="\
--bind=ctrl-z:ignore \
--exit-0 \
--height=35% \
--inline-info \
--no-sort \
--reverse \
--select-1 \
" zoxide query -i -- "${query}")")
\builtin printf '\e[5n'
else
\builtin mapfile -t COMPREPLY < <(compgen -A directory -S / -- "${query}")
fi
}
\builtin complete -F __zoxide_z_complete -o nospace -- '{{cmd}}'
fi
{%- when None %}
{{ not_configured }}

View File

@ -21,20 +21,25 @@ fn __zoxide_cd [path]{
#
# Initialize hook to track previous directory.
__zoxide_oldpwd = $pwd
before-chdir = [$@before-chdir [_]{ edit:add-var __zoxide_oldpwd $pwd }]
{#- __zoxide_hooked requires https://github.com/elves/elvish/issues/1395 #}
var oldpwd = $builtin:pwd
set builtin:before-chdir = [$@builtin:before-chdir [_]{ edit:add-var oldpwd $builtin:pwd }]
# Initialize hook to add directories to zoxide.
var shlvl = $E:SHLVL
if (builtin:eq $shlvl "") {
set shlvl = 0
}
if (builtin:not (builtin:eq $E:__zoxide_hooked_elvish $shlvl)) {
set E:__zoxide_hooked_elvish = $shlvl
{%- match hook %}
{%- when InitHook::None %}
{{ not_configured }}
{{ not_configured }}
{%- when InitHook::Prompt %}
edit:before-readline = [$@edit:before-readline []{ zoxide add -- $pwd }]
set edit:before-readline = [$@edit:before-readline []{ zoxide add -- $pwd }]
{%- when InitHook::Pwd %}
after-chdir = [$@after-chdir [_]{ zoxide add -- $pwd }]
set builtin:after-chdir = [$@builtin:after-chdir [_]{ zoxide add -- $pwd }]
{%- endmatch %}
}
{{ section }}
# When using zoxide with --no-aliases, alias these internal functions as
@ -46,13 +51,13 @@ fn __zoxide_z [@rest]{
if (builtin:eq [] $rest) {
__zoxide_cd ~
} elif (builtin:eq [-] $rest) {
__zoxide_cd $__zoxide_oldpwd
__zoxide_cd $oldpwd
} elif (and ('builtin:==' (builtin:count $rest) 1) (path:is-dir &follow-symlink=$true $rest[0])) {
__zoxide_cd $rest[0]
} else {
var path
try {
path = (zoxide query --exclude $pwd -- $@rest)
set path = (zoxide query --exclude $pwd -- $@rest)
} except {
} else {
__zoxide_cd $path
@ -65,7 +70,7 @@ edit:add-var __zoxide_z~ $__zoxide_z~
fn __zoxide_zi [@rest]{
var path
try {
path = (zoxide query -i -- $@rest)
set path = (zoxide query -i -- $@rest)
} except {
} else {
__zoxide_cd $path
@ -80,8 +85,25 @@ edit:add-var __zoxide_zi~ $__zoxide_zi~
{%- match cmd %}
{%- when Some with (cmd) %}
edit:add-var z~ $__zoxide_z~
edit:add-var zi~ $__zoxide_zi~
edit:add-var {{cmd}}~ $__zoxide_z~
edit:add-var {{cmd}}i~ $__zoxide_zi~
# Load completions.
{# zoxide-based completions are currently not possible, because Elvish only
# prints a completion if the current token is a prefix of it. -#}
fn __zoxide_z_complete [@rest]{
if (!= (builtin:count $rest) 2) {
builtin:return
}
edit:complete-filename $rest[1] |
builtin:each [completion]{
var dir = $completion[stem]
if (path:is-dir $dir) {
builtin:put $dir
}
}
}
set edit:completion:arg-completer[{{cmd}}] = $__zoxide_z_complete~
{%- when None %}

View File

@ -70,15 +70,15 @@ function __zoxide_z
end
__zoxide_cd $argv[1]
else
set -l __zoxide_result (command zoxide query --exclude (__zoxide_pwd) -- $argv)
and __zoxide_cd $__zoxide_result
set -l result (command zoxide query --exclude (__zoxide_pwd) -- $argv)
and __zoxide_cd $result
end
end
# Jump to a directory using interactive search.
function __zoxide_zi
set -l __zoxide_result (command zoxide query -i -- $argv)
and __zoxide_cd $__zoxide_result
set -l result (command zoxide query -i -- $argv)
and __zoxide_cd $result
end
{{ section }}

View File

@ -27,9 +27,9 @@ function __zoxide_cd($dir) {
# Hook to add new entries to the database.
function __zoxide_hook {
$__zoxide_result = __zoxide_pwd
if ($__zoxide_result -ne $null) {
zoxide add -- $__zoxide_result
$result = __zoxide_pwd
if ($result -ne $null) {
zoxide add -- $result
}
}
@ -43,10 +43,10 @@ if ($__zoxide_hooked -ne 1) {
{%- when InitHook::None %}
{{ not_configured }}
{%- when InitHook::Prompt %}
$__zoxide_prompt_old = $function:prompt
$prompt_old = $function:prompt
function prompt {
$null = __zoxide_hook
& $__zoxide_prompt_old
& $prompt_old
}
{%- when InitHook::Pwd %}
if ($PSVersionTable.PSVersion.Major -ge 6) {
@ -78,23 +78,23 @@ function __zoxide_z {
__zoxide_cd $args[0]
}
else {
$__zoxide_result = __zoxide_pwd
if ($__zoxide_result -ne $null) {
$__zoxide_result = zoxide query --exclude $__zoxide_result -- @args
$result = __zoxide_pwd
if ($result -ne $null) {
$result = zoxide query --exclude $result -- @args
} else {
$__zoxide_result = zoxide query -- @args
$result = zoxide query -- @args
}
if ($LASTEXITCODE -eq 0) {
__zoxide_cd $__zoxide_result
__zoxide_cd $result
}
}
}
# Jump to a directory using interactive search.
function __zoxide_zi {
$__zoxide_result = zoxide query -i -- @args
$result = zoxide query -i -- @args
if ($LASTEXITCODE -eq 0) {
__zoxide_cd $__zoxide_result
__zoxide_cd $result
}
}

View File

@ -114,7 +114,7 @@ def __zoxide_z(args: List[str]):
else:
try:
zoxide = __zoxide_bin()
__zoxide_cmd = subprocess.run(
cmd = subprocess.run(
[zoxide, "query", "--exclude", __zoxide_pwd(), "--"] + args,
check=True,
stdout=subprocess.PIPE,
@ -122,22 +122,22 @@ def __zoxide_z(args: List[str]):
except subprocess.CalledProcessError as exc:
raise ZoxideSilentException() from exc
__zoxide_result = __zoxide_cmd.stdout[:-1]
__zoxide_cd(__zoxide_result)
result = cmd.stdout[:-1]
__zoxide_cd(result)
def __zoxide_zi(args: List[str]):
"""Jump to a directory using interactive search."""
try:
zoxide = __zoxide_bin()
__zoxide_cmd = subprocess.run(
cmd = subprocess.run(
[zoxide, "query", "-i", "--"] + args, check=True, stdout=subprocess.PIPE
)
except subprocess.CalledProcessError as exc:
raise ZoxideSilentException() from exc
__zoxide_result = __zoxide_cmd.stdout[:-1]
__zoxide_cd(__zoxide_result)
result = cmd.stdout[:-1]
__zoxide_cd(result)
{{ section }}

View File

@ -62,16 +62,16 @@ function __zoxide_z() {
elif [ "$#" -eq 1 ] && [ -d "$1" ]; then
__zoxide_cd "$1"
else
\builtin local __zoxide_result
__zoxide_result="$(zoxide query --exclude "$(__zoxide_pwd)" -- "$@")" \
&& __zoxide_cd "${__zoxide_result}"
\builtin local result
result="$(zoxide query --exclude "$(__zoxide_pwd)" -- "$@")" \
&& __zoxide_cd "${result}"
fi
}
# Jump to a directory using interactive search.
function __zoxide_zi() {
\builtin local __zoxide_result
__zoxide_result="$(zoxide query -i -- "$@")" && __zoxide_cd "${__zoxide_result}"
\builtin local result
result="$(zoxide query -i -- "$@")" && __zoxide_cd "${result}"
}
{{ section }}