mirror of
https://github.com/Llewellynvdm/zoxide.git
synced 2024-11-22 04:45:20 +00:00
Add z completions for zsh (#309)
This commit is contained in:
parent
72fd48ed97
commit
58430d8c54
4
.github/workflows/ci.yml
vendored
4
.github/workflows/ci.yml
vendored
@ -10,7 +10,7 @@ jobs:
|
||||
runs-on: ${{ matrix.os }}
|
||||
strategy:
|
||||
matrix:
|
||||
os: [ubuntu-latest, macos-latest, windows-latest]
|
||||
os: [ubuntu-latest, windows-latest] # FIXME: macos-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
|
||||
@ -28,5 +28,5 @@ jobs:
|
||||
|
||||
- run: cargo xtask ci
|
||||
if: ${{ matrix.os == 'windows-latest' }}
|
||||
- run: nix-shell --cores 0 --pure --run 'cargo xtask ci'
|
||||
- run: nix-shell --cores 0 --pure --run 'rm -rf ~/.cargo/bin; cargo xtask ci'
|
||||
if: ${{ matrix.os != 'windows-latest' }}
|
||||
|
10
CHANGELOG.md
10
CHANGELOG.md
@ -9,16 +9,20 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
||||
|
||||
## Unreleased
|
||||
|
||||
### Added
|
||||
|
||||
- Zsh: completions for `z` command.
|
||||
|
||||
### Changed
|
||||
|
||||
- fzf: better default options.
|
||||
- fish: interactive completions are only triggered when the last argument is empty.
|
||||
- Fzf: better default options.
|
||||
- Fish: interactive completions are only triggered when the last argument is empty.
|
||||
|
||||
### Fixed
|
||||
|
||||
- PowerShell: use global scope for aliases.
|
||||
- Zsh: fix errors with `set -eu`.
|
||||
- fzf: handle early selection.
|
||||
- Fzf: handle early selection.
|
||||
|
||||
## [0.7.9] - 2021-11-02
|
||||
|
||||
|
@ -2,7 +2,7 @@
|
||||
authors = ["Ajeet D'Souza <98ajeet@gmail.com>"]
|
||||
categories = ["command-line-utilities", "filesystem"]
|
||||
description = "A smarter cd command for your terminal"
|
||||
edition = "2018"
|
||||
edition = "2021"
|
||||
keywords = ["cli"]
|
||||
license = "MIT"
|
||||
name = "zoxide"
|
||||
|
24
README.md
24
README.md
@ -33,15 +33,17 @@ zoxide works on all major shells.
|
||||
![Tutorial][tutorial]
|
||||
|
||||
```sh
|
||||
z foo # cd into highest ranked directory matching foo
|
||||
z foo bar # cd into highest ranked directory matching foo and bar
|
||||
z foo # cd into highest ranked directory matching foo
|
||||
z foo bar # cd into highest ranked directory matching foo and bar
|
||||
|
||||
z ~/foo # z also works like a regular cd command
|
||||
z foo/ # cd into relative path
|
||||
z .. # cd one level up
|
||||
z - # cd into previous directory
|
||||
z ~/foo # z also works like a regular cd command
|
||||
z foo/ # cd into relative path
|
||||
z .. # cd one level up
|
||||
z - # cd into previous directory
|
||||
|
||||
zi foo # cd with interactive selection (using fzf)
|
||||
zi foo # cd with interactive selection (using fzf)
|
||||
|
||||
z foo<SPACE><TAB> # show interactive completions (zoxide v0.7.10+, bash/fish/zsh only)
|
||||
```
|
||||
|
||||
Read more about the matching algorithm [here][algorithm-matching].
|
||||
@ -231,6 +233,8 @@ Add this to your configuration (usually `~/.zshrc`):
|
||||
eval "$(zoxide init zsh)"
|
||||
```
|
||||
|
||||
For completions to work, this line must be added _after_ calling `compinit`.
|
||||
|
||||
</details>
|
||||
|
||||
<details>
|
||||
@ -347,16 +351,16 @@ They must be set before `zoxide init` is called.
|
||||
[algorithm-matching]: https://github.com/ajeetdsouza/zoxide/wiki/Algorithm#matching
|
||||
[alpine linux packages]: https://pkgs.alpinelinux.org/packages?name=zoxide
|
||||
[arch linux community]: https://archlinux.org/packages/community/x86_64/zoxide/
|
||||
[builtwithnix-badge]: https://img.shields.io/badge/builtwith-nix-7d81f7
|
||||
[builtwithnix-badge]: https://img.shields.io/badge/builtwith-nix-7d81f7?style=flat-square
|
||||
[builtwithnix]: https://builtwithnix.org/
|
||||
[chocolatey]: https://community.chocolatey.org/packages/zoxide
|
||||
[conda-forge]: https://anaconda.org/conda-forge/zoxide
|
||||
[copr]: https://copr.fedorainfracloud.org/coprs/atim/zoxide/
|
||||
[crates.io-badge]: https://img.shields.io/crates/v/zoxide
|
||||
[crates.io-badge]: https://img.shields.io/crates/v/zoxide?style=flat-square
|
||||
[crates.io]: https://crates.io/crates/zoxide
|
||||
[debian packages]: https://packages.debian.org/stable/admin/zoxide
|
||||
[devuan packages]: https://pkginfo.devuan.org/cgi-bin/package-query.html?c=package&q=zoxide
|
||||
[downloads-badge]: https://img.shields.io/github/downloads/ajeetdsouza/zoxide/total
|
||||
[downloads-badge]: https://img.shields.io/github/downloads/ajeetdsouza/zoxide/total?style=flat-square
|
||||
[dports]: https://github.com/DragonFlyBSD/DPorts/tree/master/sysutils/zoxide
|
||||
[emacs]: https://www.gnu.org/software/emacs/
|
||||
[fedora packages]: https://src.fedoraproject.org/rpms/rust-zoxide
|
||||
|
38
shell.nix
38
shell.nix
@ -1,41 +1,41 @@
|
||||
let
|
||||
rust = import (builtins.fetchTarball
|
||||
"https://github.com/oxalica/rust-overlay/archive/ad311f5bb5c5ef475985f1e0f264e831470a8510.tar.gz");
|
||||
pkgs = import <nixpkgs> { overlays = [ rust ]; };
|
||||
pkgs-latest = import (builtins.fetchTarball
|
||||
"https://github.com/NixOS/nixpkgs/archive/3ef1d2a9602c18f8742e1fb63d5ae9867092e3d6.tar.gz")
|
||||
{ };
|
||||
"https://github.com/oxalica/rust-overlay/archive/783722a22ee5d762ac5c1c7b418b57b3010c827a.tar.gz");
|
||||
pkgs = import (builtins.fetchTarball
|
||||
"https://github.com/NixOS/nixpkgs/archive/58f87c20e1abbbe835f1f3106ecea10fd93c4a90.tar.gz") {
|
||||
overlays = [ rust ];
|
||||
};
|
||||
in pkgs.mkShell {
|
||||
buildInputs = [
|
||||
# Rust
|
||||
pkgs.rust-bin.stable.latest.default
|
||||
|
||||
# Shells
|
||||
pkgs-latest.elvish
|
||||
pkgs-latest.fish
|
||||
pkgs-latest.nushell
|
||||
pkgs-latest.xonsh
|
||||
pkgs.bash
|
||||
pkgs.dash
|
||||
pkgs.elvish
|
||||
pkgs.fish
|
||||
pkgs.nushell
|
||||
pkgs.powershell
|
||||
pkgs.xonsh
|
||||
pkgs.zsh
|
||||
|
||||
# Tools
|
||||
pkgs-latest.cargo-audit
|
||||
pkgs-latest.mandoc
|
||||
pkgs-latest.nixfmt
|
||||
pkgs-latest.nodePackages.markdownlint-cli
|
||||
pkgs-latest.python3Packages.black
|
||||
pkgs-latest.python3Packages.mypy
|
||||
pkgs-latest.python3Packages.pylint
|
||||
pkgs-latest.shellcheck
|
||||
pkgs-latest.shfmt
|
||||
pkgs.cargo-audit
|
||||
pkgs.mandoc
|
||||
pkgs.nixfmt
|
||||
pkgs.nodePackages.markdownlint-cli
|
||||
pkgs.python3Packages.black
|
||||
pkgs.python3Packages.mypy
|
||||
pkgs.python3Packages.pylint
|
||||
pkgs.shellcheck
|
||||
pkgs.shfmt
|
||||
|
||||
# Dependencies
|
||||
pkgs.cacert
|
||||
pkgs.libiconv
|
||||
pkgs.fzf
|
||||
pkgs.git
|
||||
pkgs.libiconv
|
||||
];
|
||||
|
||||
RUST_BACKTRACE = 1;
|
||||
|
@ -32,16 +32,17 @@ impl Query {
|
||||
|
||||
if self.interactive {
|
||||
let mut fzf = Fzf::new(false)?;
|
||||
let stdin = fzf.stdin();
|
||||
|
||||
let selection = loop {
|
||||
let dir = match stream.next() {
|
||||
Some(dir) => dir,
|
||||
None => break fzf.select()?,
|
||||
};
|
||||
|
||||
match writeln!(fzf.stdin(), "{}", dir.display_score(now)) {
|
||||
Ok(()) => (()),
|
||||
match writeln!(stdin, "{}", dir.display_score(now)) {
|
||||
Err(e) if e.kind() == io::ErrorKind::BrokenPipe => break fzf.select()?,
|
||||
Err(e) => Err(e).context("could not write to fzf")?,
|
||||
result => result.context("could not write to fzf")?,
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -19,16 +19,17 @@ impl Run for Remove {
|
||||
let mut stream = db.stream(now).with_keywords(keywords);
|
||||
|
||||
let mut fzf = Fzf::new(true)?;
|
||||
let stdin = fzf.stdin();
|
||||
|
||||
let selection = loop {
|
||||
let dir = match stream.next() {
|
||||
Some(dir) => dir,
|
||||
None => break fzf.select()?,
|
||||
};
|
||||
|
||||
match writeln!(fzf.stdin(), "{}", dir.display_score(now)) {
|
||||
Ok(()) => (()),
|
||||
match writeln!(stdin, "{}", dir.display_score(now)) {
|
||||
Err(e) if e.kind() == io::ErrorKind::BrokenPipe => break fzf.select()?,
|
||||
Err(e) => Err(e).context("could not write to fzf")?,
|
||||
result => result.context("could not write to fzf")?,
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -3,7 +3,6 @@ use std::ffi::OsString;
|
||||
use std::path::PathBuf;
|
||||
|
||||
use anyhow::{bail, Context, Result};
|
||||
use dirs;
|
||||
use glob::Pattern;
|
||||
|
||||
use crate::db::Rank;
|
||||
|
@ -24,7 +24,7 @@ impl Fzf {
|
||||
command.args(&[
|
||||
"--bind=ctrl-z:ignore",
|
||||
"--exit-0",
|
||||
"--height=35%",
|
||||
"--height=40%",
|
||||
"--inline-info",
|
||||
"--no-sort",
|
||||
"--reverse",
|
||||
|
@ -32,7 +32,7 @@ function __zoxide_cd() {
|
||||
{%- if hook == InitHook::Prompt %}
|
||||
function __zoxide_hook() {
|
||||
\builtin local -r retval="$?"
|
||||
\builtin command zoxide add -- "$(__zoxide_pwd)"
|
||||
\command zoxide add -- "$(__zoxide_pwd || \builtin true)"
|
||||
return "${retval}"
|
||||
}
|
||||
{%- else if hook == InitHook::Pwd %}
|
||||
@ -40,10 +40,11 @@ __zoxide_oldpwd="$(__zoxide_pwd)"
|
||||
|
||||
function __zoxide_hook() {
|
||||
\builtin local -r retval="$?"
|
||||
\builtin local -r pwd_tmp="$(__zoxide_pwd)"
|
||||
\builtin local pwd_tmp
|
||||
pwd_tmp="$(__zoxide_pwd)"
|
||||
if [[ ${__zoxide_oldpwd} != "${pwd_tmp}" ]]; then
|
||||
__zoxide_oldpwd="${pwd_tmp}"
|
||||
\builtin command zoxide add -- "${__zoxide_oldpwd}"
|
||||
\command zoxide add -- "${__zoxide_oldpwd}"
|
||||
fi
|
||||
return "${retval}"
|
||||
}
|
||||
@ -76,14 +77,15 @@ function __zoxide_z() {
|
||||
__zoxide_cd "${result:2}"
|
||||
else
|
||||
\builtin local result
|
||||
result="$(\builtin command zoxide query --exclude "$(__zoxide_pwd)" -- "$@")" && __zoxide_cd "${result}"
|
||||
result="$(\command zoxide query --exclude "$(__zoxide_pwd || \builtin true)" -- "$@")" &&
|
||||
__zoxide_cd "${result}"
|
||||
fi
|
||||
}
|
||||
|
||||
# Jump to a directory using interactive search.
|
||||
function __zoxide_zi() {
|
||||
\builtin local result
|
||||
result="$(\builtin command zoxide query -i -- "$@")" && __zoxide_cd "${result}"
|
||||
result="$(\command zoxide query -i -- "$@")" && __zoxide_cd "${result}"
|
||||
}
|
||||
|
||||
{{ section }}
|
||||
@ -123,11 +125,12 @@ 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]}")
|
||||
\builtin mapfile -t COMPREPLY < \
|
||||
<(\builtin compgen -A directory -S / -- "${COMP_WORDS[-1]}" || \builtin true)
|
||||
# If there is a space after the last word, use interactive selection.
|
||||
elif [[ -z ${COMP_WORDS[-1]} ]]; then
|
||||
\local result
|
||||
result="$(\builtin command zoxide query -i -- "${COMP_WORDS[@]:1}")" &&
|
||||
\builtin local result
|
||||
result="$(\command zoxide query -i -- "{{ "${COMP_WORDS[@]:1:${#COMP_WORDS[@]}-2}" }}")" &&
|
||||
COMPREPLY=("${__zoxide_z_prefix}${result}")
|
||||
\builtin printf '\e[5n'
|
||||
fi
|
||||
|
@ -8,16 +8,16 @@
|
||||
# pwd based on the value of _ZO_RESOLVE_SYMLINKS.
|
||||
__zoxide_pwd() {
|
||||
{%- if resolve_symlinks %}
|
||||
\pwd -P
|
||||
\command pwd -P
|
||||
{%- else %}
|
||||
\pwd -L
|
||||
\command pwd -L
|
||||
{%- endif %}
|
||||
}
|
||||
|
||||
# cd + custom logic based on the value of _ZO_ECHO.
|
||||
__zoxide_cd() {
|
||||
# shellcheck disable=SC2164
|
||||
\cd "$@" {%- if echo %} && __zoxide_pwd {%- endif %}
|
||||
\command cd "$@" {%- if echo %} && __zoxide_pwd {%- endif %}
|
||||
}
|
||||
|
||||
{{ section }}
|
||||
@ -31,7 +31,7 @@ __zoxide_cd() {
|
||||
{%- when InitHook::Prompt -%}
|
||||
# Hook to add new entries to the database.
|
||||
__zoxide_hook() {
|
||||
zoxide add -- "$(__zoxide_pwd)"
|
||||
\command zoxide add -- "$(__zoxide_pwd || \builtin true)"
|
||||
}
|
||||
|
||||
# Initialize hook.
|
||||
@ -40,7 +40,7 @@ if [ "${PS1:=}" = "${PS1#*\$(__zoxide_hook)}" ]; then
|
||||
fi
|
||||
|
||||
{%- when InitHook::Pwd -%}
|
||||
\printf "%s\n%s\n" \
|
||||
\command printf "%s\n%s\n" \
|
||||
"zoxide: PWD hooks are not supported on POSIX shells." \
|
||||
" Use 'zoxide init posix --hook prompt' instead."
|
||||
|
||||
@ -60,19 +60,20 @@ __zoxide_z() {
|
||||
__zoxide_cd "${OLDPWD}"
|
||||
else
|
||||
# shellcheck disable=SC2016
|
||||
\printf 'zoxide: $OLDPWD is not set'
|
||||
\command printf 'zoxide: $OLDPWD is not set'
|
||||
return 1
|
||||
fi
|
||||
elif [ "$#" -eq 1 ] && [ -d "$1" ]; then
|
||||
__zoxide_cd "$1"
|
||||
else
|
||||
__zoxide_result="$(zoxide query --exclude "$(__zoxide_pwd)" -- "$@")" && __zoxide_cd "${__zoxide_result}"
|
||||
__zoxide_result="$(\command zoxide query --exclude "$(__zoxide_pwd || \builtin true)" -- "$@")" &&
|
||||
__zoxide_cd "${__zoxide_result}"
|
||||
fi
|
||||
}
|
||||
|
||||
# Jump to a directory using interactive search.
|
||||
__zoxide_zi() {
|
||||
__zoxide_result="$(zoxide query -i -- "$@")" && __zoxide_cd "${__zoxide_result}"
|
||||
__zoxide_result="$(\command zoxide query -i -- "$@")" && __zoxide_cd "${__zoxide_result}"
|
||||
}
|
||||
|
||||
{{ section }}
|
||||
@ -84,10 +85,10 @@ __zoxide_zi() {
|
||||
|
||||
# Remove definitions.
|
||||
__zoxide_unset() {
|
||||
\unset -f "$@" >/dev/null 2>&1
|
||||
\unset -v "$@" >/dev/null 2>&1
|
||||
\command unset -f "$@" >/dev/null 2>&1
|
||||
\command unset -v "$@" >/dev/null 2>&1
|
||||
# shellcheck disable=SC1001
|
||||
\unalias "$@" >/dev/null 2>&1 || \:
|
||||
\command unalias "$@" >/dev/null 2>&1 || \:
|
||||
}
|
||||
|
||||
__zoxide_unset '{{cmd}}'
|
||||
|
@ -30,7 +30,7 @@ function __zoxide_cd() {
|
||||
{% else -%}
|
||||
# Hook to add new entries to the database.
|
||||
function __zoxide_hook() {
|
||||
zoxide add -- "$(__zoxide_pwd)"
|
||||
\command zoxide add -- "$(__zoxide_pwd || \builtin true)"
|
||||
}
|
||||
|
||||
# Initialize hook.
|
||||
@ -52,29 +52,29 @@ fi
|
||||
|
||||
# Jump to a directory using only keywords.
|
||||
function __zoxide_z() {
|
||||
if [ "$#" -eq 0 ]; then
|
||||
if [[ "$#" -eq 0 ]]; then
|
||||
__zoxide_cd ~
|
||||
elif [ "$#" -eq 1 ] && [ "$1" = '-' ]; then
|
||||
if [ -n "${OLDPWD}" ]; then
|
||||
elif [[ "$#" -eq 1 ]] && [[ "$1" = '-' ]]; then
|
||||
if [[ -n "${OLDPWD}" ]]; then
|
||||
__zoxide_cd "${OLDPWD}"
|
||||
else
|
||||
# shellcheck disable=SC2016
|
||||
\builtin printf 'zoxide: $OLDPWD is not set'
|
||||
return 1
|
||||
fi
|
||||
elif [ "$#" -eq 1 ] && [ -d "$1" ]; then
|
||||
elif [[ "$#" -eq 1 ]] && [[ -d "$1" ]]; then
|
||||
__zoxide_cd "$1"
|
||||
else
|
||||
\builtin local result
|
||||
result="$(zoxide query --exclude "$(__zoxide_pwd)" -- "$@")" \
|
||||
&& __zoxide_cd "${result}"
|
||||
result="$(\command zoxide query --exclude "$(__zoxide_pwd || \builtin true)" -- "$@")" &&
|
||||
__zoxide_cd "${result}"
|
||||
fi
|
||||
}
|
||||
|
||||
# Jump to a directory using interactive search.
|
||||
function __zoxide_zi() {
|
||||
\builtin local result
|
||||
result="$(zoxide query -i -- "$@")" && __zoxide_cd "${result}"
|
||||
result="$(\command zoxide query -i -- "$@")" && __zoxide_cd "${result}"
|
||||
}
|
||||
|
||||
{{ section }}
|
||||
@ -86,8 +86,8 @@ function __zoxide_zi() {
|
||||
|
||||
# Remove definitions.
|
||||
function __zoxide_unset() {
|
||||
\builtin unalias "$@" &>/dev/null || true
|
||||
\builtin unfunction "$@" &>/dev/null || true
|
||||
\builtin unalias "$@" &>/dev/null || \builtin true
|
||||
\builtin unfunction "$@" &>/dev/null || \builtin true
|
||||
\builtin unset "$@" &>/dev/null
|
||||
}
|
||||
|
||||
@ -101,6 +101,43 @@ function {{cmd}}i() {
|
||||
__zoxide_zi "$@"
|
||||
}
|
||||
|
||||
if [[ -o zle ]]; then
|
||||
function _{{cmd}}() {
|
||||
\builtin local buffer tokens
|
||||
# shellcheck disable=SC2034,SC2153,SC2154
|
||||
buffer="${BUFFER}."
|
||||
# shellcheck disable=SC2206,SC2296
|
||||
tokens=(${(Q)${(z)buffer}})
|
||||
|
||||
if [[ "{{ "${#tokens[@]}" }}" -eq 2 ]]; then
|
||||
_files -/
|
||||
elif [[ "${tokens[-1]}" == '.' ]]; then
|
||||
\builtin printf '\e[5n'
|
||||
fi
|
||||
}
|
||||
|
||||
function _{{cmd}}_helper() {
|
||||
\builtin local tokens result
|
||||
# shellcheck disable=SC2154,SC2206,SC2296
|
||||
tokens=(${(Q)${(z)BUFFER}})
|
||||
# shellcheck disable=SC2086
|
||||
if result="$(\command zoxide query -i -- ${tokens[2,-1]})"; then
|
||||
# shellcheck disable=SC2034
|
||||
RBUFFER=''
|
||||
# shellcheck disable=SC2034,SC2296
|
||||
LBUFFER="${tokens[1]} ${(q-)result}"
|
||||
fi
|
||||
\builtin zle reset-prompt
|
||||
}
|
||||
|
||||
\builtin zle -N _{{cmd}}_helper
|
||||
\builtin bindkey "\e[0n" _{{cmd}}_helper
|
||||
if [[ "${+functions[compdef]}" -ne 0 ]]; then
|
||||
\compdef -d {{cmd}}
|
||||
\compdef _{{cmd}} {{cmd}}
|
||||
fi
|
||||
fi
|
||||
|
||||
{%- when None %}
|
||||
|
||||
{{ not_configured }}
|
||||
|
@ -1,7 +1,7 @@
|
||||
[package]
|
||||
name = "xtask"
|
||||
version = "0.1.0"
|
||||
edition = "2018"
|
||||
edition = "2021"
|
||||
publish = false
|
||||
|
||||
[dependencies]
|
||||
|
@ -87,7 +87,11 @@ fn run_fmt(nix_enabled: bool, check: bool) -> Result<()> {
|
||||
fn run_lint(nix_enabled: bool) -> Result<()> {
|
||||
// Run cargo-clippy.
|
||||
let color: &[&str] = if is_ci() { &["--color=always"] } else { &[] };
|
||||
Command::new("cargo").args(&["clippy", "--all-features", "--all-targets"]).args(color)._run()?;
|
||||
Command::new("cargo")
|
||||
.args(&["clippy", "--all-features", "--all-targets"])
|
||||
.args(color)
|
||||
.args(&["--", "-Dwarnings"])
|
||||
._run()?;
|
||||
|
||||
if nix_enabled {
|
||||
// Run cargo-audit.
|
||||
|
Loading…
Reference in New Issue
Block a user