mirror of
https://github.com/robbyrussell/oh-my-zsh.git
synced 2026-09-28 05:56:07 +02:00
Compare commits
2
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
419fc5e9b5 | ||
|
|
338a1131c8 |
@@ -38,7 +38,6 @@ jobs:
|
|||||||
./lib/*.zsh \
|
./lib/*.zsh \
|
||||||
./plugins/*/*.plugin.zsh \
|
./plugins/*/*.plugin.zsh \
|
||||||
./plugins/*/_* \
|
./plugins/*/_* \
|
||||||
./templates/generators/*/*.zsh-template \
|
|
||||||
./themes/*.zsh-theme; do
|
./themes/*.zsh-theme; do
|
||||||
zsh -n "$file" || return 1
|
zsh -n "$file" || return 1
|
||||||
done
|
done
|
||||||
|
|||||||
@@ -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
|
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.
|
`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
|
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/`.
|
same name in the `custom/plugins/` directory and it will be loaded instead of the one in `plugins/`.
|
||||||
|
|
||||||
|
|||||||
+9
-382
@@ -24,7 +24,6 @@ function _omz {
|
|||||||
local -a cmds subcmds
|
local -a cmds subcmds
|
||||||
cmds=(
|
cmds=(
|
||||||
'changelog:Print the changelog'
|
'changelog:Print the changelog'
|
||||||
'generate:Run a generator, e.g. to create a custom plugin'
|
|
||||||
'help:Usage information'
|
'help:Usage information'
|
||||||
'plugin:Manage plugins'
|
'plugin:Manage plugins'
|
||||||
'pr:Manage Oh My Zsh Pull Requests'
|
'pr:Manage Oh My Zsh Pull Requests'
|
||||||
@@ -42,8 +41,6 @@ function _omz {
|
|||||||
changelog) local -a refs
|
changelog) local -a refs
|
||||||
refs=("${(@f)$(builtin cd -q "$ZSH"; command git for-each-ref --format="%(refname:short):%(subject)" refs/heads refs/tags)}")
|
refs=("${(@f)$(builtin cd -q "$ZSH"; command git for-each-ref --format="%(refname:short):%(subject)" refs/heads refs/tags)}")
|
||||||
_describe 'command' refs ;;
|
_describe 'command' refs ;;
|
||||||
generate) subcmds=('plugin:Create a custom plugin')
|
|
||||||
_describe 'generator' subcmds ;;
|
|
||||||
plugin) subcmds=(
|
plugin) subcmds=(
|
||||||
'disable:Disable plugin(s)'
|
'disable:Disable plugin(s)'
|
||||||
'enable:Enable plugin(s)'
|
'enable:Enable plugin(s)'
|
||||||
@@ -59,8 +56,6 @@ function _omz {
|
|||||||
esac
|
esac
|
||||||
elif (( CURRENT == 4 )); then
|
elif (( CURRENT == 4 )); then
|
||||||
case "${words[2]}::${words[3]}" in
|
case "${words[2]}::${words[3]}" in
|
||||||
generate::plugin)
|
|
||||||
_omz::generate::plugin::complete_options ;;
|
|
||||||
plugin::(disable|enable|load))
|
plugin::(disable|enable|load))
|
||||||
local -aU valid_plugins
|
local -aU valid_plugins
|
||||||
|
|
||||||
@@ -89,8 +84,6 @@ function _omz {
|
|||||||
esac
|
esac
|
||||||
elif (( CURRENT > 4 )); then
|
elif (( CURRENT > 4 )); then
|
||||||
case "${words[2]}::${words[3]}" in
|
case "${words[2]}::${words[3]}" in
|
||||||
generate::plugin)
|
|
||||||
_omz::generate::plugin::complete_options ;;
|
|
||||||
plugin::(enable|disable|load))
|
plugin::(enable|disable|load))
|
||||||
local -aU valid_plugins
|
local -aU valid_plugins
|
||||||
|
|
||||||
@@ -176,16 +169,15 @@ Usage: omz <command> [options]
|
|||||||
|
|
||||||
Available commands:
|
Available commands:
|
||||||
|
|
||||||
help Print this help message
|
help Print this help message
|
||||||
changelog Print the changelog
|
changelog Print the changelog
|
||||||
generate <generator> Run a generator, e.g. to create a custom plugin
|
plugin <command> Manage plugins
|
||||||
plugin <command> Manage plugins
|
pr <command> Manage Oh My Zsh Pull Requests
|
||||||
pr <command> Manage Oh My Zsh Pull Requests
|
reload Reload the current zsh session
|
||||||
reload Reload the current zsh session
|
shop Open the Oh My Zsh shop
|
||||||
shop Open the Oh My Zsh shop
|
theme <command> Manage themes
|
||||||
theme <command> Manage themes
|
update Update Oh My Zsh
|
||||||
update Update Oh My Zsh
|
version Show the version
|
||||||
version Show the version
|
|
||||||
|
|
||||||
EOF
|
EOF
|
||||||
}
|
}
|
||||||
@@ -210,371 +202,6 @@ EOF
|
|||||||
ZSH="$ZSH" command zsh -f "$ZSH/tools/changelog.sh" "$version" "${2:-}" "$format"
|
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 {
|
function _omz::plugin {
|
||||||
(( $# > 0 && $+functions[$0::$1] )) || {
|
(( $# > 0 && $+functions[$0::$1] )) || {
|
||||||
cat >&2 <<EOF
|
cat >&2 <<EOF
|
||||||
|
|||||||
@@ -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"
|
|
||||||
@@ -69,7 +69,7 @@ function asr() {
|
|||||||
local -a available_regions
|
local -a available_regions
|
||||||
available_regions=($(aws_regions))
|
available_regions=($(aws_regions))
|
||||||
if [[ -z "${available_regions[(r)$1]}" ]]; then
|
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
|
return 1
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
|||||||
@@ -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"
|
|
||||||
} &|
|
|
||||||
@@ -42,7 +42,6 @@ plugins=(... laravel)
|
|||||||
| `pamen` | `php artisan make:enum` |
|
| `pamen` | `php artisan make:enum` |
|
||||||
| `pami` | `php artisan make:interface` |
|
| `pami` | `php artisan make:interface` |
|
||||||
| `pamtr` | `php artisan make:trait` |
|
| `pamtr` | `php artisan make:trait` |
|
||||||
| `pamv` | `php artisan make:view` |
|
|
||||||
|
|
||||||
## Clears
|
## Clears
|
||||||
|
|
||||||
|
|||||||
@@ -31,7 +31,6 @@ alias pamcl='php artisan make:class'
|
|||||||
alias pamen='php artisan make:enum'
|
alias pamen='php artisan make:enum'
|
||||||
alias pami='php artisan make:interface'
|
alias pami='php artisan make:interface'
|
||||||
alias pamtr='php artisan make:trait'
|
alias pamtr='php artisan make:trait'
|
||||||
alias pamv='php artisan make:view'
|
|
||||||
|
|
||||||
|
|
||||||
# Clears
|
# Clears
|
||||||
|
|||||||
@@ -56,26 +56,19 @@ if zstyle -T ':omz:plugins:pipenv' auto-shell; then
|
|||||||
# deactivate shell if Pipfile doesn't exist and not in a subdir
|
# deactivate shell if Pipfile doesn't exist and not in a subdir
|
||||||
if [[ ! -f "$PWD/Pipfile" ]]; then
|
if [[ ! -f "$PWD/Pipfile" ]]; then
|
||||||
if [[ "$PIPENV_ACTIVE" == 1 ]]; then
|
if [[ "$PIPENV_ACTIVE" == 1 ]]; then
|
||||||
# Compare whole path components: `$pipfile_dir"*` also matches unrelated
|
if [[ "$PWD" != "$pipfile_dir"* ]]; then
|
||||||
# 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
|
|
||||||
unset PIPENV_ACTIVE pipfile_dir
|
unset PIPENV_ACTIVE pipfile_dir
|
||||||
deactivate
|
deactivate
|
||||||
fi
|
fi
|
||||||
fi
|
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 [[ "$PIPENV_ACTIVE" != 1 ]]; then
|
||||||
if [[ -f "$PWD/Pipfile" ]]; then
|
if [[ -f "$PWD/Pipfile" ]]; then
|
||||||
local venv_path
|
export pipfile_dir="$PWD"
|
||||||
if venv_path="$(pipenv --venv 2>/dev/null)" && [[ -n "$venv_path" && -f "$venv_path/bin/activate" ]]; then
|
source "$(pipenv --venv)/bin/activate"
|
||||||
export pipfile_dir="$PWD"
|
export PIPENV_ACTIVE=1
|
||||||
source "$venv_path/bin/activate"
|
|
||||||
export PIPENV_ACTIVE=1
|
|
||||||
fi
|
|
||||||
fi
|
fi
|
||||||
fi
|
fi
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,9 +1,7 @@
|
|||||||
# Poetry Environment Plugin
|
# Poetry Environment Plugin
|
||||||
|
|
||||||
This plugin automatically activates a Poetry environment when you enter a
|
This plugin automatically changes poetry environment when you cd into or out of the project directory.
|
||||||
directory containing both `pyproject.toml` and `poetry.lock`. It keeps the
|
Note: Script looks for pyproject.toml file to determine poetry if its a poetry environment
|
||||||
environment active in project subdirectories, switches to nested Poetry
|
|
||||||
projects, and deactivates it when you leave the project tree.
|
|
||||||
|
|
||||||
To use it, add `poetry-env` to the plugins array in your zshrc file:
|
To use it, add `poetry-env` to the plugins array in your zshrc file:
|
||||||
|
|
||||||
|
|||||||
@@ -1,24 +1,15 @@
|
|||||||
_togglePoetryShell() {
|
_togglePoetryShell() {
|
||||||
# Determine if currently in a Poetry-managed directory
|
# Determine if currently in a Poetry-managed directory
|
||||||
local in_poetry_dir=0
|
local in_poetry_dir=0
|
||||||
local in_active_poetry_dir=0
|
|
||||||
if [[ -f "$PWD/pyproject.toml" && -f "$PWD/poetry.lock" ]]; then
|
if [[ -f "$PWD/pyproject.toml" && -f "$PWD/poetry.lock" ]]; then
|
||||||
in_poetry_dir=1
|
in_poetry_dir=1
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# Deactivate when leaving the active project or entering a nested project
|
# Deactivate the current environment if moving out of a Poetry directory or into a different Poetry directory
|
||||||
if [[ $poetry_active -eq 1 ]]; then
|
if [[ $poetry_active -eq 1 ]] && { [[ $in_poetry_dir -eq 0 ]] || [[ "$PWD" != "$poetry_dir"* ]]; }; then
|
||||||
local project_dir="${poetry_dir%/}"
|
export poetry_active=0
|
||||||
if [[ "$PWD" == "$project_dir" || "$PWD" == "$project_dir"/* ]]; then
|
unset poetry_dir
|
||||||
in_active_poetry_dir=1
|
(( $+functions[deactivate] )) && deactivate
|
||||||
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
|
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# Activate the environment if in a Poetry directory and no environment is currently active
|
# Activate the environment if in a Poetry directory and no environment is currently active
|
||||||
|
|||||||
@@ -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"
|
|
||||||
} &|
|
|
||||||
@@ -0,0 +1,112 @@
|
|||||||
|
# Shopify CLI plugin
|
||||||
|
|
||||||
|
This plugin adds aliases, helper functions and completion for the
|
||||||
|
[Shopify CLI](https://shopify.dev/docs/api/shopify-cli).
|
||||||
|
|
||||||
|
To use it, add `shopify` to the plugins array in your zshrc file:
|
||||||
|
|
||||||
|
```zsh
|
||||||
|
plugins=(... shopify)
|
||||||
|
```
|
||||||
|
|
||||||
|
## Requirements
|
||||||
|
|
||||||
|
[Shopify CLI](https://shopify.dev/docs/api/shopify-cli) 4.0 or newer, installed
|
||||||
|
and on your `PATH`. The plugin does nothing if it is not:
|
||||||
|
|
||||||
|
```zsh
|
||||||
|
npm install -g @shopify/cli
|
||||||
|
# or
|
||||||
|
brew tap shopify/shopify && brew install shopify-cli
|
||||||
|
```
|
||||||
|
|
||||||
|
## Aliases
|
||||||
|
|
||||||
|
| Alias | Command | Description |
|
||||||
|
| :----- | :-------- | :--------------------- |
|
||||||
|
| `shop` | `shopify` | The Shopify CLI itself |
|
||||||
|
|
||||||
|
## Functions
|
||||||
|
|
||||||
|
| Function | Description |
|
||||||
|
| :------------- | :--------------------------------------------------------------------------------- |
|
||||||
|
| `shopd` | Runs `theme dev`, `app dev` or `hydrogen dev`, whichever fits the current project |
|
||||||
|
| `shopi` | Shows what the current project is connected to |
|
||||||
|
| `shopify_here` | Prints the kind of Shopify project you are in and the commands worth running in it |
|
||||||
|
| `shopify` | Wraps the CLI to confirm before irreversible commands. See Settings |
|
||||||
|
|
||||||
|
`shopd` and `shopi` work out which topic applies by looking at the project you
|
||||||
|
are standing in, so you do not have to remember whether this directory is a
|
||||||
|
theme, an app or a Hydrogen storefront. They complete like the command they
|
||||||
|
stand in for, so in a theme `shopd --<TAB>` offers the flags of
|
||||||
|
`shopify theme dev`.
|
||||||
|
|
||||||
|
## Completion
|
||||||
|
|
||||||
|
Every command completes with a description of what it does, at every level, and
|
||||||
|
so do their flags, short forms and allowed values. `--environment` completes
|
||||||
|
from the `[environments.*]` sections of your local `shopify.theme.toml` or
|
||||||
|
`shopify.app.toml`.
|
||||||
|
|
||||||
|
The Shopify CLI ships no completion generator of its own, so `_shopify` is
|
||||||
|
generated from `shopify commands --json` and kept in this repository. It targets
|
||||||
|
Shopify CLI 4.x.
|
||||||
|
|
||||||
|
## Settings
|
||||||
|
|
||||||
|
Set these with `zstyle` in your zshrc, before Oh My Zsh is sourced.
|
||||||
|
|
||||||
|
### Confirming destructive commands
|
||||||
|
|
||||||
|
```zsh
|
||||||
|
zstyle ':omz:plugins:shopify' confirm-destructive no
|
||||||
|
```
|
||||||
|
|
||||||
|
By default the plugin asks for confirmation before three irreversible
|
||||||
|
operations:
|
||||||
|
|
||||||
|
- `shopify theme push` with `--live`/`-l` or `--publish`/`-p`, which overwrites
|
||||||
|
or publishes the live storefront
|
||||||
|
- `shopify theme delete`, which the CLI's own help describes as impossible to
|
||||||
|
undo
|
||||||
|
- `shopify app deploy --allow-deletes`, which can permanently remove extensions
|
||||||
|
|
||||||
|
Nothing else is intercepted, and the prompt is skipped when the command already
|
||||||
|
carries `--force`/`-f` or when stdin is not a terminal, so scripts, pipelines
|
||||||
|
and CI are unaffected. Set the style to `no` to turn the prompt off entirely.
|
||||||
|
|
||||||
|
### Completing theme IDs
|
||||||
|
|
||||||
|
```zsh
|
||||||
|
zstyle ':omz:plugins:shopify' dynamic-theme-completion yes
|
||||||
|
```
|
||||||
|
|
||||||
|
Off by default. When enabled, `--theme` is completed from
|
||||||
|
`shopify theme list --json`, showing each theme's name and role next to its ID
|
||||||
|
instead of making you copy IDs by hand. It is opt-in because it runs the CLI and
|
||||||
|
makes a network call when you press <kbd>Tab</kbd>, and because it needs you to
|
||||||
|
be authenticated. Results are cached for five minutes.
|
||||||
|
|
||||||
|
### Disabling the aliases
|
||||||
|
|
||||||
|
This works for every Oh My Zsh plugin:
|
||||||
|
|
||||||
|
```zsh
|
||||||
|
zstyle ':omz:plugins:shopify' aliases no
|
||||||
|
```
|
||||||
|
|
||||||
|
## Caveats
|
||||||
|
|
||||||
|
- `shopify` is a shell function here. Run `command shopify` to reach the binary
|
||||||
|
directly.
|
||||||
|
- When a project has its own copy of the CLI in `node_modules/.bin/shopify`,
|
||||||
|
that one is used in preference to the global install. App and Hydrogen
|
||||||
|
projects normally pin the CLI in `package.json`, and running a different
|
||||||
|
global version against them is a common source of confusing errors.
|
||||||
|
- `--password` and `--store-password` are unrelated, and you often need both.
|
||||||
|
`--password` is the CLI's own authentication token, from the Theme Access app
|
||||||
|
or the Admin API. `--store-password` is the password for a
|
||||||
|
password-protected storefront.
|
||||||
|
- `shopify theme push` deletes remote files that are missing locally, and
|
||||||
|
`shopify theme pull` deletes local files that are missing remotely, unless you
|
||||||
|
pass `--nodelete`/`-n`. The plugin does not prompt for these.
|
||||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,204 @@
|
|||||||
|
# Shopify CLI: completion, aliases and guard rails.
|
||||||
|
# https://shopify.dev/docs/api/shopify-cli
|
||||||
|
|
||||||
|
if (( ! $+commands[shopify] )); then
|
||||||
|
return
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Prefer a project-local CLI: app and Hydrogen projects pin their own version.
|
||||||
|
# The walk stops at $HOME so a stray ~/node_modules cannot hijack every project.
|
||||||
|
# $commands avoids resolving back to the wrapper function below.
|
||||||
|
function _shopify_bin() {
|
||||||
|
local dir="$PWD"
|
||||||
|
while [[ -n "$dir" && "$dir" != "/" && "$dir" != "$HOME" ]]; do
|
||||||
|
if [[ -x "$dir/node_modules/.bin/shopify" ]]; then
|
||||||
|
print -r -- "$dir/node_modules/.bin/shopify"
|
||||||
|
return 0
|
||||||
|
fi
|
||||||
|
dir="${dir:h}"
|
||||||
|
done
|
||||||
|
print -r -- "$commands[shopify]"
|
||||||
|
}
|
||||||
|
|
||||||
|
# Print the project type in $PWD: hydrogen, app or theme.
|
||||||
|
# Hydrogen is tested first because those projects usually carry a
|
||||||
|
# shopify.app.toml too. shopify.theme.toml is not a theme marker: it only
|
||||||
|
# exists once environments are configured.
|
||||||
|
function _shopify_project_type() {
|
||||||
|
local dir="$PWD"
|
||||||
|
local -a app_config
|
||||||
|
|
||||||
|
while [[ -n "$dir" && "$dir" != "/" && "$dir" != "$HOME" ]]; do
|
||||||
|
if [[ -x "$dir/node_modules/.bin/h2" ]] ||
|
||||||
|
[[ -f "$dir/package.json" && "$(<"$dir/package.json")" == *'"@shopify/hydrogen"'* ]]; then
|
||||||
|
print -r -- hydrogen
|
||||||
|
return 0
|
||||||
|
fi
|
||||||
|
|
||||||
|
app_config=("$dir"/shopify.app*.toml(N))
|
||||||
|
if (( $#app_config )); then
|
||||||
|
print -r -- app
|
||||||
|
return 0
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [[ -f "$dir/config/settings_schema.json" && -f "$dir/layout/theme.liquid" ]]; then
|
||||||
|
print -r -- theme
|
||||||
|
return 0
|
||||||
|
fi
|
||||||
|
|
||||||
|
dir="${dir:h}"
|
||||||
|
done
|
||||||
|
|
||||||
|
return 1
|
||||||
|
}
|
||||||
|
|
||||||
|
# Does this invocation need confirming? Sets REPLY to the reason.
|
||||||
|
function _shopify_is_destructive() {
|
||||||
|
zstyle -T ':omz:plugins:shopify' confirm-destructive || return 1
|
||||||
|
|
||||||
|
# Nobody to answer: CI and pipelines are unaffected.
|
||||||
|
[[ -t 0 ]] || return 1
|
||||||
|
|
||||||
|
local topic="$1" subcommand="$2" arg
|
||||||
|
local -a long
|
||||||
|
local short=""
|
||||||
|
|
||||||
|
# Short flags can be bundled, so collect them as characters: -al counts as l.
|
||||||
|
for arg in "${@[3,-1]}"; do
|
||||||
|
[[ "$arg" == "--" ]] && break
|
||||||
|
case "$arg" in
|
||||||
|
--*) long+=("${arg%%=*}") ;;
|
||||||
|
-?*) short+="${${arg%%=*}#-}" ;;
|
||||||
|
esac
|
||||||
|
done
|
||||||
|
|
||||||
|
# An explicit force flag states the intent already.
|
||||||
|
if (( long[(I)--force] )) || [[ "$short" == *f* ]]; then
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
case "$topic $subcommand" in
|
||||||
|
"theme push")
|
||||||
|
if (( long[(I)--live] || long[(I)--publish] )) || [[ "$short" == *[lp]* ]]; then
|
||||||
|
REPLY="this overwrites or publishes the live theme on the storefront."
|
||||||
|
return 0
|
||||||
|
fi
|
||||||
|
;;
|
||||||
|
"theme delete")
|
||||||
|
REPLY="deleting a theme cannot be undone."
|
||||||
|
return 0
|
||||||
|
;;
|
||||||
|
"app deploy")
|
||||||
|
if (( long[(I)--allow-deletes] )); then
|
||||||
|
REPLY="this can permanently remove app extensions."
|
||||||
|
return 0
|
||||||
|
fi
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
|
||||||
|
return 1
|
||||||
|
}
|
||||||
|
|
||||||
|
# Adds a confirmation prompt before irreversible operations. Everything else
|
||||||
|
# passes straight through, so `theme dev` stays interactive and pipes stay clean.
|
||||||
|
function shopify() {
|
||||||
|
local REPLY
|
||||||
|
if _shopify_is_destructive "$@"; then
|
||||||
|
print -u2 -- "shopify: $REPLY"
|
||||||
|
if ! read -q "?Continue? [y/N] "; then
|
||||||
|
print -u2 -- ""
|
||||||
|
return 130
|
||||||
|
fi
|
||||||
|
print -u2 -- ""
|
||||||
|
fi
|
||||||
|
|
||||||
|
"$(_shopify_bin)" "$@"
|
||||||
|
}
|
||||||
|
|
||||||
|
# Print the commands worth running in the current directory.
|
||||||
|
function shopify_here() {
|
||||||
|
local project_type
|
||||||
|
project_type="$(_shopify_project_type)"
|
||||||
|
|
||||||
|
case "$project_type" in
|
||||||
|
theme)
|
||||||
|
print -- "Shopify theme project."
|
||||||
|
print -- " shopify theme dev Preview locally with live reload"
|
||||||
|
print -- " shopify theme check Lint the theme"
|
||||||
|
print -- " shopify theme list List the themes on the store"
|
||||||
|
print -- " shopify theme pull Download a remote theme into this folder"
|
||||||
|
print -- " shopify theme push Upload this folder to a remote theme"
|
||||||
|
;;
|
||||||
|
app)
|
||||||
|
print -- "Shopify app project."
|
||||||
|
print -- " shopify app dev Run the app against a development store"
|
||||||
|
print -- " shopify app info Show how the app is configured"
|
||||||
|
print -- " shopify app deploy Deploy the app and its extensions"
|
||||||
|
print -- " shopify app logs Stream app logs"
|
||||||
|
;;
|
||||||
|
hydrogen)
|
||||||
|
print -- "Hydrogen storefront."
|
||||||
|
print -- " shopify hydrogen dev Run the storefront locally"
|
||||||
|
print -- " shopify hydrogen build Build for production"
|
||||||
|
print -- " shopify hydrogen deploy Deploy to Oxygen"
|
||||||
|
print -- " shopify hydrogen link Link this project to a storefront"
|
||||||
|
;;
|
||||||
|
*)
|
||||||
|
print -- "No Shopify project found here."
|
||||||
|
print -- " shopify theme init Start a new theme"
|
||||||
|
print -- " shopify app init Start a new app"
|
||||||
|
print -- " shopify hydrogen init Start a new Hydrogen storefront"
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
}
|
||||||
|
|
||||||
|
# Run the dev server for whichever kind of project this is.
|
||||||
|
function shopd() {
|
||||||
|
local project_type
|
||||||
|
if ! project_type="$(_shopify_project_type)"; then
|
||||||
|
print -u2 -- "shopd: not inside a Shopify theme, app or Hydrogen project."
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
shopify "$project_type" dev "$@"
|
||||||
|
}
|
||||||
|
|
||||||
|
# Show what the current project is connected to.
|
||||||
|
function shopi() {
|
||||||
|
local project_type
|
||||||
|
if ! project_type="$(_shopify_project_type)"; then
|
||||||
|
print -u2 -- "shopi: not inside a Shopify theme, app or Hydrogen project."
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
case "$project_type" in
|
||||||
|
hydrogen) shopify hydrogen list "$@" ;;
|
||||||
|
*) shopify "$project_type" info "$@" ;;
|
||||||
|
esac
|
||||||
|
}
|
||||||
|
|
||||||
|
# Complete the helpers like the commands they stand in for.
|
||||||
|
if (( $+functions[compdef] )); then
|
||||||
|
_shopd() {
|
||||||
|
local project_type
|
||||||
|
project_type="$(_shopify_project_type)" || return 1
|
||||||
|
words=(shopify "$project_type" dev ${words[2,-1]})
|
||||||
|
(( CURRENT += 2 ))
|
||||||
|
_shopify
|
||||||
|
}
|
||||||
|
|
||||||
|
_shopi() {
|
||||||
|
local project_type
|
||||||
|
project_type="$(_shopify_project_type)" || return 1
|
||||||
|
if [[ "$project_type" == hydrogen ]]; then
|
||||||
|
words=(shopify hydrogen list ${words[2,-1]})
|
||||||
|
else
|
||||||
|
words=(shopify "$project_type" info ${words[2,-1]})
|
||||||
|
fi
|
||||||
|
(( CURRENT += 2 ))
|
||||||
|
_shopify
|
||||||
|
}
|
||||||
|
|
||||||
|
compdef _shopd shopd
|
||||||
|
compdef _shopi shopi
|
||||||
|
fi
|
||||||
|
|
||||||
|
alias shop='shopify'
|
||||||
@@ -19,7 +19,6 @@
|
|||||||
ssm_run_sudo() {sudo $_sublime_merge_path "$@" >/dev/null 2>&1}
|
ssm_run_sudo() {sudo $_sublime_merge_path "$@" >/dev/null 2>&1}
|
||||||
alias ssm=ssm_run_sudo
|
alias ssm=ssm_run_sudo
|
||||||
alias sm=sm_run
|
alias sm=sm_run
|
||||||
alias smerge="'$_sublime_merge_path'"
|
|
||||||
break
|
break
|
||||||
fi
|
fi
|
||||||
done
|
done
|
||||||
@@ -34,7 +33,6 @@
|
|||||||
if [[ -a $_sublime_merge_path ]]; then
|
if [[ -a $_sublime_merge_path ]]; then
|
||||||
subm () { "$_sublime_merge_path" "$@" }
|
subm () { "$_sublime_merge_path" "$@" }
|
||||||
alias sm=subm
|
alias sm=subm
|
||||||
alias smerge="'$_sublime_merge_path'"
|
|
||||||
break
|
break
|
||||||
fi
|
fi
|
||||||
done
|
done
|
||||||
@@ -47,7 +45,6 @@
|
|||||||
if [[ -a $_sublime_merge_path ]]; then
|
if [[ -a $_sublime_merge_path ]]; then
|
||||||
subm () { "$_sublime_merge_path" "$@" }
|
subm () { "$_sublime_merge_path" "$@" }
|
||||||
alias sm=subm
|
alias sm=subm
|
||||||
alias smerge="'$_sublime_merge_path'"
|
|
||||||
break
|
break
|
||||||
fi
|
fi
|
||||||
done
|
done
|
||||||
|
|||||||
@@ -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
|
|
||||||
@@ -47,7 +47,6 @@ _box_arguments=(
|
|||||||
'help:COMMAND List subcommands'
|
'help:COMMAND List subcommands'
|
||||||
'list:Lists all installed boxes'
|
'list:Lists all installed boxes'
|
||||||
'outdated:Checks if a box has newer version'
|
'outdated:Checks if a box has newer version'
|
||||||
'prune:Removes old versions of installed boxes'
|
|
||||||
'remove:NAME Removes a box from the system'
|
'remove:NAME Removes a box from the system'
|
||||||
'repackage:NAME PROVIDER VERSION Repackages an installed box into a `.box` file'
|
'repackage:NAME PROVIDER VERSION Repackages an installed box into a `.box` file'
|
||||||
'update:Updates box to a newer version, if available'
|
'update:Updates box to a newer version, if available'
|
||||||
|
|||||||
@@ -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"
|
|
||||||
Reference in New Issue
Block a user