mirror of
https://github.com/robbyrussell/oh-my-zsh.git
synced 2026-09-25 12:36:06 +02:00
Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
003d1167da |
@@ -46,10 +46,9 @@ dependencies:
|
||||
plugins/z:
|
||||
branch: master
|
||||
repo: agkozak/zsh-z
|
||||
version: 102fb78036ed76feedf623907483691777a1d510
|
||||
version: acd0e1984df350c189f8f9c4956ec586b6c73fca
|
||||
precopy: |
|
||||
set -e
|
||||
rm -r tests
|
||||
test -e README.md && mv -f README.md MANUAL.md
|
||||
postcopy: |
|
||||
set -e
|
||||
|
||||
@@ -16,7 +16,7 @@ jobs:
|
||||
contents: write # this is needed to push commits and branches
|
||||
steps:
|
||||
- name: Harden the runner (Audit all outbound calls)
|
||||
uses: step-security/harden-runner@05e31511f85b41b11d1cf0ef85d0992719546e2c # v2.21.0
|
||||
uses: step-security/harden-runner@b09bb98e06d4d774595224525879c09bc6e98c40 # v2.20.1
|
||||
with:
|
||||
egress-policy: audit
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
certifi==2026.7.22
|
||||
charset-normalizer==3.5.1
|
||||
idna==3.19
|
||||
charset-normalizer==3.4.9
|
||||
idna==3.18
|
||||
PyYAML==6.0.3
|
||||
requests==2.34.2
|
||||
semver==3.0.4
|
||||
|
||||
@@ -26,7 +26,7 @@ jobs:
|
||||
- macos-latest
|
||||
steps:
|
||||
- name: Harden the runner (Audit all outbound calls)
|
||||
uses: step-security/harden-runner@05e31511f85b41b11d1cf0ef85d0992719546e2c # v2.21.0
|
||||
uses: step-security/harden-runner@b09bb98e06d4d774595224525879c09bc6e98c40 # v2.20.1
|
||||
with:
|
||||
egress-policy: audit
|
||||
|
||||
@@ -47,7 +47,7 @@ jobs:
|
||||
- test
|
||||
steps:
|
||||
- name: Harden the runner (Audit all outbound calls)
|
||||
uses: step-security/harden-runner@05e31511f85b41b11d1cf0ef85d0992719546e2c # v2.21.0
|
||||
uses: step-security/harden-runner@b09bb98e06d4d774595224525879c09bc6e98c40 # v2.20.1
|
||||
with:
|
||||
egress-policy: audit
|
||||
|
||||
|
||||
@@ -24,7 +24,7 @@ jobs:
|
||||
if: github.repository == 'ohmyzsh/ohmyzsh'
|
||||
steps:
|
||||
- name: Harden the runner (Audit all outbound calls)
|
||||
uses: step-security/harden-runner@05e31511f85b41b11d1cf0ef85d0992719546e2c # v2.21.0
|
||||
uses: step-security/harden-runner@b09bb98e06d4d774595224525879c09bc6e98c40 # v2.20.1
|
||||
with:
|
||||
egress-policy: audit
|
||||
|
||||
@@ -38,7 +38,6 @@ jobs:
|
||||
./lib/*.zsh \
|
||||
./plugins/*/*.plugin.zsh \
|
||||
./plugins/*/_* \
|
||||
./templates/generators/*/*.zsh-template \
|
||||
./themes/*.zsh-theme; do
|
||||
zsh -n "$file" || return 1
|
||||
done
|
||||
|
||||
@@ -17,7 +17,7 @@ jobs:
|
||||
if: github.repository == 'ohmyzsh/ohmyzsh'
|
||||
steps:
|
||||
- name: Harden the runner (Audit all outbound calls)
|
||||
uses: step-security/harden-runner@05e31511f85b41b11d1cf0ef85d0992719546e2c # v2.21.0
|
||||
uses: step-security/harden-runner@b09bb98e06d4d774595224525879c09bc6e98c40 # v2.20.1
|
||||
with:
|
||||
egress-policy: audit
|
||||
- name: Authenticate as @ohmyzsh
|
||||
|
||||
@@ -36,7 +36,7 @@ jobs:
|
||||
|
||||
steps:
|
||||
- name: Harden the runner (Audit all outbound calls)
|
||||
uses: step-security/harden-runner@05e31511f85b41b11d1cf0ef85d0992719546e2c # v2.21.0
|
||||
uses: step-security/harden-runner@b09bb98e06d4d774595224525879c09bc6e98c40 # v2.20.1
|
||||
with:
|
||||
egress-policy: audit
|
||||
|
||||
@@ -60,6 +60,6 @@ jobs:
|
||||
retention-days: 5
|
||||
|
||||
- name: "Upload to code-scanning"
|
||||
uses: github/codeql-action/upload-sarif@cdf488f595d80d6e07e03d4674febd5ab45fa938 # v4.37.9
|
||||
uses: github/codeql-action/upload-sarif@5595ccaf912efad79be6eef63a5619ff05969be3 # v4.37.6
|
||||
with:
|
||||
sarif_file: results.sarif
|
||||
|
||||
@@ -346,10 +346,6 @@ directory.
|
||||
If you have many functions that go well together, you can put them as a `XYZ.plugin.zsh` file in the
|
||||
`custom/plugins/` directory and then enable this plugin.
|
||||
|
||||
The quickest way to start one is `omz generate plugin <name>`. It creates the plugin directory with a
|
||||
commented `<name>.plugin.zsh`, a `README.md`, and (for plugins that wrap a command-line tool) a completion
|
||||
skeleton, then tells you how to try it out.
|
||||
|
||||
If you would like to override the functionality of a plugin distributed with Oh My Zsh, create a plugin of the
|
||||
same name in the `custom/plugins/` directory and it will be loaded instead of the one in `plugins/`.
|
||||
|
||||
|
||||
+10
-383
@@ -24,7 +24,6 @@ function _omz {
|
||||
local -a cmds subcmds
|
||||
cmds=(
|
||||
'changelog:Print the changelog'
|
||||
'generate:Run a generator, e.g. to create a custom plugin'
|
||||
'help:Usage information'
|
||||
'plugin:Manage plugins'
|
||||
'pr:Manage Oh My Zsh Pull Requests'
|
||||
@@ -42,8 +41,6 @@ function _omz {
|
||||
changelog) local -a refs
|
||||
refs=("${(@f)$(builtin cd -q "$ZSH"; command git for-each-ref --format="%(refname:short):%(subject)" refs/heads refs/tags)}")
|
||||
_describe 'command' refs ;;
|
||||
generate) subcmds=('plugin:Create a custom plugin')
|
||||
_describe 'generator' subcmds ;;
|
||||
plugin) subcmds=(
|
||||
'disable:Disable plugin(s)'
|
||||
'enable:Enable plugin(s)'
|
||||
@@ -59,8 +56,6 @@ function _omz {
|
||||
esac
|
||||
elif (( CURRENT == 4 )); then
|
||||
case "${words[2]}::${words[3]}" in
|
||||
generate::plugin)
|
||||
_omz::generate::plugin::complete_options ;;
|
||||
plugin::(disable|enable|load))
|
||||
local -aU valid_plugins
|
||||
|
||||
@@ -89,8 +84,6 @@ function _omz {
|
||||
esac
|
||||
elif (( CURRENT > 4 )); then
|
||||
case "${words[2]}::${words[3]}" in
|
||||
generate::plugin)
|
||||
_omz::generate::plugin::complete_options ;;
|
||||
plugin::(enable|disable|load))
|
||||
local -aU valid_plugins
|
||||
|
||||
@@ -176,16 +169,15 @@ Usage: omz <command> [options]
|
||||
|
||||
Available commands:
|
||||
|
||||
help Print this help message
|
||||
changelog Print the changelog
|
||||
generate <generator> Run a generator, e.g. to create a custom plugin
|
||||
plugin <command> Manage plugins
|
||||
pr <command> Manage Oh My Zsh Pull Requests
|
||||
reload Reload the current zsh session
|
||||
shop Open the Oh My Zsh shop
|
||||
theme <command> Manage themes
|
||||
update Update Oh My Zsh
|
||||
version Show the version
|
||||
help Print this help message
|
||||
changelog Print the changelog
|
||||
plugin <command> Manage plugins
|
||||
pr <command> Manage Oh My Zsh Pull Requests
|
||||
reload Reload the current zsh session
|
||||
shop Open the Oh My Zsh shop
|
||||
theme <command> Manage themes
|
||||
update Update Oh My Zsh
|
||||
version Show the version
|
||||
|
||||
EOF
|
||||
}
|
||||
@@ -210,371 +202,6 @@ EOF
|
||||
ZSH="$ZSH" command zsh -f "$ZSH/tools/changelog.sh" "$version" "${2:-}" "$format"
|
||||
}
|
||||
|
||||
function _omz::generate {
|
||||
(( $# > 0 && $+functions[$0::$1] )) || {
|
||||
cat >&2 <<EOF
|
||||
Usage: ${(j: :)${(s.::.)0#_}} <generator> [options]
|
||||
|
||||
Available generators:
|
||||
|
||||
plugin [<name>] Create a custom plugin in \$ZSH_CUSTOM/plugins
|
||||
|
||||
EOF
|
||||
return 1
|
||||
}
|
||||
|
||||
local command="$1"
|
||||
shift
|
||||
|
||||
$0::$command "$@"
|
||||
}
|
||||
|
||||
function _omz::generate::plugin {
|
||||
setopt localoptions extendedglob
|
||||
|
||||
local -A opts
|
||||
zparseopts -D -E -A opts -- d: -description: c: -command: -no-completion -enable y -yes h -help || return 1
|
||||
|
||||
if (( ${+opts[-h]} || ${+opts[--help]} )); then
|
||||
_omz::generate::plugin::usage
|
||||
return 0
|
||||
fi
|
||||
|
||||
# zparseopts -E leaves anything it doesn't recognise in $@
|
||||
local arg
|
||||
for arg in "$@"; do
|
||||
if [[ "$arg" == -* ]]; then
|
||||
_omz::log error "unknown option '$arg'."
|
||||
_omz::generate::plugin::usage
|
||||
return 1
|
||||
fi
|
||||
done
|
||||
if (( $# > 1 )); then
|
||||
_omz::generate::plugin::usage
|
||||
return 1
|
||||
fi
|
||||
|
||||
# Only ask questions when there is someone there to answer them
|
||||
local interactive=0
|
||||
if [[ -o interactive && -t 0 ]] && (( ! ${+opts[-y]} && ! ${+opts[--yes]} )); then
|
||||
interactive=1
|
||||
fi
|
||||
|
||||
local custom="${ZSH_CUSTOM:-${ZSH:+$ZSH/custom}}"
|
||||
if [[ -z "$custom" ]]; then
|
||||
_omz::log error "\$ZSH is not set. Is Oh My Zsh loaded?"
|
||||
return 1
|
||||
fi
|
||||
|
||||
local templates="$ZSH/templates/generators/plugin"
|
||||
if [[ ! -d "$templates" ]]; then
|
||||
_omz::log error "templates not found at '${templates/#$HOME/\~}'. Try running 'omz update'."
|
||||
return 1
|
||||
fi
|
||||
|
||||
# Check we can write to $ZSH_CUSTOM/plugins, or the closest directory that exists
|
||||
local probe="$custom/plugins"
|
||||
while [[ ! -e "$probe" && "$probe" != "${probe:h}" ]]; do
|
||||
probe="${probe:h}"
|
||||
done
|
||||
if [[ ! -w "$probe" ]]; then
|
||||
_omz::log error "cannot write to '${probe/#$HOME/\~}'. Set \$ZSH_CUSTOM to a directory you own."
|
||||
return 1
|
||||
fi
|
||||
|
||||
## Gather answers. Nothing is written until all of them are in.
|
||||
|
||||
local name="$1" attempts=0
|
||||
if [[ -n "$name" ]]; then
|
||||
_omz::generate::plugin::validate_name "$name" || return 1
|
||||
elif (( interactive )); then
|
||||
while true; do
|
||||
_omz::generate::plugin::ask "Plugin name" || return 1
|
||||
name="$REPLY"
|
||||
_omz::generate::plugin::validate_name "$name" && break
|
||||
if (( ++attempts >= 3 )); then
|
||||
_omz::log error "giving up."
|
||||
return 1
|
||||
fi
|
||||
done
|
||||
else
|
||||
_omz::generate::plugin::usage
|
||||
return 1
|
||||
fi
|
||||
|
||||
local dir="$custom/plugins/$name"
|
||||
if [[ -e "$dir" ]]; then
|
||||
_omz::log error "'$name' already exists at '${dir/#$HOME/\~}'. Remove it or pick another name."
|
||||
return 1
|
||||
fi
|
||||
if [[ -d "$ZSH/plugins/$name" ]]; then
|
||||
_omz::log warn "'$name' is also a built-in plugin. Your custom plugin will override it."
|
||||
if (( interactive )); then
|
||||
_omz::confirm "Continue? [y/N] "
|
||||
if [[ "$REPLY" != [yY] ]]; then
|
||||
_omz::log info "aborted."
|
||||
return 1
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
|
||||
local description="${opts[-d]:-${opts[--description]:-}}"
|
||||
if [[ -z "$description" ]]; then
|
||||
description="$name plugin for Oh My Zsh"
|
||||
if (( interactive )); then
|
||||
_omz::generate::plugin::ask "Short description" "$description" || return 1
|
||||
description="$REPLY"
|
||||
fi
|
||||
fi
|
||||
# The description goes into a comment and a README line: keep it on one line
|
||||
description="${description//[[:cntrl:]]/ }"
|
||||
|
||||
local cmd="${opts[-c]:-${opts[--command]:-}}"
|
||||
if [[ -n "$cmd" ]]; then
|
||||
_omz::generate::plugin::validate_command "$cmd" || return 1
|
||||
elif (( interactive )); then
|
||||
local default_cmd=""
|
||||
(( $+commands[$name] )) && default_cmd="$name"
|
||||
attempts=0
|
||||
while true; do
|
||||
if [[ -n "$default_cmd" ]]; then
|
||||
_omz::generate::plugin::ask "Command-line tool this plugin wraps (or 'none')" "$default_cmd" || return 1
|
||||
else
|
||||
_omz::generate::plugin::ask "Command-line tool this plugin wraps (blank for none)" || return 1
|
||||
fi
|
||||
cmd="$REPLY"
|
||||
[[ "$cmd" != (none|-) ]] || cmd=""
|
||||
[[ -n "$cmd" ]] || break
|
||||
_omz::generate::plugin::validate_command "$cmd" && break
|
||||
if (( ++attempts >= 3 )); then
|
||||
_omz::log error "giving up."
|
||||
return 1
|
||||
fi
|
||||
done
|
||||
fi
|
||||
|
||||
# completion: "" (none), "file" (a _<cmd> skeleton) or "cached" (the tool generates it)
|
||||
local completion="" compgen=""
|
||||
if [[ -n "$cmd" ]] && (( ! ${+opts[--no-completion]} )); then
|
||||
completion=file
|
||||
if (( interactive )); then
|
||||
_omz::confirm "Add a completion function for $cmd? [Y/n] "
|
||||
if [[ "$REPLY" == [nN] ]]; then
|
||||
completion=""
|
||||
else
|
||||
_omz::confirm "Does $cmd generate its own zsh completion (e.g. '$cmd completion zsh')? [y/N] "
|
||||
if [[ "$REPLY" == [yY] ]]; then
|
||||
completion=cached
|
||||
_omz::generate::plugin::ask "Command that prints the completion script" "$cmd completion zsh" || return 1
|
||||
compgen="$REPLY"
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
|
||||
local enable=${+opts[--enable]}
|
||||
if (( interactive && ! enable )); then
|
||||
_omz::confirm "Add $name to plugins=() in your .zshrc now? [y/N] "
|
||||
[[ "$REPLY" != [yY] ]] || enable=1
|
||||
fi
|
||||
|
||||
## Write the files. If anything fails, remove only what we created.
|
||||
|
||||
local -a created
|
||||
local block="" cache="" ok=0
|
||||
{
|
||||
if [[ ! -d "$custom/plugins" ]]; then
|
||||
command mkdir -p "$custom/plugins" || return 1
|
||||
_omz::generate::plugin::created "$custom/plugins"
|
||||
fi
|
||||
command mkdir "$dir" || return 1
|
||||
_omz::generate::plugin::created "$dir"
|
||||
|
||||
local plugin_tpl=plugin.zsh-template readme_tpl=README.md-template
|
||||
if [[ -z "$cmd" ]]; then
|
||||
plugin_tpl=plugin-generic.zsh-template
|
||||
readme_tpl=README-generic.md-template
|
||||
elif [[ "$completion" == cached ]]; then
|
||||
block="$(_omz::generate::plugin::template completion-cached.zsh-template)" || return 1
|
||||
cache="$(_omz::generate::plugin::template README-cache.md-template)" || return 1
|
||||
else
|
||||
block="$(_omz::generate::plugin::template completion-note.zsh-template)" || return 1
|
||||
fi
|
||||
|
||||
_omz::generate::plugin::render "$plugin_tpl" "$dir/$name.plugin.zsh" || return 1
|
||||
_omz::generate::plugin::render "$readme_tpl" "$dir/README.md" || return 1
|
||||
if [[ "$completion" == file ]]; then
|
||||
_omz::generate::plugin::render completion.zsh-template "$dir/_$cmd" || return 1
|
||||
fi
|
||||
ok=1
|
||||
} always {
|
||||
if (( ! ok )); then
|
||||
_omz::log error "could not generate the plugin. Cleaning up..."
|
||||
(( ${#created} )) && command rm -f -- "${created[@]}"
|
||||
[[ ! -d "$dir" ]] || command rmdir -- "$dir" 2>/dev/null
|
||||
fi
|
||||
}
|
||||
|
||||
print
|
||||
_omz::log info "plugin '$name' generated."
|
||||
print
|
||||
print -r -- "Next steps:"
|
||||
print
|
||||
print -r -- " 1. Edit it: ${EDITOR:-vim} ${dir/#$HOME/\~}/$name.plugin.zsh"
|
||||
print -r -- " 2. Try it now: omz plugin load $name"
|
||||
(( enable )) || print -r -- " 3. Keep it: omz plugin enable $name"
|
||||
print
|
||||
print -r -- "Docs: https://github.com/ohmyzsh/ohmyzsh/wiki/Customization#overriding-and-adding-plugins"
|
||||
|
||||
# Last thing we do: in an interactive shell this restarts zsh
|
||||
if (( enable )); then
|
||||
print
|
||||
if (( ${plugins[(Ie)$name]} )); then
|
||||
# Already enabled (e.g. a custom override of a built-in): just reload
|
||||
_omz::log info "'$name' is already in your plugins list."
|
||||
[[ ! -o interactive ]] || _omz::reload
|
||||
else
|
||||
_omz::plugin::enable "$name"
|
||||
fi
|
||||
fi
|
||||
}
|
||||
|
||||
function _omz::generate::plugin::usage {
|
||||
cat >&2 <<EOF
|
||||
Usage: omz generate plugin [<name>] [options]
|
||||
|
||||
Creates a custom plugin in \$ZSH_CUSTOM/plugins/<name>. Anything not given as an
|
||||
option is asked for interactively. In a non-interactive shell (or with --yes)
|
||||
defaults are used instead.
|
||||
|
||||
Options:
|
||||
-d, --description <text> One-line description for the README and file header
|
||||
-c, --command <cmd> Command-line tool this plugin wraps. Adds a check
|
||||
that it is installed and scaffolds its completion
|
||||
--no-completion Don't scaffold a completion function
|
||||
--enable Add the plugin to plugins=() in .zshrc when done
|
||||
(restarts your shell)
|
||||
-y, --yes Never prompt; use defaults for anything not given
|
||||
-h, --help Show this help
|
||||
|
||||
EOF
|
||||
}
|
||||
|
||||
function _omz::generate::plugin::complete_options {
|
||||
local -a opts
|
||||
opts=(
|
||||
'--description:One-line description for the README'
|
||||
'--command:Command-line tool this plugin wraps'
|
||||
'--no-completion:Skip the completion scaffold'
|
||||
'--enable:Enable the plugin when done'
|
||||
'--yes:Never prompt'
|
||||
)
|
||||
_describe -o 'options' opts
|
||||
}
|
||||
|
||||
# The name ends up in a mkdir path and, via --enable, inside the awk script that
|
||||
# rewrites .zshrc. This is the one place it gets checked.
|
||||
function _omz::generate::plugin::validate_name {
|
||||
setopt localoptions extendedglob
|
||||
local name="$1"
|
||||
|
||||
if [[ -z "$name" ]]; then
|
||||
_omz::log error "plugin name cannot be empty."
|
||||
elif (( ${#name} > 64 )); then
|
||||
_omz::log error "plugin name is too long (64 characters max)."
|
||||
elif [[ "$name" != "${name:l}" ]]; then
|
||||
_omz::log error "plugin names must be lowercase. Did you mean '${name:l}'?"
|
||||
elif [[ "$name" != [a-z0-9][a-z0-9_-]# ]]; then
|
||||
_omz::log error "invalid plugin name: use only lowercase letters, digits, '-' and '_', starting with a letter or digit."
|
||||
else
|
||||
return 0
|
||||
fi
|
||||
return 1
|
||||
}
|
||||
|
||||
# The command name ends up in $+commands[...], _comps[...] and a filename
|
||||
function _omz::generate::plugin::validate_command {
|
||||
setopt localoptions extendedglob
|
||||
|
||||
if (( ${#1} > 64 )) || [[ "$1" != [[:alnum:]_][[:alnum:]_.+-]# ]]; then
|
||||
_omz::log error "invalid command name: use only letters, digits, '.', '_', '+' and '-'."
|
||||
return 1
|
||||
fi
|
||||
}
|
||||
|
||||
# Ask a question and leave the answer in $REPLY. An empty answer takes the
|
||||
# default. Returns 1 when there is no more input (Ctrl-D).
|
||||
function _omz::generate::plugin::ask {
|
||||
setopt localoptions extendedglob
|
||||
local question="$1" default="$2"
|
||||
[[ -z "$default" ]] || question+=" [$default]"
|
||||
|
||||
_omz::log prompt "$question: " "omz::generate::plugin"
|
||||
if ! builtin read -r; then
|
||||
print >&2
|
||||
_omz::log info "aborted." "omz::generate::plugin"
|
||||
return 1
|
||||
fi
|
||||
|
||||
[[ -n "$REPLY" ]] || REPLY="$default"
|
||||
# Answers are single-line values: flatten control characters and trim
|
||||
REPLY="${REPLY//[[:cntrl:]]/ }"
|
||||
REPLY="${${REPLY##[[:space:]]#}%%[[:space:]]#}"
|
||||
}
|
||||
|
||||
# Print a template file with its %placeholders% turned into private markers,
|
||||
# or explain which one is missing
|
||||
function _omz::generate::plugin::template {
|
||||
if [[ ! -f "$templates/$1" ]]; then
|
||||
_omz::log error "missing template '${templates/#$HOME/\~}/$1'." "omz::generate::plugin"
|
||||
return 1
|
||||
fi
|
||||
|
||||
local content="$(<"$templates/$1")" token m=$'\x1f'
|
||||
for token in completion cache name command description compgen; do
|
||||
content="${content//\%${token}\%/${m}${token}${m}}"
|
||||
done
|
||||
print -r -- "$content"
|
||||
}
|
||||
|
||||
# Fill in the placeholders of a template and write it to a file. Values come
|
||||
# from the caller: $name, $cmd, $description, $compgen, $block and $cache.
|
||||
#
|
||||
# Placeholders are matched as the markers that ::template produced, and the
|
||||
# marker character is stripped from every value, so a value that happens to
|
||||
# look like a placeholder (e.g. -d '%name%') is written out literally.
|
||||
function _omz::generate::plugin::render {
|
||||
setopt localoptions extendedglob
|
||||
local content m=$'\x1f'
|
||||
content="$(_omz::generate::plugin::template "$1")" || return 1
|
||||
|
||||
# Blocks go first: they are templates too and carry markers of their own
|
||||
content="${content//${m}completion${m}/$block}"
|
||||
content="${content//${m}cache${m}/$cache}"
|
||||
content="${content//${m}name${m}/${name//$m/}}"
|
||||
content="${content//${m}command${m}/${cmd//$m/}}"
|
||||
content="${content//${m}description${m}/${description//$m/}}"
|
||||
content="${content//${m}compgen${m}/${compgen//$m/}}"
|
||||
# Drop blank lines left behind by an empty placeholder at the end
|
||||
content="${content%%$'\n'##}"
|
||||
|
||||
created+=("$2")
|
||||
print -r -- "$content" > "$2" || return 1
|
||||
_omz::generate::plugin::created "$2"
|
||||
}
|
||||
|
||||
function _omz::generate::plugin::created {
|
||||
# Colour the verb with print -P, but print the path with print -r so that a
|
||||
# '%' somewhere in the path isn't treated as a prompt escape.
|
||||
# Keep the output plain when it is being piped.
|
||||
if [[ -t 1 ]]; then
|
||||
print -Pn " %F{green}create%f "
|
||||
else
|
||||
print -n " create "
|
||||
fi
|
||||
print -r -- "${1/#$HOME/\~}"
|
||||
}
|
||||
|
||||
function _omz::plugin {
|
||||
(( $# > 0 && $+functions[$0::$1] )) || {
|
||||
cat >&2 <<EOF
|
||||
@@ -892,7 +519,7 @@ function _omz::plugin::load {
|
||||
# Check if it has completion to reload compinit
|
||||
local -a comp_files
|
||||
comp_files=($base/_*(N))
|
||||
(( has_completion )) || has_completion=$(( $#comp_files > 0 ))
|
||||
has_completion=$(( $#comp_files > 0 ))
|
||||
|
||||
# Load the plugin
|
||||
if [[ -f "$base/$plugin.plugin.zsh" ]]; then
|
||||
|
||||
+1
-1
@@ -271,7 +271,7 @@ function _omz_diag_dump_check_core_commands() {
|
||||
unfunction unhash unlimit unset unsetopt vared wait whence where which zcompile
|
||||
zle zmodload zparseopts zregexparse zstyle )
|
||||
if is-at-least 5.1; then
|
||||
reserved_words+=( declare export integer float local readonly typeset )
|
||||
reserved_word+=( declare export integer float local readonly typeset )
|
||||
else
|
||||
builtins+=( declare export integer float local readonly typeset )
|
||||
fi
|
||||
|
||||
+12
-23
@@ -39,27 +39,16 @@ function _omz_git_prompt_info() {
|
||||
echo "${ZSH_THEME_GIT_PROMPT_PREFIX}${ref//\%/%%}${upstream//\%/%%}$(parse_git_dirty)${ZSH_THEME_GIT_PROMPT_SUFFIX}"
|
||||
}
|
||||
|
||||
# Match an extended regular expression against a subject, forcing the C locale
|
||||
# only for the duration of the call.
|
||||
#
|
||||
# OHMYZSH-13330: zsh's "=~" operator delegates to the C library regex, which
|
||||
# aborts with REG_ILLSEQ when the subject contains an invalid byte sequence
|
||||
# under a multibyte locale (e.g. a filename with non-UTF-8 bytes in `git
|
||||
# status` output). Forcing the C locale makes every byte a valid character,
|
||||
# so the regex matching never fails that way. `git status --porcelain` is
|
||||
# locale-independent, so this does not change the parsed output.
|
||||
#
|
||||
# OHMYZSH-13985: the locale must be scoped to this function and not set for
|
||||
# the whole caller. Assigning LC_ALL makes zsh re-run setlocale() right away,
|
||||
# so leaving it set while the rest of the caller runs breaks multibyte
|
||||
# handling there — most visibly, `echo` refuses to expand Unicode escapes in
|
||||
# theme prompt symbols ("character not in range").
|
||||
function _omz_git_prompt_status_match() {
|
||||
local -x LC_ALL=C
|
||||
[[ "$1" =~ "$2" ]]
|
||||
}
|
||||
|
||||
function _omz_git_prompt_status() {
|
||||
# OHMYZSH-13330: avoid "regex matching error: illegal byte sequence".
|
||||
# zsh's "=~" operator delegates to the C library regex, which aborts with
|
||||
# REG_ILLSEQ when the subject contains an invalid byte sequence under a
|
||||
# multibyte locale (e.g. a filename with non-UTF-8 bytes in `git status`
|
||||
# output). Forcing the C locale makes every byte a valid character, so the
|
||||
# regex matching below never fails that way. `git status --porcelain` is
|
||||
# locale-independent, so this does not change the parsed output.
|
||||
local -x LC_ALL=C
|
||||
|
||||
[[ "$(__git_prompt_git config --get oh-my-zsh.hide-status 2>/dev/null)" = 1 ]] && return
|
||||
|
||||
# Maps a git status prefix to an internal constant
|
||||
@@ -124,11 +113,11 @@ function _omz_git_prompt_status() {
|
||||
status_lines=("${(@f)${status_text}}")
|
||||
|
||||
# If the tracking line exists, get and parse it
|
||||
if _omz_git_prompt_status_match "$status_lines[1]" "^## [^ ]+ \[(.*)\]"; then
|
||||
if [[ "$status_lines[1]" =~ "^## [^ ]+ \[(.*)\]" ]]; then
|
||||
local branch_statuses
|
||||
branch_statuses=("${(@s/,/)match}")
|
||||
for branch_status in $branch_statuses; do
|
||||
if ! _omz_git_prompt_status_match "$branch_status" "(behind|diverged|ahead) ([0-9]+)?"; then
|
||||
if [[ ! $branch_status =~ "(behind|diverged|ahead) ([0-9]+)?" ]]; then
|
||||
continue
|
||||
fi
|
||||
local last_parsed_status=$prefix_constant_map[$match[1]]
|
||||
@@ -141,7 +130,7 @@ function _omz_git_prompt_status() {
|
||||
local status_constant="${prefix_constant_map[$status_prefix]}"
|
||||
local status_regex=$'(^|\n)'"$status_prefix"
|
||||
|
||||
if _omz_git_prompt_status_match "$status_text" "$status_regex"; then
|
||||
if [[ "$status_text" =~ $status_regex ]]; then
|
||||
statuses_seen[$status_constant]=1
|
||||
fi
|
||||
done
|
||||
|
||||
@@ -1,198 +0,0 @@
|
||||
#!/usr/bin/zsh -df
|
||||
|
||||
# Tests for `omz generate plugin`. Run with: zsh lib/tests/generate-plugin.test.zsh
|
||||
|
||||
ZSH="${0:A:h:h:h}"
|
||||
ZSH_CUSTOM="$(mktemp -d)"
|
||||
trap 'command rm -rf "$ZSH_CUSTOM"' EXIT
|
||||
|
||||
source "$ZSH/lib/cli.zsh"
|
||||
|
||||
failures=0
|
||||
pass() { print -u2 "\e[32mSuccess\e[0m: $1" }
|
||||
fail() { print -u2 "\e[31mError\e[0m: $1"; (( failures++ )) }
|
||||
|
||||
# assert_files <plugin> <expected files, space separated>
|
||||
assert_files() {
|
||||
local actual="$(print -l "$ZSH_CUSTOM"/plugins/$1/*(N:t) "$ZSH_CUSTOM"/plugins/$1/_*(N:t) | sort -u | tr '\n' ' ')"
|
||||
local expected="$(print -l ${=2} | sort -u | tr '\n' ' ')"
|
||||
if [[ "$actual" == "$expected" ]]; then
|
||||
pass "$1 has files: $expected"
|
||||
else
|
||||
fail "$1 has files '$actual', expected '$expected'"
|
||||
fi
|
||||
}
|
||||
|
||||
# assert_syntax <plugin>: every generated file must pass zsh -n, like CI does
|
||||
assert_syntax() {
|
||||
local file
|
||||
for file in "$ZSH_CUSTOM"/plugins/$1/*.plugin.zsh(N) "$ZSH_CUSTOM"/plugins/$1/_*(N); do
|
||||
if zsh -n "$file"; then
|
||||
pass "${file:t} passes zsh -n"
|
||||
else
|
||||
fail "${file:t} fails zsh -n"
|
||||
fi
|
||||
done
|
||||
}
|
||||
|
||||
# assert_contains <file> <literal string>
|
||||
assert_contains() {
|
||||
if grep -qF -- "$2" "$1"; then
|
||||
pass "${1:t} contains '$2'"
|
||||
else
|
||||
fail "${1:t} does not contain '$2'"
|
||||
fi
|
||||
}
|
||||
|
||||
## Templates must be valid zsh even before substitution (CI checks this too)
|
||||
|
||||
for file in "$ZSH"/templates/generators/plugin/*.zsh-template; do
|
||||
if zsh -n "$file"; then
|
||||
pass "template ${file:t} passes zsh -n"
|
||||
else
|
||||
fail "template ${file:t} fails zsh -n"
|
||||
fi
|
||||
done
|
||||
|
||||
## A plugin that wraps a command
|
||||
|
||||
description='Shortcuts & stuff $(id) `id` 100%'
|
||||
if omz generate plugin foo -d "$description" -c foo --yes >/dev/null 2>&1; then
|
||||
pass "generates a command-wrapping plugin"
|
||||
else
|
||||
fail "generating a command-wrapping plugin failed"
|
||||
fi
|
||||
assert_files foo "README.md _foo foo.plugin.zsh"
|
||||
assert_syntax foo
|
||||
assert_contains "$ZSH_CUSTOM/plugins/foo/README.md" 'plugins=(... foo)'
|
||||
assert_contains "$ZSH_CUSTOM/plugins/foo/README.md" "$description"
|
||||
assert_contains "$ZSH_CUSTOM/plugins/foo/foo.plugin.zsh" "$description"
|
||||
assert_contains "$ZSH_CUSTOM/plugins/foo/foo.plugin.zsh" '$+commands[foo]'
|
||||
assert_contains "$ZSH_CUSTOM/plugins/foo/_foo" '#compdef foo'
|
||||
if grep -q '%[a-z]*%' "$ZSH_CUSTOM"/plugins/foo/*; then
|
||||
fail "foo still has unfilled placeholders"
|
||||
else
|
||||
pass "foo has no unfilled placeholders"
|
||||
fi
|
||||
|
||||
## Values that look like placeholders are written literally
|
||||
|
||||
omz generate plugin lit -d '%compgen% and %name% stay' -c lit --yes >/dev/null 2>&1
|
||||
assert_contains "$ZSH_CUSTOM/plugins/lit/README.md" '%compgen% and %name% stay'
|
||||
assert_contains "$ZSH_CUSTOM/plugins/lit/lit.plugin.zsh" '%compgen% and %name% stay'
|
||||
|
||||
## A plugin with no command
|
||||
|
||||
if omz generate plugin bar --yes >/dev/null 2>&1; then
|
||||
pass "generates a generic plugin"
|
||||
else
|
||||
fail "generating a generic plugin failed"
|
||||
fi
|
||||
assert_files bar "README.md bar.plugin.zsh"
|
||||
assert_syntax bar
|
||||
assert_contains "$ZSH_CUSTOM/plugins/bar/README.md" 'This plugin does not add any aliases.'
|
||||
assert_contains "$ZSH_CUSTOM/plugins/bar/bar.plugin.zsh" 'bar plugin for Oh My Zsh'
|
||||
|
||||
## --no-completion, and the rails-style output
|
||||
|
||||
output="$(omz generate plugin baz -c baz --no-completion --yes 2>/dev/null)"
|
||||
assert_files baz "README.md baz.plugin.zsh"
|
||||
create_lines=$(print -r -- "$output" | grep -c '^ create ')
|
||||
if (( create_lines == 3 )); then
|
||||
pass "prints one create line per path"
|
||||
else
|
||||
fail "expected 3 create lines, got $create_lines"
|
||||
fi
|
||||
if [[ "$output" == *"omz plugin load baz"* ]]; then
|
||||
pass "prints next steps"
|
||||
else
|
||||
fail "next steps missing from output"
|
||||
fi
|
||||
|
||||
## Bad names are rejected without touching the filesystem
|
||||
|
||||
before="$(print -l "$ZSH_CUSTOM"/plugins/*(N:t))"
|
||||
for bad in '' 'Foo' 'a b' '../evil' 'a/b' '.hidden' '.' '..' '-x' 'foo`id`' 'foo"$(id)"' $'a\nb' "$(printf 'x%.0s' {1..65})"; do
|
||||
if omz generate plugin "$bad" --yes >/dev/null 2>&1; then
|
||||
fail "accepted bad name ${(qq)bad}"
|
||||
else
|
||||
pass "rejected bad name ${(qq)bad}"
|
||||
fi
|
||||
done
|
||||
after="$(print -l "$ZSH_CUSTOM"/plugins/*(N:t))"
|
||||
if [[ "$before" == "$after" ]]; then
|
||||
pass "bad names created nothing"
|
||||
else
|
||||
fail "bad names changed \$ZSH_CUSTOM/plugins"
|
||||
fi
|
||||
|
||||
## Bad command names are rejected
|
||||
|
||||
for bad in 'a b' '../x' 'foo;id' 'foo$(id)'; do
|
||||
if omz generate plugin qux -c "$bad" --yes >/dev/null 2>&1; then
|
||||
fail "accepted bad command ${(qq)bad}"
|
||||
else
|
||||
pass "rejected bad command ${(qq)bad}"
|
||||
fi
|
||||
done
|
||||
|
||||
## Existing plugin, unknown option, missing templates
|
||||
|
||||
if omz generate plugin foo --yes >/dev/null 2>&1; then
|
||||
fail "overwrote an existing plugin"
|
||||
else
|
||||
pass "refuses to overwrite an existing plugin"
|
||||
fi
|
||||
|
||||
if omz generate plugin quux --bogus --yes >/dev/null 2>&1; then
|
||||
fail "accepted an unknown option"
|
||||
else
|
||||
pass "rejects an unknown option"
|
||||
fi
|
||||
|
||||
if ( ZSH=/nonexistent; omz generate plugin quux --yes >/dev/null 2>&1 ); then
|
||||
fail "ran without templates"
|
||||
else
|
||||
pass "fails cleanly when templates are missing"
|
||||
fi
|
||||
[[ -e "$ZSH_CUSTOM/plugins/quux" ]] && fail "quux was created by a failed run"
|
||||
|
||||
## A failure after the first file is written removes everything it created
|
||||
|
||||
broken="$(mktemp -d)"
|
||||
mkdir -p "$broken/templates/generators/plugin" "$broken/plugins"
|
||||
cp "$ZSH/templates/generators/plugin/plugin.zsh-template" \
|
||||
"$ZSH/templates/generators/plugin/completion-note.zsh-template" "$broken/templates/generators/plugin/"
|
||||
# README.md-template is missing, so the plugin file is written and then the README fails
|
||||
if ( ZSH="$broken"; omz generate plugin partial -c partial --yes >/dev/null 2>&1 ); then
|
||||
fail "succeeded with a missing README template"
|
||||
else
|
||||
pass "fails when a later template is missing"
|
||||
fi
|
||||
if [[ -e "$ZSH_CUSTOM/plugins/partial" ]]; then
|
||||
fail "partial plugin directory was left behind: $(ls "$ZSH_CUSTOM/plugins/partial")"
|
||||
else
|
||||
pass "cleans up the partial plugin directory"
|
||||
fi
|
||||
command rm -rf "$broken"
|
||||
|
||||
## The prompt helper
|
||||
|
||||
_omz::generate::plugin::ask "Q" "dflt" 2>/dev/null < <(print '')
|
||||
[[ "$REPLY" == "dflt" ]] && pass "ask: empty answer takes the default" || fail "ask: got '$REPLY', expected 'dflt'"
|
||||
|
||||
_omz::generate::plugin::ask "Q" "dflt" 2>/dev/null < <(print ' hi there ')
|
||||
[[ "$REPLY" == "hi there" ]] && pass "ask: trims whitespace" || fail "ask: got '$REPLY', expected 'hi there'"
|
||||
|
||||
if _omz::generate::plugin::ask "Q" 2>/dev/null < /dev/null; then
|
||||
fail "ask: did not fail on EOF"
|
||||
else
|
||||
pass "ask: fails on EOF"
|
||||
fi
|
||||
|
||||
print -u2
|
||||
if (( failures )); then
|
||||
print -u2 "\e[31m$failures test(s) failed\e[0m"
|
||||
exit 1
|
||||
fi
|
||||
print -u2 "\e[32mAll tests passed\e[0m"
|
||||
@@ -9,11 +9,7 @@ if [[ ! -f "$ZSH_CACHE_DIR/completions/_op" ]]; then
|
||||
_comps[op]=_op
|
||||
fi
|
||||
|
||||
zmodload -F zsh/files b:zf_mv
|
||||
() {
|
||||
local TMPPREFIX="$ZSH_CACHE_DIR/completions/_op"
|
||||
zf_mv -f -- =( op completion zsh ) "$TMPPREFIX"
|
||||
} &|
|
||||
op completion zsh >| "$ZSH_CACHE_DIR/completions/_op" &|
|
||||
|
||||
# Load opswd function
|
||||
autoload -Uz opswd
|
||||
|
||||
@@ -11,8 +11,4 @@ if [[ ! -f "$ZSH_CACHE_DIR/completions/_arduino-cli" ]]; then
|
||||
fi
|
||||
|
||||
# Generate and load arduino-cli completion
|
||||
zmodload -F zsh/files b:zf_mv
|
||||
() {
|
||||
local TMPPREFIX="$ZSH_CACHE_DIR/completions/_arduino-cli"
|
||||
zf_mv -f -- =( arduino-cli completion zsh ) "$TMPPREFIX"
|
||||
} &|
|
||||
arduino-cli completion zsh >! "$ZSH_CACHE_DIR/completions/_arduino-cli" &|
|
||||
|
||||
@@ -11,8 +11,4 @@ if [[ ! -f "$ZSH_CACHE_DIR/completions/_argocd" ]]; then
|
||||
_comps[argocd]=_argocd
|
||||
fi
|
||||
|
||||
zmodload -F zsh/files b:zf_mv
|
||||
() {
|
||||
local TMPPREFIX="$ZSH_CACHE_DIR/completions/_argocd"
|
||||
zf_mv -f -- =( argocd completion zsh ) "$TMPPREFIX"
|
||||
} &|
|
||||
argocd completion zsh >| "$ZSH_CACHE_DIR/completions/_argocd" &|
|
||||
|
||||
@@ -12,8 +12,4 @@ if [[ ! -f "$ZSH_CACHE_DIR/completions/_asdf" ]]; then
|
||||
autoload -Uz _asdf
|
||||
_comps[asdf]=_asdf
|
||||
fi
|
||||
zmodload -F zsh/files b:zf_mv
|
||||
() {
|
||||
local TMPPREFIX="$ZSH_CACHE_DIR/completions/_asdf"
|
||||
zf_mv -f -- =( asdf completion zsh ) "$TMPPREFIX"
|
||||
} &|
|
||||
asdf completion zsh >| "$ZSH_CACHE_DIR/completions/_asdf" &|
|
||||
|
||||
@@ -69,7 +69,7 @@ function asr() {
|
||||
local -a available_regions
|
||||
available_regions=($(aws_regions))
|
||||
if [[ -z "${available_regions[(r)$1]}" ]]; then
|
||||
echo "${fg[red]}Available regions: \n$(aws_regions)${reset_color}" >&2
|
||||
echo "${fg[red]}Available regions: \n$(aws_regions)"
|
||||
return 1
|
||||
fi
|
||||
|
||||
|
||||
@@ -11,8 +11,4 @@ if [[ ! -f "$ZSH_CACHE_DIR/completions/_buf" ]]; then
|
||||
fi
|
||||
|
||||
# Generate and load buf completion
|
||||
zmodload -F zsh/files b:zf_mv
|
||||
() {
|
||||
local TMPPREFIX="$ZSH_CACHE_DIR/completions/_buf"
|
||||
zf_mv -f -- =( buf completion zsh ) "$TMPPREFIX"
|
||||
} &|
|
||||
buf completion zsh >! "$ZSH_CACHE_DIR/completions/_buf" &|
|
||||
@@ -11,8 +11,4 @@ if [[ ! -f "$ZSH_CACHE_DIR/completions/_bun" ]]; then
|
||||
_comps[bun]=_bun
|
||||
fi
|
||||
|
||||
zmodload -F zsh/files b:zf_mv
|
||||
() {
|
||||
local TMPPREFIX="$ZSH_CACHE_DIR/completions/_bun"
|
||||
zf_mv -f -- =( SHELL=zsh bun completions ) "$TMPPREFIX"
|
||||
} &|
|
||||
SHELL=zsh bun completions >| "$ZSH_CACHE_DIR/completions/_bun" &|
|
||||
|
||||
@@ -11,8 +11,4 @@ if [[ ! -f "$ZSH_CACHE_DIR/completions/_charm" ]]; then
|
||||
_comps[charm]=_charm
|
||||
fi
|
||||
|
||||
zmodload -F zsh/files b:zf_mv
|
||||
() {
|
||||
local TMPPREFIX="$ZSH_CACHE_DIR/completions/_charm"
|
||||
zf_mv -f -- =( charm completion zsh ) "$TMPPREFIX"
|
||||
} &|
|
||||
charm completion zsh >| "$ZSH_CACHE_DIR/completions/_charm" &|
|
||||
|
||||
@@ -11,8 +11,4 @@ if [[ ! -f "$ZSH_CACHE_DIR/completions/_chezmoi" ]]; then
|
||||
_comps[chezmoi]=_chezmoi
|
||||
fi
|
||||
|
||||
zmodload -F zsh/files b:zf_mv
|
||||
() {
|
||||
local TMPPREFIX="$ZSH_CACHE_DIR/completions/_chezmoi"
|
||||
zf_mv -f -- =( chezmoi completion zsh ) "$TMPPREFIX"
|
||||
} &|
|
||||
chezmoi completion zsh >| "$ZSH_CACHE_DIR/completions/_chezmoi" &|
|
||||
|
||||
@@ -11,8 +11,4 @@ if [[ ! -f "$ZSH_CACHE_DIR/completions/_codex" ]]; then
|
||||
_comps[codex]=_codex
|
||||
fi
|
||||
|
||||
zmodload -F zsh/files b:zf_mv
|
||||
() {
|
||||
local TMPPREFIX="$ZSH_CACHE_DIR/completions/_codex"
|
||||
zf_mv -f -- =( codex completion zsh < /dev/null 2> /dev/null ) "$TMPPREFIX"
|
||||
} &|
|
||||
codex completion zsh < /dev/null 2> /dev/null >| "$ZSH_CACHE_DIR/completions/_codex" &|
|
||||
|
||||
@@ -25,8 +25,4 @@ if [[ ! -f "$ZSH_CACHE_DIR/completions/_deno" ]]; then
|
||||
_comps[deno]=_deno
|
||||
fi
|
||||
|
||||
zmodload -F zsh/files b:zf_mv
|
||||
() {
|
||||
local TMPPREFIX="$ZSH_CACHE_DIR/completions/_deno"
|
||||
zf_mv -f -- =( deno completions zsh ) "$TMPPREFIX"
|
||||
} &|
|
||||
deno completions zsh >| "$ZSH_CACHE_DIR/completions/_deno" &|
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
|
||||
This plugin provides completion for [docker-compose](https://docs.docker.com/compose/) as well as some
|
||||
aliases for frequent docker-compose commands.
|
||||
This plugin chooses automatically between the legacy `docker-compose` command and the modern
|
||||
This plugin chooses automatically between the legacy `docker-compose` command and the modern
|
||||
`docker compose` subcommand, preferring `docker-compose` when both are available.
|
||||
|
||||
To use it, add docker-compose to the plugins array of your zshrc file:
|
||||
@@ -17,7 +17,6 @@ plugins=(... docker-compose)
|
||||
|-----------|----------------------------------|----------------------------------------------------------------------------------|
|
||||
| dco | `docker-compose` | Docker-compose main command |
|
||||
| dcb | `docker-compose build` | Build containers |
|
||||
| dcc | `docker-compose config` | Parse, resolve and render compose file in canonical format |
|
||||
| dce | `docker-compose exec` | Execute command inside a container |
|
||||
| dcps | `docker-compose ps` | List containers |
|
||||
| dcrestart | `docker-compose restart` | Restart container |
|
||||
|
||||
@@ -6,7 +6,6 @@
|
||||
|
||||
alias dco="$dccmd"
|
||||
alias dcb="$dccmd build"
|
||||
alias dcc="$dccmd config"
|
||||
alias dce="$dccmd exec"
|
||||
alias dcps="$dccmd ps"
|
||||
alias dcrestart="$dccmd restart"
|
||||
|
||||
@@ -56,19 +56,14 @@ if [[ ! -f "$ZSH_CACHE_DIR/completions/_docker" ]]; then
|
||||
_comps[docker]=_docker
|
||||
fi
|
||||
|
||||
zmodload -F zsh/files b:zf_mv
|
||||
() {
|
||||
|
||||
local plugin_dir="$1"
|
||||
|
||||
{
|
||||
# `docker completion` is only available from 23.0.0 on
|
||||
# docker version returns `Docker version 24.0.2, build cb74dfcd85`
|
||||
# with `s:,:` remove the comma after the version, and select third word of it
|
||||
if zstyle -t ':omz:plugins:docker' legacy-completion || \
|
||||
! is-at-least 23.0.0 ${${(s:,:z)"$(command docker --version)"}[3]}; then
|
||||
command cp "${plugin_dir}/completions/_docker" "$ZSH_CACHE_DIR/completions/_docker"
|
||||
command cp "${0:h}/completions/_docker" "$ZSH_CACHE_DIR/completions/_docker"
|
||||
else
|
||||
local TMPPREFIX="$ZSH_CACHE_DIR/completions/_docker"
|
||||
zf_mv -f -- =( command docker completion zsh ) "$TMPPREFIX"
|
||||
command docker completion zsh | tee "$ZSH_CACHE_DIR/completions/_docker" > /dev/null
|
||||
fi
|
||||
} "${0:A:h}" &|
|
||||
} &|
|
||||
|
||||
@@ -14,8 +14,4 @@ if [[ ! -f "$ZSH_CACHE_DIR/completions/_doctl" ]]; then
|
||||
_comps[doctl]=_doctl
|
||||
fi
|
||||
|
||||
zmodload -F zsh/files b:zf_mv
|
||||
() {
|
||||
local TMPPREFIX="$ZSH_CACHE_DIR/completions/_doctl"
|
||||
zf_mv -f -- =( doctl completion zsh ) "$TMPPREFIX"
|
||||
} &|
|
||||
doctl completion zsh >| "$ZSH_CACHE_DIR/completions/_doctl" &|
|
||||
|
||||
@@ -52,13 +52,8 @@ function _configure_eza() {
|
||||
if [[ $_val ]]; then
|
||||
_EZA_TAIL+=("--time-style='$_val'")
|
||||
fi
|
||||
if zstyle -t ':omz:plugins:eza' 'hyperlink'; then
|
||||
# eza >= 0.23 needs an explicit WHEN value
|
||||
if command eza --hyperlink=auto --version &>/dev/null; then
|
||||
_EZA_TAIL+=("--hyperlink=auto")
|
||||
else
|
||||
_EZA_TAIL+=("--hyperlink")
|
||||
fi
|
||||
if zstyle -t ":omz:plugins:eza" "hyperlink"; then
|
||||
_EZA_TAIL+=("--hyperlink")
|
||||
fi
|
||||
}
|
||||
|
||||
|
||||
@@ -30,8 +30,4 @@ if [[ ! -f "$ZSH_CACHE_DIR/completions/_flutter" ]]; then
|
||||
_comps[flutter]=_flutter
|
||||
fi
|
||||
|
||||
zmodload -F zsh/files b:zf_mv
|
||||
() {
|
||||
local TMPPREFIX="$ZSH_CACHE_DIR/completions/_flutter"
|
||||
zf_mv -f -- =( flutter zsh-completion < /dev/null ) "$TMPPREFIX"
|
||||
} &|
|
||||
flutter zsh-completion < /dev/null >| "$ZSH_CACHE_DIR/completions/_flutter" &|
|
||||
@@ -11,8 +11,4 @@ if [[ ! -f "$ZSH_CACHE_DIR/completions/_flux" ]]; then
|
||||
_comps[flux]=_flux
|
||||
fi
|
||||
|
||||
zmodload -F zsh/files b:zf_mv
|
||||
() {
|
||||
local TMPPREFIX="$ZSH_CACHE_DIR/completions/_flux"
|
||||
zf_mv -f -- =( flux completion zsh ) "$TMPPREFIX"
|
||||
} &|
|
||||
flux completion zsh >| "$ZSH_CACHE_DIR/completions/_flux" &|
|
||||
|
||||
@@ -10,11 +10,7 @@ if [[ ! -f "$ZSH_CACHE_DIR/completions/_fnm" ]]; then
|
||||
_comps[fnm]=_fnm
|
||||
fi
|
||||
|
||||
zmodload -F zsh/files b:zf_mv
|
||||
() {
|
||||
local TMPPREFIX="$ZSH_CACHE_DIR/completions/_fnm"
|
||||
zf_mv -f -- =( fnm completions --shell=zsh ) "$TMPPREFIX"
|
||||
} &|
|
||||
fnm completions --shell=zsh >| "$ZSH_CACHE_DIR/completions/_fnm" &|
|
||||
|
||||
if zstyle -t ':omz:plugins:fnm' autostart; then
|
||||
local -a fnm_env_cmd
|
||||
|
||||
@@ -1,18 +0,0 @@
|
||||
# Grafana CLI plugin
|
||||
|
||||
This plugin adds completion for the [Grafana CLI (gcx)](https://github.com/grafana/gcx).
|
||||
|
||||
To use it, add `gcx` to the plugins array in your zshrc file:
|
||||
|
||||
```zsh
|
||||
plugins=(... gcx)
|
||||
```
|
||||
|
||||
This plugin does not add any aliases.
|
||||
|
||||
## Cache
|
||||
|
||||
This plugin caches the completion script and automatically updates it when the
|
||||
plugin is loaded, which is usually when you start a new terminal emulator.
|
||||
|
||||
The cache is stored at `$ZSH_CACHE_DIR/completions/_gcx`.
|
||||
@@ -1,18 +0,0 @@
|
||||
# Autocompletion for the Grafana CLI (gcx).
|
||||
if (( ! $+commands[gcx] )); then
|
||||
return
|
||||
fi
|
||||
|
||||
# If the completion file doesn't exist yet, we need to autoload it and
|
||||
# bind it to `gcx`. Otherwise, compinit will have already done that.
|
||||
if [[ ! -f "$ZSH_CACHE_DIR/completions/_gcx" ]]; then
|
||||
typeset -g -A _comps
|
||||
autoload -Uz _gcx
|
||||
_comps[gcx]=_gcx
|
||||
fi
|
||||
|
||||
zmodload -F zsh/files b:zf_mv
|
||||
() {
|
||||
local TMPPREFIX="$ZSH_CACHE_DIR/completions/_gcx"
|
||||
zf_mv -f -- =( gcx completion zsh ) "$TMPPREFIX"
|
||||
} &|
|
||||
@@ -11,8 +11,4 @@ if [[ ! -f "$ZSH_CACHE_DIR/completions/_gh" ]]; then
|
||||
_comps[gh]=_gh
|
||||
fi
|
||||
|
||||
zmodload -F zsh/files b:zf_mv
|
||||
() {
|
||||
local TMPPREFIX="$ZSH_CACHE_DIR/completions/_gh"
|
||||
zf_mv -f -- =( gh completion --shell zsh ) "$TMPPREFIX"
|
||||
} &|
|
||||
gh completion --shell zsh >| "$ZSH_CACHE_DIR/completions/_gh" &|
|
||||
|
||||
@@ -137,9 +137,8 @@ function gbda() {
|
||||
# Copied and modified from James Roeder (jmaroeder) under MIT License
|
||||
# https://github.com/jmaroeder/plugin-git/blob/216723ef4f9e8dde399661c39c80bdf73f4076c4/functions/gbda.fish
|
||||
function gbds() {
|
||||
local default_branch
|
||||
default_branch=$(git_main_branch) \
|
||||
|| default_branch=$(git_develop_branch)
|
||||
local default_branch=$(git_main_branch)
|
||||
(( ! $? )) || default_branch=$(git_develop_branch)
|
||||
|
||||
git for-each-ref refs/heads/ "--format=%(refname:short)" | \
|
||||
while read branch; do
|
||||
|
||||
@@ -9,9 +9,5 @@ if [[ ! -f "$ZSH_CACHE_DIR/completions/_hasura" ]]; then
|
||||
source "$ZSH_CACHE_DIR/completions/_hasura"
|
||||
else
|
||||
source "$ZSH_CACHE_DIR/completions/_hasura"
|
||||
zmodload -F zsh/files b:zf_mv
|
||||
() {
|
||||
local TMPPREFIX="$ZSH_CACHE_DIR/completions/_hasura"
|
||||
zf_mv -f -- =( hasura completion zsh ) "$TMPPREFIX"
|
||||
} &|
|
||||
hasura completion zsh --file "$ZSH_CACHE_DIR/completions/_hasura" >/dev/null &|
|
||||
fi
|
||||
|
||||
@@ -13,11 +13,7 @@ if [[ ! -f "$ZSH_CACHE_DIR/completions/_hcloud" ]]; then
|
||||
_comps[hcloud]=_hcloud
|
||||
fi
|
||||
|
||||
zmodload -F zsh/files b:zf_mv
|
||||
() {
|
||||
local TMPPREFIX="$ZSH_CACHE_DIR/completions/_hcloud"
|
||||
zf_mv -f -- =( hcloud completion zsh 2> /dev/null ) "$TMPPREFIX"
|
||||
} &|
|
||||
hcloud completion zsh 2> /dev/null >| "$ZSH_CACHE_DIR/completions/_hcloud" &|
|
||||
|
||||
# Main alias
|
||||
alias hc='hcloud'
|
||||
|
||||
@@ -9,11 +9,7 @@ if [[ ! -f "$ZSH_CACHE_DIR/completions/_helm" ]]; then
|
||||
source "$ZSH_CACHE_DIR/completions/_helm"
|
||||
else
|
||||
source "$ZSH_CACHE_DIR/completions/_helm"
|
||||
zmodload -F zsh/files b:zf_mv
|
||||
() {
|
||||
local TMPPREFIX="$ZSH_CACHE_DIR/completions/_helm"
|
||||
zf_mv -f -- =( helm completion zsh ) "$TMPPREFIX"
|
||||
} &|
|
||||
helm completion zsh | tee "$ZSH_CACHE_DIR/completions/_helm" >/dev/null &|
|
||||
fi
|
||||
|
||||
alias h='helm'
|
||||
|
||||
@@ -11,11 +11,7 @@ if [[ ! -f "$ZSH_CACHE_DIR/completions/_jj" ]]; then
|
||||
_comps[jj]=_jj
|
||||
fi
|
||||
|
||||
zmodload -F zsh/files b:zf_mv
|
||||
() {
|
||||
local TMPPREFIX="$ZSH_CACHE_DIR/completions/_jj"
|
||||
zf_mv -f -- =( COMPLETE=zsh jj ) "$TMPPREFIX"
|
||||
} &|
|
||||
COMPLETE=zsh jj >| "$ZSH_CACHE_DIR/completions/_jj" &|
|
||||
|
||||
function __jj_prompt_jj() {
|
||||
local -a flags
|
||||
@@ -76,3 +72,4 @@ alias jjsq='jj squash'
|
||||
alias jjst='jj status'
|
||||
alias jjwa='jj workspace add'
|
||||
alias jjwf='jj workspace forget'
|
||||
|
||||
|
||||
@@ -11,8 +11,4 @@ fi
|
||||
|
||||
# and then generate it in the background. On first completion,
|
||||
# the actual completion file will be loaded.
|
||||
zmodload -F zsh/files b:zf_mv
|
||||
() {
|
||||
local TMPPREFIX="$ZSH_CACHE_DIR/completions/_k9s"
|
||||
zf_mv -f -- =( k9s completion zsh ) "$TMPPREFIX"
|
||||
} &|
|
||||
k9s completion zsh >| "$ZSH_CACHE_DIR/completions/_k9s" &|
|
||||
|
||||
@@ -11,11 +11,7 @@ if [[ ! -f "$ZSH_CACHE_DIR/completions/_kind" ]]; then
|
||||
fi
|
||||
|
||||
# Generate and load kind completion
|
||||
zmodload -F zsh/files b:zf_mv
|
||||
() {
|
||||
local TMPPREFIX="$ZSH_CACHE_DIR/completions/_kind"
|
||||
zf_mv -f -- =( kind completion zsh ) "$TMPPREFIX"
|
||||
} &|
|
||||
kind completion zsh >! "$ZSH_CACHE_DIR/completions/_kind" &|
|
||||
|
||||
# Register aliases
|
||||
alias kicc="kind create cluster"
|
||||
|
||||
@@ -10,11 +10,7 @@ if [[ ! -f "$ZSH_CACHE_DIR/completions/_kubectl" ]]; then
|
||||
_comps[kubectl]=_kubectl
|
||||
fi
|
||||
|
||||
zmodload -F zsh/files b:zf_mv
|
||||
() {
|
||||
local TMPPREFIX="$ZSH_CACHE_DIR/completions/_kubectl"
|
||||
zf_mv -f -- =( kubectl completion zsh 2> /dev/null ) "$TMPPREFIX"
|
||||
} &|
|
||||
kubectl completion zsh 2> /dev/null >| "$ZSH_CACHE_DIR/completions/_kubectl" &|
|
||||
|
||||
# This command is used a LOT both below and in daily life
|
||||
alias k=kubectl
|
||||
|
||||
@@ -22,21 +22,6 @@ RPS1='$(kubectx_prompt_info)'
|
||||
PROMPT="$PROMPT"'$(kubectx_prompt_info)'
|
||||
```
|
||||
|
||||
The context is loaded asynchronously on supported versions of zsh so that
|
||||
`kubectl` does not block the prompt. To restore synchronous behavior, add this
|
||||
before Oh My Zsh is sourced:
|
||||
|
||||
```zsh
|
||||
zstyle ':omz:alpha:plugins:kubectx' async-prompt no
|
||||
```
|
||||
|
||||
If your theme calls `kubectx_prompt_info` indirectly through another function,
|
||||
force registration of the async handler instead:
|
||||
|
||||
```zsh
|
||||
zstyle ':omz:alpha:plugins:kubectx' async-prompt force
|
||||
```
|
||||
|
||||
### Custom context names
|
||||
|
||||
You can rename the default context name for better readability or additional formatting.
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
typeset -g -A kubectx_mapping
|
||||
|
||||
function _omz_kubectx_prompt_info() {
|
||||
function kubectx_prompt_info() {
|
||||
(( $+commands[kubectl] )) || return
|
||||
|
||||
local current_ctx=$(kubectl config current-context 2> /dev/null)
|
||||
@@ -13,34 +13,3 @@ function _omz_kubectx_prompt_info() {
|
||||
# the context name, as it could contain a % character.
|
||||
echo "${kubectx_mapping[$current_ctx]:-${current_ctx:gs/%/%%}}"
|
||||
}
|
||||
|
||||
function kubectx_prompt_info() {
|
||||
if (( ${+_OMZ_ASYNC_OUTPUT} )) \
|
||||
&& [[ -n "${_OMZ_ASYNC_OUTPUT[_omz_kubectx_prompt_info]-}" ]]; then
|
||||
echo -n "${_OMZ_ASYNC_OUTPUT[_omz_kubectx_prompt_info]}"
|
||||
fi
|
||||
}
|
||||
|
||||
local _style
|
||||
if zstyle -t ':omz:alpha:plugins:kubectx' async-prompt \
|
||||
|| { is-at-least 5.0.6 && zstyle -T ':omz:alpha:plugins:kubectx' async-prompt }; then
|
||||
function _defer_async_kubectx_register() {
|
||||
case "${PS1}:${PS2}:${PS3}:${PS4}:${RPROMPT-}:${RPS1-}:${RPS2-}:${RPS3-}:${RPS4-}" in
|
||||
*(\$\(kubectx_prompt_info\)|\`kubectx_prompt_info\`)*)
|
||||
_omz_register_handler _omz_kubectx_prompt_info
|
||||
;;
|
||||
esac
|
||||
|
||||
add-zsh-hook -d precmd _defer_async_kubectx_register
|
||||
unset -f _defer_async_kubectx_register
|
||||
}
|
||||
|
||||
autoload -Uz add-zsh-hook
|
||||
precmd_functions=(_defer_async_kubectx_register $precmd_functions)
|
||||
elif zstyle -s ':omz:alpha:plugins:kubectx' async-prompt _style && [[ $_style == "force" ]]; then
|
||||
_omz_register_handler _omz_kubectx_prompt_info
|
||||
else
|
||||
function kubectx_prompt_info() {
|
||||
_omz_kubectx_prompt_info
|
||||
}
|
||||
fi
|
||||
|
||||
@@ -10,7 +10,6 @@ plugins=(... laravel)
|
||||
|:-:|:-:|
|
||||
| `artisan` | `php artisan` |
|
||||
| `pas` | `php artisan serve` |
|
||||
| `pad` | `php artisan dev` |
|
||||
| `pats` | `php artisan test` |
|
||||
|
||||
## Database
|
||||
@@ -42,7 +41,6 @@ plugins=(... laravel)
|
||||
| `pamen` | `php artisan make:enum` |
|
||||
| `pami` | `php artisan make:interface` |
|
||||
| `pamtr` | `php artisan make:trait` |
|
||||
| `pamv` | `php artisan make:view` |
|
||||
|
||||
## Clears
|
||||
|
||||
|
||||
@@ -4,7 +4,6 @@ alias bob='php artisan bob::build'
|
||||
|
||||
# Development
|
||||
alias pas='php artisan serve'
|
||||
alias pad='php artisan dev'
|
||||
alias pats='php artisan test'
|
||||
|
||||
# Database
|
||||
@@ -31,7 +30,6 @@ alias pamcl='php artisan make:class'
|
||||
alias pamen='php artisan make:enum'
|
||||
alias pami='php artisan make:interface'
|
||||
alias pamtr='php artisan make:trait'
|
||||
alias pamv='php artisan make:view'
|
||||
|
||||
|
||||
# Clears
|
||||
|
||||
@@ -10,8 +10,4 @@ if [[ ! -f "$ZSH_CACHE_DIR/completions/_minikube" ]]; then
|
||||
_comps[minikube]=_minikube
|
||||
fi
|
||||
|
||||
zmodload -F zsh/files b:zf_mv
|
||||
() {
|
||||
local TMPPREFIX="$ZSH_CACHE_DIR/completions/_minikube"
|
||||
zf_mv -f -- =( minikube completion zsh ) "$TMPPREFIX"
|
||||
} &|
|
||||
minikube completion zsh >| "$ZSH_CACHE_DIR/completions/_minikube" &|
|
||||
|
||||
@@ -1,14 +1,9 @@
|
||||
if (( $+commands[mise] )); then
|
||||
_mise_bin=mise
|
||||
elif [[ -x ~/.local/bin/mise ]]; then
|
||||
_mise_bin=~/.local/bin/mise
|
||||
else
|
||||
if (( ! $+commands[mise] )); then
|
||||
return
|
||||
fi
|
||||
|
||||
# Load mise hooks
|
||||
eval "$($_mise_bin activate zsh)"
|
||||
unset _mise_bin
|
||||
eval "$(mise activate zsh)"
|
||||
|
||||
# If the completion file doesn't exist yet, we need to autoload it and
|
||||
# bind it to `mise`. Otherwise, compinit will have already done that.
|
||||
@@ -19,8 +14,4 @@ if [[ ! -f "$ZSH_CACHE_DIR/completions/_mise" ]]; then
|
||||
fi
|
||||
|
||||
# Generate and load mise completion
|
||||
zmodload -F zsh/files b:zf_mv
|
||||
() {
|
||||
local TMPPREFIX="$ZSH_CACHE_DIR/completions/_mise"
|
||||
zf_mv -f -- =( mise completion zsh ) "$TMPPREFIX"
|
||||
} &|
|
||||
mise completion zsh >| "$ZSH_CACHE_DIR/completions/_mise" &|
|
||||
|
||||
@@ -11,11 +11,7 @@ if [[ ! -f "$ZSH_CACHE_DIR/completions/_molecule" ]]; then
|
||||
_comps[molecule]=_molecule
|
||||
fi
|
||||
|
||||
zmodload -F zsh/files b:zf_mv
|
||||
() {
|
||||
local TMPPREFIX="$ZSH_CACHE_DIR/completions/_molecule"
|
||||
zf_mv -f -- =( _MOLECULE_COMPLETE=zsh_source molecule ) "$TMPPREFIX"
|
||||
} &|
|
||||
_MOLECULE_COMPLETE=zsh_source molecule >| "$ZSH_CACHE_DIR/completions/_molecule" &|
|
||||
|
||||
# Alias
|
||||
# molecule: https://docs.ansible.com/projects/molecule/
|
||||
|
||||
@@ -11,8 +11,4 @@ if [[ ! -f "$ZSH_CACHE_DIR/completions/_atlas" ]]; then
|
||||
_comps[atlas]=_atlas
|
||||
fi
|
||||
|
||||
zmodload -F zsh/files b:zf_mv
|
||||
() {
|
||||
local TMPPREFIX="$ZSH_CACHE_DIR/completions/_atlas"
|
||||
zf_mv -f -- =( atlas completion zsh ) "$TMPPREFIX"
|
||||
} &|
|
||||
atlas completion zsh >| "$ZSH_CACHE_DIR/completions/atlas" &|
|
||||
|
||||
@@ -7,11 +7,7 @@ if (( $+commands[nsc] )); then
|
||||
_comps[nsc]=_nsc
|
||||
fi
|
||||
|
||||
zmodload -F zsh/files b:zf_mv
|
||||
() {
|
||||
local TMPPREFIX="$ZSH_CACHE_DIR/completions/_nsc"
|
||||
zf_mv -f -- =( nsc completion zsh ) "$TMPPREFIX"
|
||||
} &|
|
||||
nsc completion zsh >| "$ZSH_CACHE_DIR/completions/_nsc" &|
|
||||
fi
|
||||
|
||||
if (( $+commands[nats] )); then
|
||||
@@ -23,9 +19,5 @@ if (( $+commands[nats] )); then
|
||||
_comps[nats]=_nats
|
||||
fi
|
||||
|
||||
zmodload -F zsh/files b:zf_mv
|
||||
() {
|
||||
local TMPPREFIX="$ZSH_CACHE_DIR/completions/_nats"
|
||||
zf_mv -f -- =( nats --completion-script-zsh ) "$TMPPREFIX"
|
||||
} &|
|
||||
nats --completion-script-zsh >| "$ZSH_CACHE_DIR/completions/_nats" &|
|
||||
fi
|
||||
|
||||
@@ -11,8 +11,4 @@ if [[ ! -f "$ZSH_CACHE_DIR/completions/_ngrok" ]]; then
|
||||
_comps[ngrok]=_ngrok
|
||||
fi
|
||||
|
||||
zmodload -F zsh/files b:zf_mv
|
||||
() {
|
||||
local TMPPREFIX="$ZSH_CACHE_DIR/completions/_ngrok"
|
||||
zf_mv -f -- =( ngrok completion zsh ) "$TMPPREFIX"
|
||||
} &|
|
||||
ngrok completion zsh >| "$ZSH_CACHE_DIR/completions/_ngrok" &|
|
||||
|
||||
@@ -11,8 +11,4 @@ if [[ ! -f "$ZSH_CACHE_DIR/completions/_pass-cli" ]]; then
|
||||
_comps[pass-cli]=_pass-cli
|
||||
fi
|
||||
|
||||
zmodload -F zsh/files b:zf_mv
|
||||
() {
|
||||
local TMPPREFIX="$ZSH_CACHE_DIR/completions/_pass-cli"
|
||||
zf_mv -f -- =( pass-cli completions zsh ) "$TMPPREFIX"
|
||||
} &|
|
||||
pass-cli completions zsh >| "$ZSH_CACHE_DIR/completions/_pass-cli" &|
|
||||
|
||||
@@ -112,6 +112,9 @@ function _per-directory-history-change-directory() {
|
||||
#read history in new file
|
||||
if [[ -e $_per_directory_history_directory ]]; then
|
||||
fc -R $_per_directory_history_directory
|
||||
# -p: push the new directory's history file as the active history context,
|
||||
# so that the history is kept up to date on every directory change.
|
||||
fc -p $_per_directory_history_directory
|
||||
fi
|
||||
fi
|
||||
}
|
||||
@@ -153,6 +156,7 @@ function _per-directory-history-set-directory-history() {
|
||||
HISTSIZE=$original_histsize
|
||||
if [[ -e "$_per_directory_history_directory" ]]; then
|
||||
fc -R "$_per_directory_history_directory"
|
||||
# -p: push the directory's history file as the active history context.
|
||||
fc -p "$_per_directory_history_directory"
|
||||
fi
|
||||
}
|
||||
@@ -164,6 +168,7 @@ function _per-directory-history-set-global-history() {
|
||||
HISTSIZE=$original_histsize
|
||||
if [[ -e "$_per_directory_history_global" ]]; then
|
||||
fc -R "$_per_directory_history_global"
|
||||
# -p: push the global history file as the active history context.
|
||||
fc -p "$_per_directory_history_global"
|
||||
fi
|
||||
}
|
||||
|
||||
@@ -43,11 +43,7 @@ else
|
||||
_comps[pipenv]=_pipenv
|
||||
fi
|
||||
|
||||
zmodload -F zsh/files b:zf_mv
|
||||
() {
|
||||
local TMPPREFIX="$ZSH_CACHE_DIR/completions/_pipenv"
|
||||
zf_mv -f -- =( _PIPENV_COMPLETE=zsh_source pipenv ) "$TMPPREFIX"
|
||||
} &|
|
||||
_PIPENV_COMPLETE=zsh_source pipenv >| "$ZSH_CACHE_DIR/completions/_pipenv" &|
|
||||
fi
|
||||
|
||||
if zstyle -T ':omz:plugins:pipenv' auto-shell; then
|
||||
@@ -56,26 +52,19 @@ if zstyle -T ':omz:plugins:pipenv' auto-shell; then
|
||||
# deactivate shell if Pipfile doesn't exist and not in a subdir
|
||||
if [[ ! -f "$PWD/Pipfile" ]]; then
|
||||
if [[ "$PIPENV_ACTIVE" == 1 ]]; then
|
||||
# Compare whole path components: `$pipfile_dir"*` also matches unrelated
|
||||
# siblings that merely start with the same text (…/proj -> …/proj-docs),
|
||||
# which would keep the virtualenv active outside the project.
|
||||
local project_dir="${pipfile_dir%/}"
|
||||
if [[ "$PWD" != "$project_dir" && "$PWD" != "$project_dir"/* ]]; then
|
||||
if [[ "$PWD" != "$pipfile_dir"* ]]; then
|
||||
unset PIPENV_ACTIVE pipfile_dir
|
||||
deactivate
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
|
||||
# activate the shell if Pipfile exists and its virtualenv is usable
|
||||
# activate the shell if Pipfile exists
|
||||
if [[ "$PIPENV_ACTIVE" != 1 ]]; then
|
||||
if [[ -f "$PWD/Pipfile" ]]; then
|
||||
local venv_path
|
||||
if venv_path="$(pipenv --venv 2>/dev/null)" && [[ -n "$venv_path" && -f "$venv_path/bin/activate" ]]; then
|
||||
export pipfile_dir="$PWD"
|
||||
source "$venv_path/bin/activate"
|
||||
export PIPENV_ACTIVE=1
|
||||
fi
|
||||
export pipfile_dir="$PWD"
|
||||
source "$(pipenv --venv)/bin/activate"
|
||||
export PIPENV_ACTIVE=1
|
||||
fi
|
||||
fi
|
||||
}
|
||||
|
||||
@@ -10,11 +10,7 @@ if [[ ! -f "$ZSH_CACHE_DIR/completions/_podman" ]]; then
|
||||
_comps[podman]=_podman
|
||||
fi
|
||||
|
||||
zmodload -F zsh/files b:zf_mv
|
||||
() {
|
||||
local TMPPREFIX="$ZSH_CACHE_DIR/completions/_podman"
|
||||
zf_mv -f -- =( podman completion zsh 2> /dev/null ) "$TMPPREFIX"
|
||||
} &|
|
||||
podman completion zsh 2> /dev/null >| "$ZSH_CACHE_DIR/completions/_podman" &|
|
||||
|
||||
alias pbl='podman build'
|
||||
alias pcin='podman container inspect'
|
||||
|
||||
@@ -1,9 +1,7 @@
|
||||
# Poetry Environment Plugin
|
||||
|
||||
This plugin automatically activates a Poetry environment when you enter a
|
||||
directory containing both `pyproject.toml` and `poetry.lock`. It keeps the
|
||||
environment active in project subdirectories, switches to nested Poetry
|
||||
projects, and deactivates it when you leave the project tree.
|
||||
This plugin automatically changes poetry environment when you cd into or out of the project directory.
|
||||
Note: Script looks for pyproject.toml file to determine poetry if its a poetry environment
|
||||
|
||||
To use it, add `poetry-env` to the plugins array in your zshrc file:
|
||||
|
||||
|
||||
@@ -1,24 +1,15 @@
|
||||
_togglePoetryShell() {
|
||||
# Determine if currently in a Poetry-managed directory
|
||||
local in_poetry_dir=0
|
||||
local in_active_poetry_dir=0
|
||||
if [[ -f "$PWD/pyproject.toml" && -f "$PWD/poetry.lock" ]]; then
|
||||
in_poetry_dir=1
|
||||
fi
|
||||
|
||||
# Deactivate when leaving the active project or entering a nested project
|
||||
if [[ $poetry_active -eq 1 ]]; then
|
||||
local project_dir="${poetry_dir%/}"
|
||||
if [[ "$PWD" == "$project_dir" || "$PWD" == "$project_dir"/* ]]; then
|
||||
in_active_poetry_dir=1
|
||||
fi
|
||||
|
||||
if [[ $in_active_poetry_dir -eq 0 ]] ||
|
||||
{ [[ $in_poetry_dir -eq 1 ]] && [[ "$PWD" != "$poetry_dir" ]]; }; then
|
||||
export poetry_active=0
|
||||
unset poetry_dir
|
||||
(( $+functions[deactivate] )) && deactivate
|
||||
fi
|
||||
# Deactivate the current environment if moving out of a Poetry directory or into a different Poetry directory
|
||||
if [[ $poetry_active -eq 1 ]] && { [[ $in_poetry_dir -eq 0 ]] || [[ "$PWD" != "$poetry_dir"* ]]; }; then
|
||||
export poetry_active=0
|
||||
unset poetry_dir
|
||||
(( $+functions[deactivate] )) && deactivate
|
||||
fi
|
||||
|
||||
# Activate the environment if in a Poetry directory and no environment is currently active
|
||||
|
||||
@@ -39,8 +39,4 @@ if [[ ! -f "$ZSH_CACHE_DIR/completions/_poetry" ]]; then
|
||||
_comps[poetry]=_poetry
|
||||
fi
|
||||
|
||||
zmodload -F zsh/files b:zf_mv
|
||||
() {
|
||||
local TMPPREFIX="$ZSH_CACHE_DIR/completions/_poetry"
|
||||
zf_mv -f -- =( poetry completions zsh ) "$TMPPREFIX"
|
||||
} &|
|
||||
poetry completions zsh >| "$ZSH_CACHE_DIR/completions/_poetry" &|
|
||||
|
||||
@@ -10,16 +10,12 @@ if [[ ! -f "$ZSH_CACHE_DIR/completions/_procs" ]]; then
|
||||
_comps[procs]=_procs
|
||||
fi
|
||||
|
||||
zmodload -F zsh/files b:zf_mv
|
||||
() {
|
||||
local TMPPREFIX="$ZSH_CACHE_DIR/completions/_procs"
|
||||
{
|
||||
autoload -Uz is-at-least
|
||||
local _version=$(procs --version)
|
||||
zf_mv -f -- =(
|
||||
if is-at-least "0.14" "${_version#procs }"; then
|
||||
procs --gen-completion-out zsh
|
||||
else
|
||||
procs --completion-out zsh
|
||||
fi
|
||||
) "$TMPPREFIX"
|
||||
if is-at-least "0.14" "${_version#procs }"; then
|
||||
procs --gen-completion-out zsh >| "$ZSH_CACHE_DIR/completions/_procs"
|
||||
else
|
||||
procs --completion-out zsh >| "$ZSH_CACHE_DIR/completions/_procs"
|
||||
fi
|
||||
} &|
|
||||
|
||||
@@ -10,11 +10,7 @@ if [[ ! -f "$ZSH_CACHE_DIR/completions/_pulumi" ]]; then
|
||||
_comps[pulumi]=_pulumi
|
||||
fi
|
||||
|
||||
zmodload -F zsh/files b:zf_mv
|
||||
() {
|
||||
local TMPPREFIX="$ZSH_CACHE_DIR/completions/_pulumi"
|
||||
zf_mv -f -- =( pulumi gen-completion zsh ) "$TMPPREFIX"
|
||||
} &|
|
||||
pulumi gen-completion zsh >| "$ZSH_CACHE_DIR/completions/_pulumi" &|
|
||||
|
||||
# Aliases
|
||||
alias pul='pulumi'
|
||||
|
||||
@@ -11,8 +11,4 @@ if [[ ! -f "$ZSH_CACHE_DIR/completions/_qodana" ]]; then
|
||||
_comps[qodana]=_qodana
|
||||
fi
|
||||
|
||||
zmodload -F zsh/files b:zf_mv
|
||||
() {
|
||||
local TMPPREFIX="$ZSH_CACHE_DIR/completions/_qodana"
|
||||
zf_mv -f -- =( qodana completion zsh ) "$TMPPREFIX"
|
||||
} &|
|
||||
qodana completion zsh >| "$ZSH_CACHE_DIR/completions/_qodana" &|
|
||||
|
||||
@@ -54,33 +54,6 @@ plugins=(... rails)
|
||||
| `rta` | `rails test:all` | Runs all Rails tests, including system tests |
|
||||
| `ru` | `rails runner` | Run Ruby code in the context of Rails |
|
||||
|
||||
### Multiple databases
|
||||
|
||||
Rails applications can define more than one database (`primary`, `cache`, `cable`,
|
||||
`queue`, ...), and each one gets its own namespaced task. These commands accept an
|
||||
optional database name as the first argument:
|
||||
|
||||
`rdc`, `rdd`, `rdm`, `rdmd`, `rdmr`, `rdms`, `rdmu`, `rdr`, `rdrs`, `rdsl`
|
||||
|
||||
```zsh
|
||||
rdm # rails db:migrate
|
||||
rdm cache # rails db:migrate:cache
|
||||
rdm VERSION=20231225 # rails db:migrate VERSION=20231225
|
||||
rdm cache STEP=2 # rails db:migrate:cache STEP=2
|
||||
rdm --trace # rails db:migrate --trace
|
||||
```
|
||||
|
||||
The first argument is read as a database name only when it is a bare word. Flags
|
||||
(`--trace`), variables (`STEP=2`) and other tasks (`db:seed`) are passed through to
|
||||
`rails` unchanged, so previous usage keeps working. When a database name is given,
|
||||
the resolved command is printed so it is clear which database is being used.
|
||||
|
||||
`rdmrs` is not in the list above because Rails does not define a per-database
|
||||
`db:migrate:reset` task.
|
||||
|
||||
Note that these are implemented as shell functions rather than aliases, so they will
|
||||
not appear in the output of `alias`.
|
||||
|
||||
### Foreman
|
||||
|
||||
| Alias | Command | Description |
|
||||
|
||||
@@ -47,9 +47,19 @@ alias rc='rails console'
|
||||
alias rcs='rails console --sandbox'
|
||||
alias rd='rails destroy'
|
||||
alias rdb='rails dbconsole'
|
||||
alias rdc='rails db:create'
|
||||
alias rdd='rails db:drop'
|
||||
alias rdm='rails db:migrate'
|
||||
alias rdmd='rails db:migrate:down'
|
||||
alias rdmr='rails db:migrate:redo'
|
||||
alias rdmrs='rails db:migrate:reset'
|
||||
alias rdms='rails db:migrate:status'
|
||||
alias rdmtc='rails db:migrate db:test:clone'
|
||||
alias rdmu='rails db:migrate:up'
|
||||
alias rdr='rails db:rollback'
|
||||
alias rdrs='rails db:reset'
|
||||
alias rds='rails db:seed'
|
||||
alias rdsl='rails db:schema:load'
|
||||
alias rdtc='rails db:test:clone'
|
||||
alias rdtp='rails db:test:prepare'
|
||||
alias rgen='rails generate'
|
||||
@@ -96,47 +106,6 @@ alias rkn='rake notes'
|
||||
alias rksts='rake stats'
|
||||
alias rkt='rake test'
|
||||
|
||||
# Database tasks
|
||||
#
|
||||
# Rails applications can define more than one database (primary, cache, cable,
|
||||
# queue, ...). Each one gets its own namespaced task, e.g. `db:migrate:cache`.
|
||||
# The functions below take an optional database name as the first argument:
|
||||
#
|
||||
# rdm -> rails db:migrate
|
||||
# rdm cache -> rails db:migrate:cache
|
||||
# rdm VERSION=20231225 -> rails db:migrate VERSION=20231225
|
||||
# rdm cache STEP=2 -> rails db:migrate:cache STEP=2
|
||||
# rdm --trace -> rails db:migrate --trace
|
||||
#
|
||||
# The first argument is read as a database name only when it is a bare word.
|
||||
# Flags (--trace), variables (STEP=2) and other tasks (db:seed) are passed
|
||||
# through to rails untouched, so the previous alias behavior still works.
|
||||
function _rails_db_command() {
|
||||
local task="$1"
|
||||
shift
|
||||
|
||||
if [[ $# -gt 0 && "$1" != -* && "$1" != *=* && "$1" != *:* ]]; then
|
||||
task="$task:$1"
|
||||
shift
|
||||
# Echo the resolved task so it is clear which database is being used
|
||||
local -a cmd=(rails "$task" "$@")
|
||||
print -u2 -r -- "Running: ${cmd[*]}"
|
||||
fi
|
||||
|
||||
rails "$task" "$@"
|
||||
}
|
||||
|
||||
function rdc() { _rails_db_command db:create "$@" }
|
||||
function rdd() { _rails_db_command db:drop "$@" }
|
||||
function rdm() { _rails_db_command db:migrate "$@" }
|
||||
function rdmd() { _rails_db_command db:migrate:down "$@" }
|
||||
function rdmr() { _rails_db_command db:migrate:redo "$@" }
|
||||
function rdms() { _rails_db_command db:migrate:status "$@" }
|
||||
function rdmu() { _rails_db_command db:migrate:up "$@" }
|
||||
function rdr() { _rails_db_command db:rollback "$@" }
|
||||
function rdrs() { _rails_db_command db:reset "$@" }
|
||||
function rdsl() { _rails_db_command db:schema:load "$@" }
|
||||
|
||||
# legacy stuff
|
||||
alias sc='ruby script/console'
|
||||
alias sd='ruby script/destroy'
|
||||
|
||||
@@ -10,11 +10,7 @@ if [[ ! -f "$ZSH_CACHE_DIR/completions/_rbw" ]]; then
|
||||
_comps[rbw]=_rbw
|
||||
fi
|
||||
|
||||
zmodload -F zsh/files b:zf_mv
|
||||
() {
|
||||
local TMPPREFIX="$ZSH_CACHE_DIR/completions/_rbw"
|
||||
zf_mv -f -- =( rbw gen-completions zsh ) "$TMPPREFIX"
|
||||
} &|
|
||||
rbw gen-completions zsh >| "$ZSH_CACHE_DIR/completions/_rbw" &|
|
||||
|
||||
# rbwpw function copies the password of a service to the clipboard
|
||||
# and clears it after 20 seconds
|
||||
|
||||
@@ -11,8 +11,4 @@ if [[ ! -f "$ZSH_CACHE_DIR/completions/_rclone" ]]; then
|
||||
_comps[rclone]=_rclone
|
||||
fi
|
||||
|
||||
zmodload -F zsh/files b:zf_mv
|
||||
() {
|
||||
local TMPPREFIX="$ZSH_CACHE_DIR/completions/_rclone"
|
||||
zf_mv -f -- =( rclone completion zsh - ) "$TMPPREFIX"
|
||||
} &|
|
||||
rclone completion zsh - >| "$ZSH_CACHE_DIR/completions/_rclone" &|
|
||||
|
||||
@@ -1,22 +0,0 @@
|
||||
# ruff plugin
|
||||
|
||||
This plugin automatically installs [ruff](https://github.com/astral-sh/ruff)'s completions for you,
|
||||
and keeps them up to date. It also adds convenient aliases for common usage.
|
||||
|
||||
To use it, add `ruff` to the plugins array in your zshrc file:
|
||||
|
||||
```zsh
|
||||
plugins=(... ruff)
|
||||
```
|
||||
|
||||
## Aliases
|
||||
|
||||
| Alias | Command | Description |
|
||||
| :---- | -------------------- | :----------------------------------------------------------- |
|
||||
| ruc | `ruff check` | Run Ruff linter on the given files or directories |
|
||||
| rucf | `ruff check --fix` | Run Ruff linter and fix auto-fixable issues |
|
||||
| ruf | `ruff format` | Run the Ruff formatter on the given files or directories |
|
||||
| rufc | `ruff format --check`| Check if files are already formatted without making changes |
|
||||
| rur | `ruff rule` | Explain a rule (or all rules) |
|
||||
| rul | `ruff linter` | List all supported upstream linters |
|
||||
| rucl | `ruff clean` | Clear any caches in the current directory and subdirectories |
|
||||
@@ -1,27 +0,0 @@
|
||||
# Return immediately if ruff is not found
|
||||
if (( ! ${+commands[ruff]} )); then
|
||||
return
|
||||
fi
|
||||
|
||||
alias ruc='ruff check'
|
||||
alias rucf='ruff check --fix'
|
||||
alias ruf='ruff format'
|
||||
alias rufc='ruff format --check'
|
||||
alias rur='ruff rule'
|
||||
alias rul='ruff linter'
|
||||
alias rucl='ruff clean'
|
||||
|
||||
# If the completion file doesn't exist yet, we need to autoload it and
|
||||
# bind it. Otherwise, compinit will have already done that.
|
||||
if [[ ! -f "$ZSH_CACHE_DIR/completions/_ruff" ]]; then
|
||||
typeset -g -A _comps
|
||||
autoload -Uz _ruff
|
||||
_comps[ruff]=_ruff
|
||||
fi
|
||||
|
||||
# Overwrites the file each time as completions might change with ruff versions.
|
||||
zmodload -F zsh/files b:zf_mv
|
||||
() {
|
||||
local TMPPREFIX="$ZSH_CACHE_DIR/completions/_ruff"
|
||||
zf_mv -f -- =( ruff generate-shell-completion zsh ) "$TMPPREFIX"
|
||||
} &|
|
||||
@@ -19,11 +19,7 @@ if [[ ! -f "$ZSH_CACHE_DIR/completions/_rustup" ]]; then
|
||||
fi
|
||||
|
||||
# Generate completion files in the background
|
||||
zmodload -F zsh/files b:zf_mv
|
||||
() {
|
||||
local TMPPREFIX="$ZSH_CACHE_DIR/completions/_rustup"
|
||||
zf_mv -f -- =( rustup completions zsh ) "$TMPPREFIX"
|
||||
} &|
|
||||
rustup completions zsh >| "$ZSH_CACHE_DIR/completions/_rustup" &|
|
||||
cat >| "$ZSH_CACHE_DIR/completions/_cargo" <<'EOF'
|
||||
#compdef cargo
|
||||
source "$(rustup run ${${(z)$(rustup default)}[1]} rustc --print sysroot)"/share/zsh/site-functions/_cargo
|
||||
|
||||
@@ -12,11 +12,7 @@ function install_autocompletion {
|
||||
_comps[$1]=_$1
|
||||
fi
|
||||
|
||||
zmodload -F zsh/files b:zf_mv
|
||||
() {
|
||||
local TMPPREFIX="$ZSH_CACHE_DIR/completions/_$1"
|
||||
zf_mv -f -- =( $1 completion zsh ) "$TMPPREFIX"
|
||||
} "$1" &|
|
||||
$1 completion zsh >| "$ZSH_CACHE_DIR/completions/_$1" &|
|
||||
}
|
||||
|
||||
install_autocompletion cosign
|
||||
|
||||
@@ -11,8 +11,4 @@ if [[ ! -f "$ZSH_CACHE_DIR/completions/_skaffold" ]]; then
|
||||
_comps[skaffold]=_skaffold
|
||||
fi
|
||||
|
||||
zmodload -F zsh/files b:zf_mv
|
||||
() {
|
||||
local TMPPREFIX="$ZSH_CACHE_DIR/completions/_skaffold"
|
||||
zf_mv -f -- =( skaffold completion zsh ) "$TMPPREFIX"
|
||||
} &|
|
||||
skaffold completion zsh >| "$ZSH_CACHE_DIR/completions/_skaffold" &|
|
||||
|
||||
@@ -101,18 +101,10 @@ if zstyle -t :omz:plugins:ssh-agent agent-forwarding \
|
||||
&& [[ -n "$SSH_AUTH_SOCK" ]]; then
|
||||
if [[ ! -L "$SSH_AUTH_SOCK" ]]; then
|
||||
if [[ -n "$TERMUX_VERSION" ]]; then
|
||||
_omz_ssh_agent_link="$PREFIX"/tmp/ssh-agent-$USERNAME-screen
|
||||
ln -sf "$SSH_AUTH_SOCK" "$PREFIX"/tmp/ssh-agent-$USERNAME-screen
|
||||
else
|
||||
_omz_ssh_agent_link=/tmp/ssh-agent-$USERNAME-screen
|
||||
ln -sf "$SSH_AUTH_SOCK" /tmp/ssh-agent-$USERNAME-screen
|
||||
fi
|
||||
# `ln -sf` unlinks the old symlink and then creates the new one: two
|
||||
# syscalls, no atomic swap. Shells starting concurrently (a tmux window
|
||||
# opening several panes at once) interleave those steps and all but one
|
||||
# fail with "ln: ...: File exists". Stage the link under a PID-unique
|
||||
# name and move it into place, since rename(2) is atomic.
|
||||
command ln -sf "$SSH_AUTH_SOCK" "$_omz_ssh_agent_link.$$" \
|
||||
&& command mv -f "$_omz_ssh_agent_link.$$" "$_omz_ssh_agent_link"
|
||||
unset _omz_ssh_agent_link
|
||||
fi
|
||||
else
|
||||
_start_agent
|
||||
|
||||
@@ -10,8 +10,4 @@ if [[ ! -f "$ZSH_CACHE_DIR/completions/_stripe" ]]; then
|
||||
_comps[stripe]=_stripe
|
||||
fi
|
||||
|
||||
zmodload -F zsh/files b:zf_mv
|
||||
() {
|
||||
local TMPPREFIX="$ZSH_CACHE_DIR/completions/_stripe"
|
||||
zf_mv -f -- =( stripe completion --shell zsh --write-to-stdout ) "$TMPPREFIX"
|
||||
} &|
|
||||
stripe completion --shell zsh --write-to-stdout >| "$ZSH_CACHE_DIR/completions/_stripe" &|
|
||||
|
||||
@@ -19,7 +19,6 @@
|
||||
ssm_run_sudo() {sudo $_sublime_merge_path "$@" >/dev/null 2>&1}
|
||||
alias ssm=ssm_run_sudo
|
||||
alias sm=sm_run
|
||||
alias smerge="'$_sublime_merge_path'"
|
||||
break
|
||||
fi
|
||||
done
|
||||
@@ -34,7 +33,6 @@
|
||||
if [[ -a $_sublime_merge_path ]]; then
|
||||
subm () { "$_sublime_merge_path" "$@" }
|
||||
alias sm=subm
|
||||
alias smerge="'$_sublime_merge_path'"
|
||||
break
|
||||
fi
|
||||
done
|
||||
@@ -47,7 +45,6 @@
|
||||
if [[ -a $_sublime_merge_path ]]; then
|
||||
subm () { "$_sublime_merge_path" "$@" }
|
||||
alias sm=subm
|
||||
alias smerge="'$_sublime_merge_path'"
|
||||
break
|
||||
fi
|
||||
done
|
||||
|
||||
@@ -138,7 +138,7 @@ function consume100() {
|
||||
|
||||
# Website traffic statistics (G)
|
||||
function webtraffic() {
|
||||
awk '{sum+=$10} END {print sum/1024/1024/1024}' "$(retlog)"
|
||||
awk "{sum+=$10} END {print sum/1024/1024/1024}" "$(retlog)"
|
||||
}
|
||||
|
||||
# Statistical connections 404
|
||||
|
||||
@@ -22,8 +22,4 @@ if (( $+aliases[tailscale] )); then
|
||||
_comps[${aliases[tailscale]:t}]=_tailscale
|
||||
fi
|
||||
|
||||
zmodload -F zsh/files b:zf_mv
|
||||
() {
|
||||
local TMPPREFIX="$ZSH_CACHE_DIR/completions/_tailscale"
|
||||
zf_mv -f -- =( tailscale completion zsh ) "$TMPPREFIX"
|
||||
} &|
|
||||
tailscale completion zsh >| "$ZSH_CACHE_DIR/completions/_tailscale" &|
|
||||
|
||||
@@ -11,8 +11,4 @@ if [[ ! -f "$ZSH_CACHE_DIR/completions/_task" ]]; then
|
||||
fi
|
||||
|
||||
# Generate and load task completion
|
||||
zmodload -F zsh/files b:zf_mv
|
||||
() {
|
||||
local TMPPREFIX="$ZSH_CACHE_DIR/completions/_task"
|
||||
zf_mv -f -- =( task --completion zsh ) "$TMPPREFIX"
|
||||
} &|
|
||||
task --completion zsh >! "$ZSH_CACHE_DIR/completions/_task" &|
|
||||
@@ -11,8 +11,4 @@ if [[ ! -f "$ZSH_CACHE_DIR/completions/_timoni" ]]; then
|
||||
_comps[timoni]=_timoni
|
||||
fi
|
||||
|
||||
zmodload -F zsh/files b:zf_mv
|
||||
() {
|
||||
local TMPPREFIX="$ZSH_CACHE_DIR/completions/_timoni"
|
||||
zf_mv -f -- =( timoni completion zsh ) "$TMPPREFIX"
|
||||
} &|
|
||||
timoni completion zsh >| "$ZSH_CACHE_DIR/completions/_timoni" &|
|
||||
|
||||
@@ -1,10 +0,0 @@
|
||||
# uv Environment Plugin
|
||||
|
||||
This plugin automatically activates the uv virtual environment when you cd into a project directory, and deactivates it when you cd out.
|
||||
Note: Script looks for pyproject.toml and uv.lock files to determine if it's a uv project
|
||||
|
||||
To use it, add `uv-env` to the plugins array in your zshrc file:
|
||||
|
||||
```zsh
|
||||
plugins=(... uv-env)
|
||||
```
|
||||
@@ -1,26 +0,0 @@
|
||||
_toggleUvShell() {
|
||||
local in_uv_dir=0
|
||||
if [[ -f "$PWD/pyproject.toml" && -f "$PWD/uv.lock" ]]; then
|
||||
in_uv_dir=1
|
||||
fi
|
||||
|
||||
if [[ $uv_active -eq 1 ]] && { [[ $in_uv_dir -eq 0 ]] || [[ "$PWD" != "$uv_dir" && "$PWD" != "$uv_dir"/* ]]; }; then
|
||||
typeset -g uv_active=0
|
||||
unset uv_dir
|
||||
(( $+functions[deactivate] )) && deactivate
|
||||
fi
|
||||
|
||||
if [[ $in_uv_dir -eq 1 ]] && [[ $uv_active -ne 1 ]]; then
|
||||
local venv_dir="${UV_PROJECT_ENVIRONMENT:-$PWD/.venv}"
|
||||
[[ "$venv_dir" != /* ]] && venv_dir="$PWD/$venv_dir"
|
||||
|
||||
if [[ -f "${venv_dir}/bin/activate" ]]; then
|
||||
typeset -g uv_active=1
|
||||
typeset -g uv_dir="$PWD"
|
||||
source "${venv_dir}/bin/activate"
|
||||
fi
|
||||
fi
|
||||
}
|
||||
autoload -Uz add-zsh-hook
|
||||
add-zsh-hook chpwd _toggleUvShell
|
||||
_toggleUvShell
|
||||
@@ -43,12 +43,5 @@ fi
|
||||
|
||||
# uv and uvx are installed together (uvx is an alias to `uv tool run`)
|
||||
# Overwrites the file each time as completions might change with uv versions.
|
||||
zmodload -F zsh/files b:zf_mv
|
||||
() {
|
||||
local TMPPREFIX="$ZSH_CACHE_DIR/completions/_uv"
|
||||
zf_mv -f -- =( uv generate-shell-completion zsh ) "$TMPPREFIX"
|
||||
} &|
|
||||
() {
|
||||
local TMPPREFIX="$ZSH_CACHE_DIR/completions/_uvx"
|
||||
zf_mv -f -- =( uvx --generate-shell-completion zsh ) "$TMPPREFIX"
|
||||
} &|
|
||||
uv generate-shell-completion zsh >| "$ZSH_CACHE_DIR/completions/_uv" &|
|
||||
uvx --generate-shell-completion zsh >| "$ZSH_CACHE_DIR/completions/_uvx" &|
|
||||
|
||||
@@ -47,7 +47,6 @@ _box_arguments=(
|
||||
'help:COMMAND List subcommands'
|
||||
'list:Lists all installed boxes'
|
||||
'outdated:Checks if a box has newer version'
|
||||
'prune:Removes old versions of installed boxes'
|
||||
'remove:NAME Removes a box from the system'
|
||||
'repackage:NAME PROVIDER VERSION Repackages an installed box into a `.box` file'
|
||||
'update:Updates box to a newer version, if available'
|
||||
|
||||
@@ -11,8 +11,4 @@ if [[ ! -f "$ZSH_CACHE_DIR/completions/_volta" ]]; then
|
||||
_comps[volta]=_volta
|
||||
fi
|
||||
|
||||
zmodload -F zsh/files b:zf_mv
|
||||
() {
|
||||
local TMPPREFIX="$ZSH_CACHE_DIR/completions/_volta"
|
||||
zf_mv -f -- =( volta completions zsh ) "$TMPPREFIX"
|
||||
} &|
|
||||
volta completions zsh >| "$ZSH_CACHE_DIR/completions/_volta" &|
|
||||
|
||||
+17
-82
@@ -2,26 +2,20 @@
|
||||
|
||||
[](https://opensource.org/licenses/MIT)
|
||||

|
||||

|
||||

|
||||
[](https://github.com/agkozak/zsh-z/stargazers)
|
||||
|
||||

|
||||
|
||||
Zsh-z is a command-line tool that allows you to jump quickly to directories that you have visited frequently or recently -- but most often a combination of the two (a concept known as ["frecency"](https://en.wikipedia.org/wiki/Frecency)). It works by keeping track of when you go to directories and how much time you spend in them. Based on this data, it predicts where you want to go when you type a partial string. For example, `z src` might take you to `~/src/zsh`. `z zsh` might also get you there, and `z c/z` might prove to be even more specific -- it all depends on your habits and how long you have been using Zsh-z to build up a database. After using Zsh-z for a little while, you will get to where you want to be by typing considerably less than you would need to if you were using `cd`.
|
||||
|
||||
Zsh-z is a native Zsh port of [`rupa/z`](https://github.com/rupa/z), a tool written for `bash` and Zsh that uses embedded `awk` scripts to do the heavy lifting. `rupa/z` was my most used command-line tool for a couple of years. I decided to translate it, `awk` parts and all, into pure Zsh script, to see if by eliminating calls to external tools (`awk`, `sort`, `date`, `sed`, `mv`, `rm`, and `chown`) and reducing forking through subshells I could make it faster. The performance increase is impressive, particularly on systems where forking is slow, such as Cygwin, MSYS2, and WSL.
|
||||
Zsh-z is a native Zsh port of [`rupa/z`](https://github.com/rupa/z), a tool written for `bash` and Zsh that uses embedded `awk` scripts to do the heavy lifting. `rupa/z` was my most used command-line tool for a couple of years. I decided to translate it, `awk` parts and all, into pure Zsh script, to see if by eliminating calls to external tools (`awk`, `sort`, `date`, `sed`, `mv`, `rm`, and `chown`) and reducing forking through subshells I could make it faster. The performance increase is impressive, particularly on systems where forking is slow, such as Cygwin, MSYS2, and WSL. I have found that in those environments, switching directories using Zsh-z can be over 100% faster than it is using `rupa/z`.
|
||||
|
||||
There is also a significant stability improvement. Race conditions have always been a problem with `rupa/z`, and users of that utility occasionally lose their `~/.z` databases. By having Zsh-z only use Zsh (`rupa/z` uses a hybrid shell code standard that works on `bash` as well), I have been able to implement a `zsh/system`-based file-locking mechanism. It is now nearly impossible to crash the database.
|
||||
There is also a significant stability improvement. Race conditions have always been a problem with `rupa/z`, and users of that utility occasionally lose their `~/.z` databases. By having Zsh-z only use Zsh (`rupa/z` uses a hybrid shell code standard that works on `bash` as well), I have been able to implement a `zsh/system`-based file-locking mechanism similar to [the one @mafredri once proposed for `rupa/z`](https://github.com/rupa/z/pull/199). It is now nearly impossible to crash the database.
|
||||
|
||||
There are other, smaller improvements which I document below in [Other Improvements to the Original Functionality of `rupa/z`](#other-improvements-to-the-original-functionality-of-rupaz). For instance, tab completions are now sorted by frecency by default rather than alphabetically (the latter behavior can be restored if you like it -- [see below](#settings)).
|
||||
There are other, smaller improvements which I document below in [Improvements and Fixes](#improvements-and-fixes). For instance, tab completions are now sorted by frecency by default rather than alphabetically (the latter behavior can be restored if you like it -- [see below](#settings)).
|
||||
|
||||
Zsh-z is a drop-in replacement for `rupa/z` and will, by default, use the same database (`~/.z`, or whatever database file you specify), so you can go on using `rupa/z` when you launch `bash`.
|
||||
|
||||
> ### Zsh-z v2.0
|
||||
>
|
||||
> **v2.0 is the most significant release in the project's history.** It is faster than ever at adding, searching, and listing on modern Zsh; it never makes your prompt wait on database writes -- on any platform; it hardens those writes against corruption and against prying eyes; and it makes tab completion "just work" even under `setopt COMPLETE_ALIASES`. See [**v2.0**](#v20) in the News below for the full rundown, and [Performance](#performance) for the benchmarks.
|
||||
|
||||
## Table of Contents
|
||||
- [News](#news)
|
||||
- [Installation](#installation)
|
||||
@@ -29,45 +23,16 @@ Zsh-z is a drop-in replacement for `rupa/z` and will, by default, use the same d
|
||||
- [Settings](#settings)
|
||||
- [Case Sensitivity](#case-sensitivity)
|
||||
- [`ZSHZ_UNCOMMON`](#zshz_uncommon)
|
||||
- [`ZSHZ_OWNER`](#zshz_owner)
|
||||
- [Making `--add` work for you](#making---add-work-for-you)
|
||||
- [Performance](#performance)
|
||||
- [Other Improvements to the Original Functionality of `rupa/z`](#other-improvements-to-the-original-functionality-of-rupaz)
|
||||
- [Other Improvements to the Original Functionality of `rupa/z`](#other-improvements-to-the-original-functionality-of-rupa-z)
|
||||
- [Migrating from Other Tools](#migrating-from-other-tools)
|
||||
- [`COMPLETE_ALIASES`](#complete_aliases)
|
||||
|
||||
## News
|
||||
|
||||
### v2.0 (August 14, 2026)
|
||||
|
||||
Version **2.0** is a major step forward, and these are the changes most worth knowing about:
|
||||
|
||||
- **Zsh-z is even faster than before.** Version 2.0 builds on Zsh-z's past successes in optimizing adding to the datafile -- something it does at virtually every prompt -- by streamlining searching and listing, as well. See [Performance](#performance) for the numbers.
|
||||
- **Database writes never block your prompt** -- on any platform. The per-prompt `--add` has long run in the background on most systems, but Cygwin and MSYS2 did the write in the foreground, because backgrounding there cost a wrapper subshell plus a job. `--add` now runs as a single disowned job (`&!`) everywhere: one fork, no wrapper subshell, no job-control noise. On Cygwin and MSYS2 that turns a foreground write whose cost grows with your datafile (~30 ms at 300 entries, ~300 ms at 1,000) into a flat ~10-12 ms fork. Elsewhere it halves the forks per prompt.
|
||||
- **Safer, crash-resistant concurrent writes.** Writes are now guarded by a dedicated, stable lockfile using `zsh/system` file locking, with a bounded wait for lock acquisition (the new [`ZSHZ_LOCK_TIMEOUT`](#settings), default `1` second). Write errors are handled gracefully, and locks are always released even if a write is interrupted. On Cygwin and MSYS2 a write is also retried briefly if Windows refuses it: a virus scanner or the search indexer that opens the database in the instant between its being written and its being moved into place makes the move fail, which used to lose that one directory silently. Zsh-z now retries the move briefly.
|
||||
- **Your database file now has `600` permissions** -- readable and writable only by you -- so that other users on a shared system cannot read your directory history ([#92](https://github.com/agkozak/zsh-z/issues/92)). On Zsh 5+ this uses the in-process `zf_chmod` builtin; on Zsh 4.3.11 it uses a `umask`-in-a-subshell technique that avoids the fork-and-exec of an external `chmod`.
|
||||
- **`COMPLETE_ALIASES` works automatically in normal setups.** Tab completion no longer breaks when you have `setopt COMPLETE_ALIASES` enabled. Zsh-z registers the alias automatically on the first Tab press, so the manual `compdef` line that earlier versions required is no longer necessary. [See below](#complete_aliases).
|
||||
- **Fixed a `can't clobber parameter tmpfd` error on some Zsh builds.** On certain Zsh builds, every database write could fail with `can't clobber parameter tmpfd containing file descriptor 0`, leaving an error at each new prompt. The file descriptor used for the temporary database file is now held in an unset scalar rather than one seeded with `0`, so the write never trips Zsh's file-descriptor-clobber guard ([#81](https://github.com/agkozak/zsh-z/issues/81)).
|
||||
- **A misconfigured database file no longer closes your shell -- or nags you at every prompt.** When `ZSHZ_DATA` points at a directory, or names a file without a directory, Zsh-z now reports the problem and returns instead of calling `exit`. The per-prompt `--add` stays quiet about it, so you are told once, when you actually run `z`, rather than at every prompt ([#103](https://github.com/agkozak/zsh-z/issues/103); props @ahjota).
|
||||
- **`z -x` can now remove the entry for a directory that no longer exists -- and can no longer crash Zsh 4.3.11.** The removal target used to have to exist on disk, so a database entry whose directory had been deleted -- exactly the entry you most want gone -- could not be removed. `z -x /deleted/dir` (and `z -xR`) now canonicalizes the argument without requiring it to exist, resolving symlinks in as much of the path as is still present. The same change fixes a crash on Zsh 4.3.11, where an upstream bug makes `${x:A}` segfault when the top-level component of the path is missing: `z -x /gone/sub` -- or a `ZSHZ_DATA` pointing into a missing top-level directory -- could kill the shell there.
|
||||
- **More robust startup and operation.** A version check on an unsupported Zsh no longer risks exiting your interactive shell.
|
||||
|
||||
#### Smaller changes you may notice
|
||||
|
||||
None of these should need any action from you, but they are the things a v1 user is most likely to spot:
|
||||
|
||||
- **`-r` and `-t` can no longer be combined.** They name mutually exclusive sort orders -- rank versus recency -- so `z -rt foo` was always contradictory, and `-t` silently took precedence. It is now rejected with an error message instead of silently picking one.
|
||||
- **A lockfile appears next to your database.** Writes are serialized through `~/.z.lock` (or `$ZSHZ_DATA` plus `.lock`). It is created `600`, it stays empty, and it is deliberately never deleted -- removing a lockfile that another shell has already opened would reintroduce the very race it exists to prevent. Where `zsh/system` is missing and `zsystem flock` is therefore unavailable -- MobaXterm's cut-down Cygwin is the case in practice -- you will see a short-lived `~/.z.lock.d` **directory** instead, which is created and removed for each write. See [`ZSHZ_LOCK_TIMEOUT`](#settings) for how that fallback behaves.
|
||||
- **An existing database gets tightened to `600` on the next write.** If your `~/.z` predates this release and is `644`, the first write will re-mode it. This is the [#92](https://github.com/agkozak/zsh-z/issues/92) fix applied to databases you already have, not just newly created ones. Setting the mode is treated as part of the write rather than a courtesy afterwards: if it cannot be done, the write is abandoned and reports failure instead of publishing a database that anyone on the machine could read.
|
||||
|
||||
The dated entries below remain the historical record of changes leading up to v2.0.
|
||||
|
||||
<details>
|
||||
<summary>Here are the older features and updates.</summary>
|
||||
<summary>Here are the latest features and updates.</summary>
|
||||
|
||||
- May 6, 2026
|
||||
+ Zsh-z will now handle paths with dollar signs (`$`) in them.
|
||||
+ Workaround for Zsh emulating `sh`/`bash`/`ksh`.
|
||||
- May 1, 2026
|
||||
+ Various tab completion bugs resolved.
|
||||
- April 27, 2026
|
||||
@@ -125,7 +90,7 @@ The dated entries below remain the historical record of changes leading up to v2
|
||||
- February 15, 2021
|
||||
+ Ranks are displayed the way `rupa/z` now displays them, i.e. as large integers. This should help Zsh-z to integrate with other tools.
|
||||
- January 31, 2021
|
||||
+ Zsh-z is now efficient enough that, on MSYS2 and Cygwin, it is faster to run it in the foreground than it is to fork a subshell for it. (Behavior superseded in v2.0.)
|
||||
+ Zsh-z is now efficient enough that, on MSYS2 and Cygwin, it is faster to run it in the foreground than it is to fork a subshell for it.
|
||||
+ `_zshz_precmd` simply returns if `PWD` is `HOME` or in `ZSHZ_EXCLUDE_DIRS`, rather than waiting for `zshz` to do that.
|
||||
- January 17, 2021
|
||||
+ Made sure that the `PUSHD_IGNORE_DUPS` option is respected.
|
||||
@@ -156,11 +121,11 @@ This plugin can be installed simply by putting the various files in a directory
|
||||
|
||||
source /path/to/zsh-z.plugin.zsh
|
||||
|
||||
Tab completion requires `compinit`. `_zshz` *must* also be in the same directory as `zsh-z.plugin.zsh`. The frameworks handle both of these requirements, but if you are not using a framework, put
|
||||
For tab completion to work, `_zshz` *must* be in the same directory as `zsh-z.plugin.zsh`, and you will want to have loaded `compinit`. The frameworks handle this themselves. If you are not using a framework, put
|
||||
|
||||
autoload -U compinit; compinit
|
||||
|
||||
in your `.zshrc` somewhere below where you source `zsh-z.plugin.zsh` -- the plugin adds its directory to `fpath` at source time, and `compinit` needs to see it there in order to find `_zshz`.
|
||||
in your `.zshrc` somewhere below where you source `zsh-z.plugin.zsh`.
|
||||
|
||||
If you add
|
||||
|
||||
@@ -230,7 +195,7 @@ Add a backslash to the end of the last line and add `'zsh-z'` to the list, e.g.,
|
||||
Then relaunch `zsh`.
|
||||
|
||||
### For [zcomet](https://github.com/agkozak/zcomet) users
|
||||
|
||||
|
||||
Simply add
|
||||
|
||||
zcomet load agkozak/zsh-z
|
||||
@@ -270,7 +235,7 @@ Add the line
|
||||
|
||||
to your `.zshrc`.
|
||||
|
||||
Zsh-z supports `zinit`'s `unload` feature; just run `zinit unload agkozak/zsh-z` to restore the shell to its state before Zsh-z was loaded. It gives back only what it took: the `fpath` entry is removed only if Zsh-z was the one that added it, so a directory your plugin manager put there is left alone, and the Tab-completion mapping is dropped only while it still points at Zsh-z's own completer.
|
||||
Zsh-z supports `zinit`'s `unload` feature; just run `zinit unload agkozak/zsh-z` to restore the shell to its state before Zsh-z was loaded.
|
||||
|
||||
### For [Znap](https://github.com/marlonrichert/zsh-snap) users
|
||||
|
||||
@@ -309,7 +274,6 @@ to install Zsh-z.
|
||||
|
||||
Zsh-z has environment variables (they all begin with `ZSHZ_`) that change its behavior if you set them. You can also keep your old ones if you have been using `rupa/z` (whose environment variables begin with `_Z_`).
|
||||
|
||||
* `ZSHZ_CASE` can be `ignore`, for case-insensitive matching, or `smart`, for Vim-like `smartcase` matching; [see below](#case-sensitivity) (default: empty, i.e., a case-sensitive match is tried first, then a case-insensitive one)
|
||||
* `ZSHZ_CMD` changes the command name (default: `z`)
|
||||
* `ZSHZ_CD` specifies the default directory-changing command (default: `builtin cd`)
|
||||
* `ZSHZ_COMPLETION` can be `'frecent'` (default) or `'legacy'`, depending on whether you want your completion results sorted according to frecency or simply sorted alphabetically
|
||||
@@ -317,10 +281,9 @@ Zsh-z has environment variables (they all begin with `ZSHZ_`) that change its be
|
||||
* `ZSHZ_ECHO` displays the new path name when changing directories (default: `0`)
|
||||
* `ZSHZ_EXCLUDE_DIRS` is an array of directories to keep out of the database (default: empty)
|
||||
* `ZSHZ_KEEP_DIRS` is an array of directories that should not be removed from the database, even if they are not currently available (useful when a drive is not always mounted) (default: empty)
|
||||
* `ZSHZ_LOCK_TIMEOUT` is the number of seconds to wait for the database lock before giving up on a write (default: `1`). Where `zsh/system` is unavailable and `zsystem flock` cannot be used -- MobaXterm's cut-down Cygwin, for instance -- Zsh-z serializes writes with an atomic `mkdir` on `~/.z.lock.d` instead, and this setting bounds the wait the same way. That fallback has no equivalent of the kernel releasing a lock when its holder dies, so a lock directory older than 30 seconds is treated as abandoned and cleared; a write takes milliseconds, so nothing legitimate is ever that old. A write that times out is dropped silently -- the automatic `precmd` add is best-effort -- so if the database seems to stop updating, the lock is probably contended: run `z --add .` by hand and check `$?`. A `2` is a lock-acquisition timeout, which confirms contention -- look for a stale process holding `~/.z.lock` (or a leftover `~/.z.lock.d` directory on the fallback path), or raise this setting. A `1` is something else entirely, usually a permissions or ownership problem, such as a root-owned `~/.z` or `~/.z.lock` left behind by an earlier `sudo -s` session.
|
||||
* `ZSHZ_MAX_SCORE` is the maximum combined score the database entries can have before they begin to age and potentially drop out of the database (default: 9000)
|
||||
* `ZSHZ_NO_RESOLVE_SYMLINKS` prevents symlink resolution (default: `0`)
|
||||
* `ZSHZ_OWNER` is the username the database belongs to; set it to your own login name to keep `z` working in a root shell, such as under `sudo -E -s`; [see below](#zshz_owner) (default: empty)
|
||||
* `ZSHZ_OWNER` allows usage when in `sudo -s` mode (default: empty)
|
||||
* `ZSHZ_TILDE` displays the name of the `HOME` directory as a `~` (default: `0`)
|
||||
* `ZSHZ_TRAILING_SLASH` makes it so that a search pattern ending in `/` can match the final element in a path; e.g., `z foo/` can match `/path/to/foo` (default: `0`)
|
||||
* `ZSHZ_UNCOMMON` changes the logic used to calculate the directory jumped to; [see below](#zshz_uncommon) (default: `0`)
|
||||
@@ -356,12 +319,6 @@ then there is no common prefix. In this case, `z code` will simply send you to t
|
||||
|
||||
You may enable an alternate, experimental behavior by setting `ZSHZ_UNCOMMON=1`. If you do that, Zsh-z will not jump to a common prefix, even if one exists. Instead, it chooses the highest-ranking match -- but it drops any subdirectories that do not include the search term. So if you type `z bat` and `/home/me/code/bat` is the best match, that is exactly where you will end up. If, however, you had typed `z code` and the best match was also `/home/me/code/bat`, you would have ended up in `/home/me/code` (because `code` was what you had searched for). This feature is still in development, and feedback is welcome.
|
||||
|
||||
## `ZSHZ_OWNER`
|
||||
|
||||
If you are using `root` privileges while keeping your personal home directory as `HOME` (as is the case with `sudo -E -s`), conflicts with file ownership arise. You can resolve them by using `ZSHZ_OWNER`. If you set this variable to your username, Zsh-z will be able to use your personal datafile, restoring its proper ownership with every write.
|
||||
|
||||
Setting `ZSHZ_OWNER` makes one thing stricter, because a privileged shell is then writing to a path that an unprivileged user controls: Zsh-z follows a symlink on the way to the datafile -- the file itself, or any parent directory -- only if `root` owns the link, and reports an error instead of writing otherwise. Symlinked system directories, such as `/home` → `/usr/home` on the BSDs or `/var` → `/private/var` on macOS, belong to root and still resolve. With `ZSHZ_OWNER` unset none of this applies: a symlinked `~/.z` is followed exactly as before, so pointing it at synced storage keeps working.
|
||||
|
||||
## Making `--add` Work for You
|
||||
|
||||
Zsh-z internally uses the `--add` option to add paths to its database. @zachriggle pointed out to me that users might want to use `--add` themselves, so I have altered it a little to make it more user-friendly.
|
||||
@@ -374,33 +331,9 @@ A good example might involve a directory tree that has Git repositories within i
|
||||
|
||||
(As a Zsh user, I tend to use `**` instead of `find`, but it is good to see how deep your directory trees go before doing that.)
|
||||
|
||||
## Performance
|
||||
|
||||
One of the goals of the rewrite that culminated in v2.0 was to make Zsh-z simultaneously more stable and faster. On modern Zsh, Zsh-z outpaces `rupa/z`'s `z.sh` at adding, searching, and listing. Representative figures (N = 200 database entries, medians of seven interleaved runs on a Core i7-12700 desktop under WSL2):
|
||||
|
||||
**Modern Zsh (5.9) -- Zsh-z vs. `rupa/z`:**
|
||||
|
||||
| Operation | `rupa/z` (`z.sh`) | Zsh-z | Winner |
|
||||
| --------- | ----------------- | ----------- | ----------------- |
|
||||
| `add` | 6.25 ms/op | 1.99 ms/op | **Zsh-z** ~3.14x |
|
||||
| `search` | 6.51 ms/op | 3.62 ms/op | **Zsh-z** ~1.80x |
|
||||
| `list` | 8.93 ms/op | 4.36 ms/op | **Zsh-z** ~2.05x |
|
||||
|
||||
**Zsh 4.3.11 (the oldest supported release) -- Zsh-z vs. `rupa/z`:**
|
||||
|
||||
| Operation | `rupa/z` (`z.sh`) | Zsh-z | Winner |
|
||||
| --------- | ----------------- | ----------- | ----------------- |
|
||||
| `add` | 5.00 ms/op | 2.92 ms/op | **Zsh-z** ~1.71x |
|
||||
| `search` | 4.93 ms/op | 4.47 ms/op | **Zsh-z** ~1.10x |
|
||||
| `list` | 7.92 ms/op | 6.08 ms/op | **Zsh-z** ~1.30x |
|
||||
|
||||
Removal is absent from these tables: in `rupa/z`, the per-prompt hook re-adds the current directory right after `z -x` removes it, so the two implementations' `-x` are not doing comparable work.
|
||||
|
||||
Relative to the previous generation of Zsh-z, the v2.0 read path is dramatically faster -- on modern Zsh, listing the whole database is about 2.4x faster and searching about 1.6x faster.
|
||||
|
||||
## Other Improvements to the Original Functionality of `rupa/z`
|
||||
|
||||
* `z -x` works: a directory you remove stays removed.
|
||||
* `z -x` works, with the help of `chpwd_functions`.
|
||||
* Zsh-z is compatible with Solaris.
|
||||
* Zsh-z uses the "new" `zshcompsys` completion system instead of the old `compctl` one.
|
||||
* No error message is displayed when the database file has not yet been created.
|
||||
@@ -422,10 +355,12 @@ If you are coming to Zsh-z (or even to the original `rupa/z`, for that matter) f
|
||||
|
||||
## `COMPLETE_ALIASES`
|
||||
|
||||
`z`, or any alternative you set up using `$ZSHZ_CMD` or `$_Z_CMD`, is an alias. `setopt COMPLETE_ALIASES` divorces the tab completion for aliases from the underlying commands they invoke, which historically broke Zsh-z's tab completion. Zsh-z now handles this automatically: the first Tab press registers the alias name with `_zshz` so completion works under `COMPLETE_ALIASES` without any extra setup.
|
||||
`z`, or any alternative you set up using `$ZSHZ_CMD` or `$_Z_CMD`, is an alias. `setopt COMPLETE_ALIASES` divorces the tab completion for aliases from the underlying commands they invoke, so if you enable `COMPLETE_ALIASES`, tab completion for Zsh-z will be broken. You can get it working again, however, by adding under
|
||||
|
||||
That registration happens inside Zsh-z's own Tab widget. If a plugin loaded after Zsh-z replaces the Tab binding without invoking the previous widget, Zsh-z's widget never runs and the registration does not happen. Under `COMPLETE_ALIASES`, you would then have no completion for `z`. Once `compinit` has run, adding
|
||||
setopt COMPLETE_ALIASES
|
||||
|
||||
the line
|
||||
|
||||
compdef _zshz ${ZSHZ_CMD:-${_Z_CMD:-z}}
|
||||
|
||||
below `setopt COMPLETE_ALIASES` in your `.zshrc` fixes that, and it is harmless if the automatic registration has already run.
|
||||
That will re-bind `z` or the command of your choice to the underlying Zsh-z function.
|
||||
|
||||
+6
-2
@@ -1,6 +1,6 @@
|
||||
#compdef zshz ${ZSHZ_CMD:-${_Z_CMD:-z}}
|
||||
#
|
||||
# Zsh-z - jump around with Zsh - A native Zsh version of rupa/z without awk, sort,
|
||||
# Zsh-z - jump around with Zsh - A native Zsh version of z without awk, sort,
|
||||
# date, or sed
|
||||
#
|
||||
# https://github.com/agkozak/zsh-z
|
||||
@@ -24,7 +24,11 @@
|
||||
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
# SOFTWARE.
|
||||
################################################################################
|
||||
#
|
||||
# z (https://github.com/rupa/z) is copyright (c) 2009 rupa deadwyler and
|
||||
# licensed under the WTFPL license, Version 2.a
|
||||
#
|
||||
# shellcheck shell=ksh
|
||||
|
||||
############################################################
|
||||
# Zsh-z COMPLETIONS
|
||||
|
||||
+288
-1070
File diff suppressed because it is too large
Load Diff
@@ -1,7 +0,0 @@
|
||||
|
||||
## Cache
|
||||
|
||||
This plugin caches the completion script and automatically updates it when the
|
||||
plugin is loaded, which is usually when you start a new terminal emulator.
|
||||
|
||||
The cache is stored at `$ZSH_CACHE_DIR/completions/_%command%`.
|
||||
@@ -1,11 +0,0 @@
|
||||
# %name% plugin
|
||||
|
||||
%description%
|
||||
|
||||
To use it, add `%name%` to the plugins array in your zshrc file:
|
||||
|
||||
```zsh
|
||||
plugins=(... %name%)
|
||||
```
|
||||
|
||||
This plugin does not add any aliases.
|
||||
@@ -1,20 +0,0 @@
|
||||
# %name% plugin
|
||||
|
||||
%description%
|
||||
|
||||
To use it, add `%name%` to the plugins array in your zshrc file:
|
||||
|
||||
```zsh
|
||||
plugins=(... %name%)
|
||||
```
|
||||
|
||||
## Aliases
|
||||
|
||||
| Alias | Command | Description |
|
||||
| :----------- | ------------------ | :-------------------- |
|
||||
| `%command%s` | `%command% status` | Show %command% status |
|
||||
|
||||
## Requirements
|
||||
|
||||
This plugin requires [%command%](https://example.com) to be installed.
|
||||
%cache%
|
||||
@@ -1,22 +0,0 @@
|
||||
#
|
||||
# Completion
|
||||
#
|
||||
# %command% generates its own zsh completion, so we cache it instead of
|
||||
# maintaining a `_%command%` file by hand.
|
||||
#
|
||||
# On the first shell after installing this plugin the cache file doesn't exist
|
||||
# yet, so compinit hasn't bound it. Do that manually here.
|
||||
if [[ ! -f "$ZSH_CACHE_DIR/completions/_%command%" ]]; then
|
||||
typeset -g -A _comps
|
||||
autoload -Uz _%command%
|
||||
_comps[%command%]=_%command%
|
||||
fi
|
||||
|
||||
# Regenerate the cache in the background so it never blocks shell startup.
|
||||
# TMPPREFIX puts the temp file next to the destination, which keeps the move
|
||||
# atomic.
|
||||
zmodload -F zsh/files b:zf_mv
|
||||
() {
|
||||
local TMPPREFIX="$ZSH_CACHE_DIR/completions/_%command%"
|
||||
zf_mv -f -- =( %compgen% ) "$TMPPREFIX"
|
||||
} &|
|
||||
@@ -1,6 +0,0 @@
|
||||
#
|
||||
# Completion
|
||||
#
|
||||
# Oh My Zsh adds this directory to $fpath, so a file named `_%command%` next to
|
||||
# this one is picked up automatically as the completion for %command%.
|
||||
#
|
||||
@@ -1,32 +0,0 @@
|
||||
#compdef %command%
|
||||
#
|
||||
# Completion for %command%.
|
||||
#
|
||||
# This is a starting point. Delete what you don't need. Two references:
|
||||
# https://zsh.sourceforge.io/Doc/Release/Completion-System.html
|
||||
# https://github.com/zsh-users/zsh/blob/master/Etc/completion-style-guide
|
||||
|
||||
local -a subcommands
|
||||
subcommands=(
|
||||
'status:Show the current status'
|
||||
'run:Run something'
|
||||
'help:Show help for a command'
|
||||
)
|
||||
|
||||
_arguments -C \
|
||||
'(-h --help)'{-h,--help}'[show help]' \
|
||||
'(-v --version)'{-v,--version}'[show the version]' \
|
||||
'1: :->subcommand' \
|
||||
'*:: :->args'
|
||||
|
||||
case $state in
|
||||
subcommand)
|
||||
_describe -t commands '%command% subcommand' subcommands
|
||||
;;
|
||||
args)
|
||||
case $words[1] in
|
||||
status) _arguments '--short[one-line output]' ;;
|
||||
run) _files ;;
|
||||
esac
|
||||
;;
|
||||
esac
|
||||
@@ -1,48 +0,0 @@
|
||||
# %name% plugin
|
||||
#
|
||||
# %description%
|
||||
#
|
||||
# This file is sourced by Oh My Zsh in every new shell, so keep it fast.
|
||||
# Avoid running external commands at the top level unless you really need to.
|
||||
#
|
||||
# Wrapping a command-line tool? Guard everything so people who don't have it
|
||||
# installed don't end up with broken aliases:
|
||||
#
|
||||
# if (( ! $+commands[sometool] )); then
|
||||
# return
|
||||
# fi
|
||||
|
||||
#
|
||||
# Aliases
|
||||
#
|
||||
# Document every alias in README.md. Short, obvious, and few beats many.
|
||||
#
|
||||
|
||||
# alias %name%='echo "hello from %name%"'
|
||||
|
||||
#
|
||||
# Functions
|
||||
#
|
||||
# Anything that needs arguments in the middle, or more than one command,
|
||||
# belongs here rather than in an alias.
|
||||
#
|
||||
|
||||
# function %name%_hello() {
|
||||
# echo "hello, ${1:-world}"
|
||||
# }
|
||||
|
||||
#
|
||||
# Completion
|
||||
#
|
||||
# Oh My Zsh adds this directory to $fpath, so a file named `_sometool` next to
|
||||
# this one is picked up automatically as the completion for `sometool`.
|
||||
#
|
||||
|
||||
#
|
||||
# Need the path to this plugin's own directory (for data files, a lib/ dir...)?
|
||||
# This is the standard way to get it, since $0 is not reliable on its own:
|
||||
# https://zdharma-continuum.github.io/Zsh-100-Commits-Club/Zsh-Plugin-Standard.html
|
||||
#
|
||||
# 0="${ZERO:-${${0:#$ZSH_ARGZERO}:-${(%):-%N}}}"
|
||||
# 0="${${(M)0:#/*}:-$PWD/$0}"
|
||||
# source "${0:A:h}/lib/helpers.zsh"
|
||||
@@ -1,43 +0,0 @@
|
||||
# %name% plugin
|
||||
#
|
||||
# %description%
|
||||
#
|
||||
# This file is sourced by Oh My Zsh in every new shell, so keep it fast.
|
||||
# Avoid running external commands at the top level unless you really need to.
|
||||
|
||||
# Only define anything if the tool is actually installed. Without this guard,
|
||||
# people who don't have %command% get aliases that fail with "command not found".
|
||||
if (( ! $+commands[%command%] )); then
|
||||
return
|
||||
fi
|
||||
|
||||
#
|
||||
# Aliases
|
||||
#
|
||||
# Document every alias in README.md. Short, obvious, and few beats many.
|
||||
# The one below is just an example: replace it with something %command% can do.
|
||||
#
|
||||
|
||||
alias %command%s='%command% status'
|
||||
|
||||
#
|
||||
# Functions
|
||||
#
|
||||
# Anything that needs arguments in the middle, or more than one command,
|
||||
# belongs here rather than in an alias.
|
||||
#
|
||||
|
||||
# function %name%_current() {
|
||||
# %command% status --short "$@"
|
||||
# }
|
||||
|
||||
%completion%
|
||||
|
||||
#
|
||||
# Need the path to this plugin's own directory (for data files, a lib/ dir...)?
|
||||
# This is the standard way to get it, since $0 is not reliable on its own:
|
||||
# https://zdharma-continuum.github.io/Zsh-100-Commits-Club/Zsh-Plugin-Standard.html
|
||||
#
|
||||
# 0="${ZERO:-${${0:#$ZSH_ARGZERO}:-${(%):-%N}}}"
|
||||
# 0="${${(M)0:#/*}:-$PWD/$0}"
|
||||
# source "${0:A:h}/lib/helpers.zsh"
|
||||
+2
-2
@@ -221,12 +221,12 @@ supports_hyperlinks() {
|
||||
|
||||
# If $TERM_PROGRAM is set, these terminals support hyperlinks
|
||||
case "$TERM_PROGRAM" in
|
||||
ghostty|Hyper|iTerm.app|terminology|vscode|WezTerm) return 0 ;;
|
||||
Hyper|iTerm.app|terminology|WezTerm|vscode) return 0 ;;
|
||||
esac
|
||||
|
||||
# These termcap entries support hyperlinks
|
||||
case "$TERM" in
|
||||
alacritty|alacritty-direct|xterm-ghostty|xterm-kitty) return 0 ;;
|
||||
xterm-kitty|alacritty|alacritty-direct) return 0 ;;
|
||||
esac
|
||||
|
||||
# xfce4-terminal supports hyperlinks
|
||||
|
||||
@@ -28,7 +28,7 @@ zstyle -s ':omz:update' mode update_mode || {
|
||||
if [[ "$update_mode" = disabled ]] \
|
||||
|| [[ ! -w "$ZSH" || ! -O "$ZSH" ]] \
|
||||
|| [[ ! -t 1 && ${POWERLEVEL9K_INSTANT_PROMPT:-off} == off ]] \
|
||||
|| ! command git --version >/dev/null 2>&1 \
|
||||
|| ! command git --version 2>&1 >/dev/null \
|
||||
|| (builtin cd -q "$ZSH"; ! command git rev-parse --is-inside-work-tree &>/dev/null); then
|
||||
unset update_mode
|
||||
return
|
||||
|
||||
+5
-27
@@ -49,31 +49,9 @@ USER=${USER:-$(id -u -n)}
|
||||
# $HOME is defined at the time of login, but it could be unset. If it is unset,
|
||||
# a tilde by itself (~) will not be expanded to the current user's home directory.
|
||||
# POSIX: https://pubs.opengroup.org/onlinepubs/009696899/basedefs/xbd_chap08.html#tag_08_03
|
||||
if [ -z "$HOME" ]; then
|
||||
HOME=$(getent passwd "$USER" 2>/dev/null | cut -d: -f6)
|
||||
|
||||
# macOS does not have getent; fall back to tilde expansion, but only if
|
||||
# $USER is a safe username. The eval below would otherwise expand any shell
|
||||
# metacharacters in $USER and allow command injection (CWE-78).
|
||||
case "$USER" in
|
||||
*[![:alnum:]_.-]*|'')
|
||||
;;
|
||||
*)
|
||||
resolved_home=$(eval echo ~"$USER")
|
||||
# Unknown users are not expanded and produce a literal "~username".
|
||||
[ "$resolved_home" = "~$USER" ] || HOME=$resolved_home
|
||||
;;
|
||||
esac
|
||||
|
||||
case "$HOME" in
|
||||
/*) ;;
|
||||
*)
|
||||
echo "Error: unable to determine the current user's home directory." >&2
|
||||
echo "Set HOME explicitly and rerun the installer." >&2
|
||||
exit 1
|
||||
;;
|
||||
esac
|
||||
fi
|
||||
HOME="${HOME:-$(getent passwd $USER 2>/dev/null | cut -d: -f6)}"
|
||||
# macOS does not have getent, but this works even if $HOME is unset
|
||||
HOME="${HOME:-$(eval echo ~"$USER")}"
|
||||
|
||||
|
||||
# Track if $ZSH was provided
|
||||
@@ -190,12 +168,12 @@ supports_hyperlinks() {
|
||||
|
||||
# If $TERM_PROGRAM is set, these terminals support hyperlinks
|
||||
case "$TERM_PROGRAM" in
|
||||
ghostty|Hyper|iTerm.app|terminology|vscode|WezTerm) return 0 ;;
|
||||
Hyper|iTerm.app|terminology|WezTerm|vscode) return 0 ;;
|
||||
esac
|
||||
|
||||
# These termcap entries support hyperlinks
|
||||
case "$TERM" in
|
||||
alacritty|alacritty-direct|xterm-ghostty|xterm-kitty) return 0 ;;
|
||||
xterm-kitty|alacritty|alacritty-direct) return 0 ;;
|
||||
esac
|
||||
|
||||
# xfce4-terminal supports hyperlinks
|
||||
|
||||
+2
-2
@@ -95,12 +95,12 @@ supports_hyperlinks() {
|
||||
|
||||
# If $TERM_PROGRAM is set, these terminals support hyperlinks
|
||||
case "$TERM_PROGRAM" in
|
||||
ghostty|Hyper|iTerm.app|terminology|vscode|WezTerm) return 0 ;;
|
||||
Hyper|iTerm.app|terminology|WezTerm|vscode) return 0 ;;
|
||||
esac
|
||||
|
||||
# These termcap entries support hyperlinks
|
||||
case "$TERM" in
|
||||
alacritty|alacritty-direct|xterm-ghostty|xterm-kitty) return 0 ;;
|
||||
xterm-kitty|alacritty|alacritty-direct) return 0 ;;
|
||||
esac
|
||||
|
||||
# xfce4-terminal supports hyperlinks
|
||||
|
||||
Reference in New Issue
Block a user