diff --git a/lib/cli.zsh b/lib/cli.zsh index 2189e24ca..cadc82e27 100644 --- a/lib/cli.zsh +++ b/lib/cli.zsh @@ -35,7 +35,7 @@ function _omz { elif (( CURRENT == 3 )); then case "$words[2]" in changelog) local -a refs - refs=("${(@f)$(command git for-each-ref --format="%(refname:short):%(subject)" refs/heads refs/tags)}") + refs=("${(@f)$(command git -C "$ZSH" for-each-ref --format="%(refname:short):%(subject)" refs/heads refs/tags)}") _describe 'command' refs ;; plugin) subcmds=( 'disable:Disable plugin(s)' @@ -630,17 +630,23 @@ function _omz::theme::list { return fi + # Print theme in use + if [[ -n "$ZSH_THEME" ]]; then + print -Pn "%U%BCurrent theme%b%u: " + [[ $ZSH_THEME = random ]] && echo "$RANDOM_THEME (via random)" || echo "$ZSH_THEME" + echo + fi + + # Print custom themes if there are any if (( ${#custom_themes} )); then print -P "%U%BCustom themes%b%u:" print -l ${(q-)custom_themes} | column -x + echo fi - if (( ${#builtin_themes} )); then - (( ${#custom_themes} )) && echo # add a line of separation - - print -P "%U%BBuilt-in themes%b%u:" - print -l ${(q-)builtin_themes} | column -x - fi + # Print built-in themes + print -P "%U%BBuilt-in themes%b%u:" + print -l ${(q-)builtin_themes} | column -x } function _omz::theme::set { @@ -727,6 +733,10 @@ function _omz::theme::use { _omz::log error "%B$1%b theme not found" return 1 fi + + # Update theme settings + ZSH_THEME="$1" + [[ $1 = random ]] || unset RANDOM_THEME } function _omz::update { diff --git a/lib/completion.zsh b/lib/completion.zsh index ebaab0856..2c5695487 100644 --- a/lib/completion.zsh +++ b/lib/completion.zsh @@ -58,9 +58,12 @@ zstyle ':completion:*:*:*:users' ignored-patterns \ # ... unless we really want to. zstyle '*' single-ignored show -if [[ $COMPLETION_WAITING_DOTS = true ]]; then +if [[ ${COMPLETION_WAITING_DOTS:-false} != false ]]; then expand-or-complete-with-dots() { - print -Pn "%F{red}…%f" + # use $COMPLETION_WAITING_DOTS either as toggle or as the sequence to show + [[ $COMPLETION_WAITING_DOTS = true ]] && COMPLETION_WAITING_DOTS="%F{red}…%f" + # turn off line wrapping and print prompt-expanded "dot" sequence + printf '\e[?7l%s\e[?7h' "${(%)COMPLETION_WAITING_DOTS}" zle expand-or-complete zle redisplay } diff --git a/lib/correction.zsh b/lib/correction.zsh index c635236b5..4259d3418 100644 --- a/lib/correction.zsh +++ b/lib/correction.zsh @@ -9,6 +9,7 @@ if [[ "$ENABLE_CORRECTION" == "true" ]]; then alias mv='nocorrect mv' alias mysql='nocorrect mysql' alias sudo='nocorrect sudo' + alias su='nocorrect su' setopt correct_all fi diff --git a/lib/termsupport.zsh b/lib/termsupport.zsh index 33451ef1f..ef0d78895 100644 --- a/lib/termsupport.zsh +++ b/lib/termsupport.zsh @@ -10,7 +10,8 @@ function title { emulate -L zsh setopt prompt_subst - [[ "$INSIDE_EMACS" == *term* ]] && return + # Don't set the title if inside emacs, unless using vterm + [[ -n "$INSIDE_EMACS" && "$INSIDE_EMACS" != vterm ]] && return # if $2 is unset use $1 as default # if it is set and empty, leave it as is @@ -29,12 +30,9 @@ function title { print -Pn "\e]2;${2:q}\a" # set window name print -Pn "\e]1;${1:q}\a" # set tab name else - # Try to use terminfo to set the title - # If the feature is available set title - if [[ -n "$terminfo[fsl]" ]] && [[ -n "$terminfo[tsl]" ]]; then - echoti tsl - print -Pn "$1" - echoti fsl + # Try to use terminfo to set the title if the feature is available + if (( ${+terminfo[fsl]} && ${+terminfo[tsl]} )); then + print -Pn "${terminfo[tsl]}$1${terminfo[fsl]}" fi fi ;; @@ -105,10 +103,12 @@ function omz_termsupport_preexec { title '$CMD' '%100>...>$LINE%<<' } -autoload -U add-zsh-hook -add-zsh-hook precmd omz_termsupport_precmd -add-zsh-hook preexec omz_termsupport_preexec +autoload -Uz add-zsh-hook +if [[ -z "$INSIDE_EMACS" || "$INSIDE_EMACS" = vterm ]]; then + add-zsh-hook precmd omz_termsupport_precmd + add-zsh-hook preexec omz_termsupport_preexec +fi # Keep Apple Terminal.app's current working directory updated # Based on this answer: https://superuser.com/a/315029 diff --git a/oh-my-zsh.sh b/oh-my-zsh.sh index 16e244be5..bf5902fc8 100644 --- a/oh-my-zsh.sh +++ b/oh-my-zsh.sh @@ -1,3 +1,11 @@ +# Protect against non-zsh execution of Oh My Zsh (use POSIX syntax here) +[ -n "$ZSH_VERSION" ] || { + # ANSI (\033[m): 0: reset, 1: bold, 4: underline, 22: no bold, 24: no underline, 31: red + printf "\033[1;31mERROR:\033[22m Oh My Zsh can't be loaded from: \033[1m${0#-}\033[22m. " >&2 + printf "You need to run \033[1;4mzsh\033[22;24m instead.\033[0m\n" >&2 + return 1 +} + # If ZSH is not defined, use the current script's directory. [[ -z "$ZSH" ]] && export ZSH="${${(%):-%x}:a:h}" @@ -7,6 +15,15 @@ if [[ -z "$ZSH_CACHE_DIR" ]]; then ZSH_CACHE_DIR="$ZSH/cache" fi +# Make sure $ZSH_CACHE_DIR is writable, otherwise use a directory in $HOME +if [[ ! -w "$ZSH_CACHE_DIR" ]]; then + ZSH_CACHE_DIR="${XDG_CACHE_HOME:-$HOME/.cache}/oh-my-zsh" +fi + +# Create cache and completions dir and add to $fpath +mkdir -p "$ZSH_CACHE_DIR/completions" +(( ${fpath[(Ie)"$ZSH_CACHE_DIR/completions"]} )) || fpath=("$ZSH_CACHE_DIR/completions" $fpath) + # Check for updates on initial load... if [ "$DISABLE_AUTO_UPDATE" != "true" ]; then source $ZSH/tools/check_for_upgrade.sh diff --git a/plugins/archlinux/README.md b/plugins/archlinux/README.md index d6b41ee40..c8ec1de1e 100644 --- a/plugins/archlinux/README.md +++ b/plugins/archlinux/README.md @@ -32,7 +32,7 @@ plugins=(... archlinux) | pacfiles | `pacman -F` | Search package file names for matching strings | | pacls | `pacman -Ql` | List files in a package | | pacown | `pacman -Qo` | Show which package owns a file | -| upgrade[²](#f2) | `sudo pacman -Syu` | Sync with repositories before upgrading packages | +| upgrade[¹](#f1) | `sudo pacman -Syu` | Sync with repositories before upgrading packages | | Function | Description | |----------------|-----------------------------------------------------------| @@ -73,7 +73,7 @@ upgrades were available. Use `pacman -Que` instead. | auupd | `sudo aura -Sy` | Update and refresh local package, ABS and AUR databases | | auupg | `sudo sh -c "aura -Syu && aura -Au"` | Sync with repositories before upgrading all packages (from AUR too) | | ausu | `sudo sh -c "aura -Syu --no-confirm && aura -Au --no-confirm"` | Same as `auupg`, but without confirmation | -| upgrade[²](#f2) | `sudo aura -Syu` | Sync with repositories before upgrading packages | +| upgrade[¹](#f1) | `sudo aura -Syu` | Sync with repositories before upgrading packages | | Function | Description | |-----------------|---------------------------------------------------------------------| @@ -99,7 +99,7 @@ upgrades were available. Use `pacman -Que` instead. | paupd | `pacaur -Sy` | Update and refresh local package, ABS and AUR databases | | paupg | `pacaur -Syua` | Sync with repositories before upgrading all packages (from AUR too) | | pasu | `pacaur -Syua --no-confirm` | Same as `paupg`, but without confirmation | -| upgrade[²](#f2) | `pacaur -Syu` | Sync with repositories before upgrading packages | +| upgrade[¹](#f1) | `pacaur -Syu` | Sync with repositories before upgrading packages | #### Trizen @@ -121,31 +121,9 @@ upgrades were available. Use `pacman -Que` instead. | trupd | `trizen -Sy` | Update and refresh local package, ABS and AUR databases | | trupg | `trizen -Syua` | Sync with repositories before upgrading all packages (from AUR too) | | trsu | `trizen -Syua --no-confirm` | Same as `trupg`, but without confirmation | -| upgrade[²](#f2) | `trizen -Syu` | Sync with repositories before upgrading packages | +| upgrade[¹](#f1) | `trizen -Syu` | Sync with repositories before upgrading packages | -#### Yaourt[¹](#f1) - -| Alias | Command | Description | -|---------|-----------------------------------|---------------------------------------------------------------------| -| yaconf | `yaourt -C` | Fix all configuration files with vimdiff | -| yain | `yaourt -S` | Install packages from the repositories | -| yains | `yaourt -U` | Install a package from a local file | -| yainsd | `yaourt -S --asdeps` | Install packages as dependencies of another package | -| yaloc | `yaourt -Qi` | Display information about a package in the local database | -| yalocs | `yaourt -Qs` | Search for packages in the local database | -| yalst | `yaourt -Qe` | List installed packages including from AUR (tagged as "local") | -| yamir | `yaourt -Syy` | Force refresh of all package lists after updating mirrorlist | -| yaorph | `yaourt -Qtd` | Remove orphans using yaourt | -| yare | `yaourt -R` | Remove packages, keeping its settings and dependencies | -| yarem | `yaourt -Rns` | Remove packages, including its settings and unneeded dependencies | -| yarep | `yaourt -Si` | Display information about a package in the repositories | -| yareps | `yaourt -Ss` | Search for packages in the repositories | -| yaupd | `yaourt -Sy` | Update and refresh local package, ABS and AUR databases | -| yaupg | `yaourt -Syua` | Sync with repositories before upgrading all packages (from AUR too) | -| yasu | `yaourt -Syua --no-confirm` | Same as `yaupg`, but without confirmation | -| upgrade[²](#f2) | `yaourt -Syu` | Sync with repositories before upgrading packages | - -#### Yay[¹](#f1) +#### Yay | Alias | Command | Description | |---------|--------------------------------|-------------------------------------------------------------------| @@ -165,23 +143,19 @@ upgrades were available. Use `pacman -Que` instead. | yaupd | `yay -Sy` | Update and refresh local package, ABS and AUR databases | | yaupg | `yay -Syu` | Sync with repositories before upgrading packages | | yasu | `yay -Syu --no-confirm` | Same as `yaupg`, but without confirmation | -| upgrade[²](#f2) | `yay -Syu` | Sync with repositories before upgrading packages | +| upgrade[¹](#f1) | `yay -Syu` | Sync with repositories before upgrading packages | --- ¹ -Yay and Yaourt aliases overlap. If both are installed, yay will take precedence. - -² The `upgrade` alias is set for all package managers. Its value will depend on whether the package manager is installed, checked in the following order: 1. `yay` -2. `yaourt` -3. `trizen` -4. `pacaur` -5. `aura` -6. `pacman` +2. `trizen` +3. `pacaur` +4. `aura` +5. `pacman` ## Contributors diff --git a/plugins/archlinux/archlinux.plugin.zsh b/plugins/archlinux/archlinux.plugin.zsh index c94fb8f6c..0c5782d98 100644 --- a/plugins/archlinux/archlinux.plugin.zsh +++ b/plugins/archlinux/archlinux.plugin.zsh @@ -104,7 +104,7 @@ if (( $+commands[aura] )); then alias auras='aura -As --both' alias auupd="sudo aura -Sy" alias auupg='sudo sh -c "aura -Syu && aura -Au"' - alias ausu='sudo sh -c "aura -Syu --no-confirm && aura -Au --no-confirm"' + alias ausu='sudo sh -c "aura -Syu --no-confirm && aura -Au --no-confirm"' alias upgrade='sudo aura -Syu' # extra bonus specially for aura @@ -153,26 +153,6 @@ if (( $+commands[trizen] )); then alias upgrade='trizen -Syu' fi -if (( $+commands[yaourt] )); then - alias yaconf='yaourt -C' - alias yaupg='yaourt -Syua' - alias yasu='yaourt -Syua --noconfirm' - alias yain='yaourt -S' - alias yains='yaourt -U' - alias yare='yaourt -R' - alias yarem='yaourt -Rns' - alias yarep='yaourt -Si' - alias yareps='yaourt -Ss' - alias yaloc='yaourt -Qi' - alias yalocs='yaourt -Qs' - alias yalst='yaourt -Qe' - alias yaorph='yaourt -Qtd' - alias yainsd='yaourt -S --asdeps' - alias yamir='yaourt -Syy' - alias yaupd="yaourt -Sy" - alias upgrade='yaourt -Syu' -fi - if (( $+commands[yay] )); then alias yaconf='yay -Pg' alias yaupg='yay -Syu' @@ -192,4 +172,3 @@ if (( $+commands[yay] )); then alias yaupd="yay -Sy" alias upgrade='yay -Syu' fi - diff --git a/plugins/cargo/.gitignore b/plugins/cargo/.gitignore deleted file mode 100644 index 42d7ecdd6..000000000 --- a/plugins/cargo/.gitignore +++ /dev/null @@ -1 +0,0 @@ -_cargo diff --git a/plugins/cargo/cargo.plugin.zsh b/plugins/cargo/cargo.plugin.zsh index 92eae5359..7082d2d55 100644 --- a/plugins/cargo/cargo.plugin.zsh +++ b/plugins/cargo/cargo.plugin.zsh @@ -1,11 +1,23 @@ -# COMPLETION FUNCTION if (( $+commands[rustup] && $+commands[cargo] )); then - if [[ ! -f $ZSH_CACHE_DIR/cargo_version ]] \ - || [[ "$(cargo --version)" != "$(< "$ZSH_CACHE_DIR/cargo_version")" ]] \ - || [[ ! -f $ZSH/plugins/cargo/_cargo ]]; then - rustup completions zsh cargo > $ZSH/plugins/cargo/_cargo - cargo --version > $ZSH_CACHE_DIR/cargo_version + # remove old generated completion file + command rm -f "${0:A:h}/_cargo" + + # generate new completion file + ver="$(cargo --version)" + ver_file="$ZSH_CACHE_DIR/cargo_version" + comp_file="$ZSH_CACHE_DIR/completions/_cargo" + + mkdir -p "${comp_file:h}" + (( ${fpath[(Ie)${comp_file:h}]} )) || fpath=("${comp_file:h}" $fpath) + + if [[ ! -f "$comp_file" || ! -f "$ver_file" || "$ver" != "$(< "$ver_file")" ]]; then + rustup completions zsh cargo >| "$comp_file" + echo "$ver" >| "$ver_file" fi + + declare -A _comps autoload -Uz _cargo _comps[cargo]=_cargo + + unset ver ver_file comp_file fi diff --git a/plugins/copybuffer/copybuffer.plugin.zsh b/plugins/copybuffer/copybuffer.plugin.zsh index 87a658d93..e67f920f0 100644 --- a/plugins/copybuffer/copybuffer.plugin.zsh +++ b/plugins/copybuffer/copybuffer.plugin.zsh @@ -11,4 +11,6 @@ copybuffer () { zle -N copybuffer -bindkey "^O" copybuffer +bindkey -M emacs "^O" copybuffer +bindkey -M viins "^O" copybuffer +bindkey -M vicmd "^O" copybuffer diff --git a/plugins/deno/.gitignore b/plugins/deno/.gitignore deleted file mode 100644 index cba5b03e8..000000000 --- a/plugins/deno/.gitignore +++ /dev/null @@ -1 +0,0 @@ -_deno diff --git a/plugins/deno/deno.plugin.zsh b/plugins/deno/deno.plugin.zsh index a37b3bec4..34adddc37 100644 --- a/plugins/deno/deno.plugin.zsh +++ b/plugins/deno/deno.plugin.zsh @@ -12,12 +12,24 @@ alias dup='deno upgrade' # COMPLETION FUNCTION if (( $+commands[deno] )); then - if [[ ! -f $ZSH_CACHE_DIR/deno_version ]] \ - || [[ "$(deno --version)" != "$(< "$ZSH_CACHE_DIR/deno_version")" ]] \ - || [[ ! -f $ZSH/plugins/deno/_deno ]]; then - deno completions zsh > $ZSH/plugins/deno/_deno - deno --version > $ZSH_CACHE_DIR/deno_version + # remove old generated completion file + command rm -f "${0:A:h}/_deno" + + ver="$(deno --version)" + ver_file="$ZSH_CACHE_DIR/deno_version" + comp_file="$ZSH_CACHE_DIR/completions/_deno" + + mkdir -p "${comp_file:h}" + (( ${fpath[(Ie)${comp_file:h}]} )) || fpath=("${comp_file:h}" $fpath) + + if [[ ! -f "$comp_file" || ! -f "$ver_file" || "$ver" != "$(< "$ver_file")" ]]; then + deno completions zsh >| "$comp_file" + echo "$ver" >| "$ver_file" fi + + declare -A _comps autoload -Uz _deno _comps[deno]=_deno + + unset ver ver_file comp_file fi diff --git a/plugins/django/README.md b/plugins/django/README.md index 1740e55e5..cfab43980 100644 --- a/plugins/django/README.md +++ b/plugins/django/README.md @@ -1,36 +1,12 @@ # Django plugin -This plugin adds completion and hints for the [Django Project](https://www.djangoproject.com/) `manage.py` commands -and options. +This plugin adds completion for the [Django Project](https://www.djangoproject.com/) commands +(`manage.py`, `django-admin`, ...). -To use it, add `django` to the plugins array in your zshrc file: +## Deprecation (2021-09-22) -```zsh -plugins=(... django) -``` +The plugin used to provide completion for `./manage.py` and `django-admin`, but Zsh already provides +a better, more extensive completion for those, so this plugin is no longer needed. -## Usage - -```zsh -$> python manage.py (press here) -``` - -Would result in: - -```zsh -cleanup -- remove old data from the database -compilemessages -- compile .po files to .mo for use with gettext -createcachetable -- creates table for SQL cache backend -createsuperuser -- create a superuser -dbshell -- run command-line client for the current database -diffsettings -- display differences between the current settings and Django defaults -dumpdata -- output contents of database as a fixture -flush -- execute 'sqlflush' on the current database -inspectdb -- output Django model module for tables in database -loaddata -- install the named fixture(s) in the database -makemessages -- pull out all strings marked for translation -reset -- executes 'sqlreset' for the given app(s) -runfcgi -- run this project as a fastcgi -runserver -- start a lightweight web server for development -... -``` +Right now a warning message is shown, but in the near future the plugin will stop working altogether. +So you can remove it from your plugins and you'll automatically start using Zsh's django completion. diff --git a/plugins/django/django.plugin.zsh b/plugins/django/django.plugin.zsh index c2d00c171..a07a30889 100644 --- a/plugins/django/django.plugin.zsh +++ b/plugins/django/django.plugin.zsh @@ -402,3 +402,6 @@ compdef _managepy django compdef _managepy django-admin compdef _managepy django-admin.py compdef _managepy django-manage + +print -P "%F{yellow}The django plugin is deprecated in favor of Zsh's Django completion. +%BPlease remove it from your plugins to stop using it.%b%f" diff --git a/plugins/docker/_docker b/plugins/docker/_docker index 7fe204313..8ee35abcf 100644 --- a/plugins/docker/_docker +++ b/plugins/docker/_docker @@ -1343,7 +1343,7 @@ __docker_node_complete_ls_filters() { ;; esac else - opts=('id' 'label' 'membership' 'name' 'role') + opts=('id' 'label' 'membership' 'name' 'node.label' 'role') _describe -t filter-opts "filter options" opts -qS "=" && ret=0 fi @@ -2544,6 +2544,82 @@ __docker_volume_subcommand() { # EO volume +# BO context + +__docker_complete_contexts() { + [[ $PREFIX = -* ]] && return 1 + integer ret=1 + declare -a contexts + + contexts=(${(f)${:-"$(_call_program commands docker $docker_options context ls -q)"$'\n'}}) + + _describe -t context-list "context" contexts && ret=0 + return ret +} + +__docker_context_commands() { + local -a _docker_context_subcommands + _docker_context_subcommands=( + "create:Create new context" + "inspect:Display detailed information on one or more contexts" + "list:List available contexts" + "rm:Remove one or more contexts" + "show:Print the current context" + "update:Update a context" + "use:Set the default context" + ) + _describe -t docker-context-commands "docker context command" _docker_context_subcommands +} + +__docker_context_subcommand() { + local -a _command_args opts_help + local expl help="--help" + integer ret=1 + + opts_help=("(: -)--help[Print usage]") + + case "$words[1]" in + (create) + _arguments $(__docker_arguments) \ + $opts_help \ + "($help)--default-stack-orchestrator=[Default orchestrator for stack operations to use with this context]:default-stack-orchestrator:(swarm kubernetes all)" \ + "($help)--description=[Description of the context]:description:" \ + "($help)--docker=[Set the docker endpoint]:docker:" \ + "($help)--kubernetes=[Set the kubernetes endpoint]:kubernetes:" \ + "($help)--from=[Create context from a named context]:from:__docker_complete_contexts" \ + "($help -):name: " && ret=0 + ;; + (use) + _arguments $(__docker_arguments) \ + $opts_help \ + "($help -)1:context:__docker_complete_contexts" && ret=0 + ;; + (inspect) + _arguments $(__docker_arguments) \ + $opts_help \ + "($help -)1:context:__docker_complete_contexts" && ret=0 + ;; + (rm) + _arguments $(__docker_arguments) \ + $opts_help \ + "($help -)1:context:__docker_complete_contexts" && ret=0 + ;; + (update) + _arguments $(__docker_arguments) \ + $opts_help \ + "($help)--default-stack-orchestrator=[Default orchestrator for stack operations to use with this context]:default-stack-orchestrator:(swarm kubernetes all)" \ + "($help)--description=[Description of the context]:description:" \ + "($help)--docker=[Set the docker endpoint]:docker:" \ + "($help)--kubernetes=[Set the kubernetes endpoint]:kubernetes:" \ + "($help -):name:" && ret=0 + ;; + esac + + return ret +} + +# EO context + __docker_caching_policy() { oldp=( "$1"(Nmh+1) ) # 1 hour (( $#oldp )) @@ -2576,7 +2652,7 @@ __docker_commands() { then local -a lines lines=(${(f)"$(_call_program commands docker 2>&1)"}) - _docker_subcommands=(${${${(M)${lines[$((${lines[(i)*Commands:]} + 1)),-1]}:# *}## #}/ ##/:}) + _docker_subcommands=(${${${(M)${lines[$((${lines[(i)*Commands:]} + 1)),-1]}:# *}## #}/\*# ##/:}) _docker_subcommands=($_docker_subcommands 'daemon:Enable daemon mode' 'help:Show help for a command') (( $#_docker_subcommands > 2 )) && _store_cache docker_subcommands _docker_subcommands fi @@ -2631,6 +2707,23 @@ __docker_subcommand() { ;; esac ;; + (context) + local curcontext="$curcontext" state + _arguments $(__docker_arguments) \ + $opts_help \ + "($help -): :->command" \ + "($help -)*:: :->option-or-argument" && ret=0 + + case $state in + (command) + __docker_context_commands && ret=0 + ;; + (option-or-argument) + curcontext=${curcontext%:*:*}:docker-${words[-1]}: + __docker_context_subcommand && ret=0 + ;; + esac + ;; (daemon) _arguments $(__docker_arguments) \ $opts_help \ @@ -2698,7 +2791,8 @@ __docker_subcommand() { "($help)--tlsverify[Use TLS and verify the remote]" \ "($help)--userns-remap=[User/Group setting for user namespaces]:user\:group:->users-groups" \ "($help)--userland-proxy[Use userland proxy for loopback traffic]" \ - "($help)--userland-proxy-path=[Path to the userland proxy binary]:binary:_files" && ret=0 + "($help)--userland-proxy-path=[Path to the userland proxy binary]:binary:_files" \ + "($help)--validate[Validate daemon configuration and exit]" && ret=0 case $state in (cluster-store) diff --git a/plugins/emacs/emacs.plugin.zsh b/plugins/emacs/emacs.plugin.zsh index 0b602d12a..027c7550f 100644 --- a/plugins/emacs/emacs.plugin.zsh +++ b/plugins/emacs/emacs.plugin.zsh @@ -9,57 +9,55 @@ # - You can share opened buffered across opened frames. # - Configuration changes made at runtime are applied to all frames. +# Require emacs version to be minimum 24 +autoload -Uz is-at-least +is-at-least 24 "${${(Az)"$(emacsclient --version 2>/dev/null)"}[2]}" || return 0 -if "$ZSH/tools/require_tool.sh" emacsclient 24 2>/dev/null ; then - export EMACS_PLUGIN_LAUNCHER="$ZSH/plugins/emacs/emacsclient.sh" +# Path to custom emacsclient launcher +export EMACS_PLUGIN_LAUNCHER="${0:A:h}/emacsclient.sh" - # set EDITOR if not already defined. - export EDITOR="${EDITOR:-${EMACS_PLUGIN_LAUNCHER}}" +# set EDITOR if not already defined. +export EDITOR="${EDITOR:-${EMACS_PLUGIN_LAUNCHER}}" - alias emacs="$EMACS_PLUGIN_LAUNCHER --no-wait" - alias e=emacs - # open terminal emacsclient - alias te="$EMACS_PLUGIN_LAUNCHER -nw" +alias emacs="$EMACS_PLUGIN_LAUNCHER --no-wait" +alias e=emacs +# open terminal emacsclient +alias te="$EMACS_PLUGIN_LAUNCHER -nw" - # same than M-x eval but from outside Emacs. - alias eeval="$EMACS_PLUGIN_LAUNCHER --eval" - # create a new X frame - alias eframe='emacsclient --alternate-editor "" --create-frame' +# same than M-x eval but from outside Emacs. +alias eeval="$EMACS_PLUGIN_LAUNCHER --eval" +# create a new X frame +alias eframe='emacsclient --alternate-editor "" --create-frame' - # Emacs ANSI Term tracking - if [[ -n "$INSIDE_EMACS" ]]; then - chpwd_emacs() { print -P "\033AnSiTc %d"; } - print -P "\033AnSiTc %d" # Track current working directory - print -P "\033AnSiTu %n" # Track username +# Emacs ANSI Term tracking +if [[ -n "$INSIDE_EMACS" ]]; then + chpwd_emacs() { print -P "\033AnSiTc %d"; } + print -P "\033AnSiTc %d" # Track current working directory + print -P "\033AnSiTu %n" # Track username - # add chpwd hook - autoload -Uz add-zsh-hook - add-zsh-hook chpwd chpwd_emacs - fi - - # Write to standard output the path to the file - # opened in the current buffer. - function efile { - local cmd="(buffer-file-name (window-buffer))" - "$EMACS_PLUGIN_LAUNCHER" --eval "$cmd" | tr -d \" - } - - # Write to standard output the directory of the file - # opened in the the current buffer - function ecd { - local cmd="(let ((buf-name (buffer-file-name (window-buffer)))) - (if buf-name (file-name-directory buf-name)))" - - local dir="$($EMACS_PLUGIN_LAUNCHER --eval $cmd | tr -d \")" - if [ -n "$dir" ] ;then - echo "$dir" - else - echo "can not deduce current buffer filename." >/dev/stderr - return 1 - fi - } + # add chpwd hook + autoload -Uz add-zsh-hook + add-zsh-hook chpwd chpwd_emacs fi -## Local Variables: -## mode: sh -## End: +# Write to standard output the path to the file +# opened in the current buffer. +function efile { + local cmd="(buffer-file-name (window-buffer))" + local file="$("$EMACS_PLUGIN_LAUNCHER" --eval "$cmd" | tr -d \")" + + if [[ -z "$file" ]]; then + echo "Can't deduce current buffer filename." >&2 + return 1 + fi + + echo "$file" +} + +# Write to standard output the directory of the file +# opened in the the current buffer +function ecd { + local file + file="$(efile)" || return $? + echo "${file:h}" +} diff --git a/plugins/emacs/emacsclient.sh b/plugins/emacs/emacsclient.sh index 04a2c2afd..25efe0d68 100755 --- a/plugins/emacs/emacsclient.sh +++ b/plugins/emacs/emacsclient.sh @@ -1,29 +1,38 @@ #!/bin/sh -_emacsfun() -{ - # get list of emacs frames. - frameslist=`emacsclient --alternate-editor '' --eval '(frame-list)' 2>/dev/null | egrep -o '(frame)+'` +emacsfun() { + local cmd frames - if [ "$(echo "$frameslist" | sed -n '$=')" -ge 2 ] ;then - # prevent creating another X frame if there is at least one present. - emacsclient --alternate-editor "" "$@" - else - # Create one if there is no X window yet. - emacsclient --alternate-editor "" --create-frame "$@" - fi + # Build the Emacs Lisp command to check for suitable frames + # See https://www.gnu.org/software/emacs/manual/html_node/elisp/Frames.html#index-framep + case "$*" in + *-t*|*--tty*|*-nw*) cmd="(memq 't (mapcar 'framep (frame-list)))" ;; # if != nil, there are tty frames + *) cmd="(delete 't (mapcar 'framep (frame-list)))" ;; # if != nil, there are graphical terminals (x, w32, ns) + esac + + # Check if there are suitable frames + frames="$(emacsclient -a '' -n -e "$cmd" 2>/dev/null)" + + # Only create another X frame if there isn't one present + if [ -z "$frames" -o "$frames" = nil ]; then + emacsclient --alternate-editor "" --create-frame "$@" + return $? + fi + + emacsclient --alternate-editor "" "$@" } - -# adopted from https://github.com/davidshepherd7/emacs-read-stdin/blob/master/emacs-read-stdin.sh +# Adapted from https://github.com/davidshepherd7/emacs-read-stdin/blob/master/emacs-read-stdin.sh # If the second argument is - then write stdin to a tempfile and open the # tempfile. (first argument will be `--no-wait` passed in by the plugin.zsh) -if [ "$#" -ge "2" -a "$2" = "-" ] -then - tempfile="$(mktemp --tmpdir emacs-stdin-$USERNAME.XXXXXXX 2>/dev/null \ - || mktemp -t emacs-stdin-$USERNAME)" # support BSD mktemp - cat - > "$tempfile" - _emacsfun --no-wait $tempfile -else - _emacsfun "$@" +if [ $# -ge 2 -a "$2" = "-" ]; then + # Create a tempfile to hold stdin + tempfile="$(mktemp --tmpdir emacs-stdin-$USERNAME.XXXXXXX 2>/dev/null \ + || mktemp -t emacs-stdin-$USERNAME)" # support BSD mktemp + # Redirect stdin to the tempfile + cat - > "$tempfile" + # Reset $2 to the tempfile so that "$@" works as expected + set -- "$1" "$tempfile" "${@:3}" fi + +emacsfun "$@" diff --git a/plugins/fnm/.gitignore b/plugins/fnm/.gitignore deleted file mode 100644 index 0b2bc9ab7..000000000 --- a/plugins/fnm/.gitignore +++ /dev/null @@ -1,2 +0,0 @@ -_fnm - diff --git a/plugins/fnm/fnm.plugin.zsh b/plugins/fnm/fnm.plugin.zsh index 5ce558dcb..c161b27cd 100644 --- a/plugins/fnm/fnm.plugin.zsh +++ b/plugins/fnm/fnm.plugin.zsh @@ -1,12 +1,23 @@ -# COMPLETION FUNCTION if (( $+commands[fnm] )); then - if [[ ! -f $ZSH_CACHE_DIR/fnm_version ]] \ - || [[ "$(fnm --version)" != "$(< "$ZSH_CACHE_DIR/fnm_version")" ]] \ - || [[ ! -f $ZSH/plugins/fnm/_fnm ]]; then - fnm completions --shell=zsh > $ZSH/plugins/fnm/_fnm - fnm --version > $ZSH_CACHE_DIR/fnm_version + # remove old generated completion file + command rm -f "${0:A:h}/_fnm" + + ver="$(fnm --version)" + ver_file="$ZSH_CACHE_DIR/fnm_version" + comp_file="$ZSH_CACHE_DIR/completions/_fnm" + + mkdir -p "${comp_file:h}" + (( ${fpath[(Ie)${comp_file:h}]} )) || fpath=("${comp_file:h}" $fpath) + + if [[ ! -f "$comp_file" || ! -f "$ver_file" || "$ver" != "$(< "$ver_file")" ]]; then + fnm completions --shell=zsh >| "$comp_file" + echo "$ver" >| "$ver_file" fi + + declare -A _comps autoload -Uz _fnm _comps[fnm]=_fnm + + unset ver ver_file comp_file fi diff --git a/plugins/gh/.gitignore b/plugins/gh/.gitignore deleted file mode 100644 index fa1244ab5..000000000 --- a/plugins/gh/.gitignore +++ /dev/null @@ -1 +0,0 @@ -_gh diff --git a/plugins/gh/gh.plugin.zsh b/plugins/gh/gh.plugin.zsh index 8e055ec35..3e4cdee5e 100644 --- a/plugins/gh/gh.plugin.zsh +++ b/plugins/gh/gh.plugin.zsh @@ -1,13 +1,24 @@ # Autocompletion for the GitHub CLI (gh). - if (( $+commands[gh] )); then - if [[ ! -r "$ZSH_CACHE_DIR/gh_version" \ - || "$(gh --version)" != "$(< "$ZSH_CACHE_DIR/gh_version")" - || ! -f "$ZSH/plugins/gh/_gh" ]]; then - gh completion --shell zsh > $ZSH/plugins/gh/_gh - gh --version > $ZSH_CACHE_DIR/gh_version + # remove old generated completion file + command rm -f "${0:A:h}/_gh" + + ver="$(gh --version)" + ver_file="$ZSH_CACHE_DIR/gh_version" + comp_file="$ZSH_CACHE_DIR/completions/_gh" + + mkdir -p "${comp_file:h}" + (( ${fpath[(Ie)${comp_file:h}]} )) || fpath=("${comp_file:h}" $fpath) + + if [[ ! -f "$comp_file" || ! -f "$ver_file" || "$ver" != "$(< "$ver_file")" ]]; then + gh completion --shell zsh >| "$comp_file" + echo "$ver" >| "$ver_file" fi + + declare -A _comps autoload -Uz _gh _comps[gh]=_gh + + unset ver ver_file comp_file fi diff --git a/plugins/golang/README.md b/plugins/golang/README.md index 0a1b43c30..af2c4dff9 100644 --- a/plugins/golang/README.md +++ b/plugins/golang/README.md @@ -19,6 +19,7 @@ plugins=(... golang) | gof | `go fmt` | Gofmt formats (aligns and indents) Go programs. | | gofa | `go fmt ./...` | Run go fmt for all packages in current directory, recursively | | gog | `go get` | Downloads packages and then installs them to $GOPATH | +| gog | `go get ./...` | Installs all dependencies in current directory, recursively | | goi | `go install` | Compiles and installs packages to $GOPATH | | gol | `go list` | Lists Go packages | | gom | `go mod` | Access to operations on modules | @@ -27,4 +28,5 @@ plugins=(... golang) | gops | `cd $GOPATH/src` | Takes you to $GOPATH/src | | gor | `go run` | Compiles and runs your code | | got | `go test` | Runs tests | +| gota | `go test ./...` | Runs tests in all subdirectories | | gov | `go vet` | Vet examines Go source code and reports suspicious constructs | diff --git a/plugins/golang/golang.plugin.zsh b/plugins/golang/golang.plugin.zsh index 398bd966f..fce663fd6 100644 --- a/plugins/golang/golang.plugin.zsh +++ b/plugins/golang/golang.plugin.zsh @@ -263,6 +263,7 @@ alias god='go doc' alias gof='go fmt' alias gofa='go fmt ./...' alias gog='go get' +alias goga='go get ./...' alias goi='go install' alias gol='go list' alias gom='go mod' @@ -271,4 +272,5 @@ alias gopb='cd $GOPATH/bin' alias gops='cd $GOPATH/src' alias gor='go run' alias got='go test' +alias gota='go test ./...' alias gov='go vet' diff --git a/plugins/jsontools/README.md b/plugins/jsontools/README.md index 1fa2b8eed..6a2740014 100644 --- a/plugins/jsontools/README.md +++ b/plugins/jsontools/README.md @@ -17,32 +17,63 @@ Usage is simple... just take your json data and pipe it into the appropriate jso - `urlencode_json`: returns a url encoded string for the given json. - `urldecode_json`: returns decoded json for the given url encoded string. +### Supports NDJSON (Newline Delimited JSON) + +The plugin also supports [NDJSON](http://ndjson.org/) input, which means all functions +have an alternative function that reads and processes the input line by line. These +functions have the same name except using `ndjson` instead of `json`: + +> `pp_ndjson`, `is_ndjson`, `urlencode_ndjson`, `urldecode_ndjson`. + ### Examples - **pp_json**: -```sh +```console # curl json data and pretty print the results curl https://coderwall.com/bobwilliams.json | pp_json ``` - **is_json**: -```sh -# Validate if file's content conforms to a valid JSON schema -less data.json | is_json +```console +# validate if file's content conforms to a valid JSON schema +$ is_json < data.json +true +# shows true / false and returns the proper exit code +$ echo $? +0 ``` - **urlencode_json**: -```sh +```console # json data directly from the command line -echo '{"b":2, "a":1}' | urlencode_json +$ echo '{"b":2, "a":1}' | urlencode_json +%7B%22b%22:2,%20%22a%22:1%7D ``` - **urldecode_json**: -```sh +```console # url encoded string to decode -echo '%7B%22b%22:2,%20%22a%22:1%7D%0A' | urldecode_json +$ echo '%7B%22b%22:2,%20%22a%22:1%7D' | urldecode_json +{"b":2, "a":1} +``` + +- **pp_ndjson**: + +```console +# echo two separate json objects and pretty print both +$ echo '{"a": "b"}\n{"c": [1,2,3]}' | pp_ndjson +{ + "a": "b" +} +{ + "c": [ + 1, + 2, + 3 + ] +} ``` diff --git a/plugins/jsontools/jsontools.plugin.zsh b/plugins/jsontools/jsontools.plugin.zsh index 912c83509..ed45cfa8e 100644 --- a/plugins/jsontools/jsontools.plugin.zsh +++ b/plugins/jsontools/jsontools.plugin.zsh @@ -1,42 +1,113 @@ # JSON Tools # Adds command line aliases useful for dealing with JSON -if [[ $(whence $JSONTOOLS_METHOD) = "" ]]; then - JSONTOOLS_METHOD="" +# Check that user-defined method is installed +if [[ -n "$JSONTOOLS_METHOD" ]]; then + (( $+commands[$JSONTOOLS_METHOD] )) || unset JSONTOOLS_METHOD fi -if [[ $(whence node) != "" && ( "x$JSONTOOLS_METHOD" = "x" || "x$JSONTOOLS_METHOD" = "xnode" ) ]]; then - alias pp_json='xargs -0 node -e "console.log(JSON.stringify(JSON.parse(process.argv[1]), null, 4));"' - alias is_json='xargs -0 node -e "try {json = JSON.parse(process.argv[1]);} catch (e) { console.log(false); json = null; } if(json) { console.log(true); }"' - alias urlencode_json='xargs -0 node -e "console.log(encodeURIComponent(process.argv[1]))"' - alias urldecode_json='xargs -0 node -e "console.log(decodeURIComponent(process.argv[1]))"' -elif [[ $(whence python) != "" && ( "x$JSONTOOLS_METHOD" = "x" || "x$JSONTOOLS_METHOD" = "xpython" ) ]]; then - alias pp_json='python -c "import sys; del sys.path[0]; import runpy; runpy._run_module_as_main(\"json.tool\")"' - alias is_json='python -c " -import sys; del sys.path[0]; -import json; -try: - json.loads(sys.stdin.read()) -except ValueError, e: - print False -else: - print True -sys.exit(0)"' - alias urlencode_json='python -c " -import sys; del sys.path[0]; -import urllib, json; -print urllib.quote_plus(sys.stdin.read()) -sys.exit(0)"' - alias urldecode_json='python -c " -import sys; del sys.path[0]; -import urllib, json; -print urllib.unquote_plus(sys.stdin.read()) -sys.exit(0)"' -elif [[ $(whence ruby) != "" && ( "x$JSONTOOLS_METHOD" = "x" || "x$JSONTOOLS_METHOD" = "xruby" ) ]]; then - alias pp_json='ruby -e "require \"json\"; require \"yaml\"; puts JSON.parse(STDIN.read).to_yaml"' - alias is_json='ruby -e "require \"json\"; begin; JSON.parse(STDIN.read); puts true; rescue Exception => e; puts false; end"' - alias urlencode_json='ruby -e "require \"uri\"; puts URI.escape(STDIN.read)"' - alias urldecode_json='ruby -e "require \"uri\"; puts URI.unescape(STDIN.read)"' +# If method undefined, find the first one that is installed +if [[ ! -v JSONTOOLS_METHOD ]]; then + for JSONTOOLS_METHOD in node python ruby; do + # If method found, break out of loop + (( $+commands[$JSONTOOLS_METHOD] )) && break + # Otherwise unset the variable + unset JSONTOOLS_METHOD + done + + # If no methods were found, exit the plugin + [[ -v JSONTOOLS_METHOD ]] || return 1 fi +# Define json tools for each method +case "$JSONTOOLS_METHOD" in + node) + # node doesn't make it easy to deal with stdin, so we pass it as an argument with xargs -0 + function pp_json() { + xargs -0 node -e 'console.log(JSON.stringify(JSON.parse(process.argv[1]), null, 4));' + } + function is_json() { + xargs -0 node -e ' + try { + json = JSON.parse(process.argv[1]); + console.log("true"); + process.exit(0); + } catch (e) { + console.log("false"); + process.exit(1); + } + ' + } + function urlencode_json() { + xargs -0 node -e "console.log(encodeURIComponent(process.argv[1]))" + } + function urldecode_json() { + xargs -0 node -e "console.log(decodeURIComponent(process.argv[1]))" + } + ;; + python) + function pp_json() { + python -c 'import sys; del sys.path[0]; import runpy; runpy._run_module_as_main("json.tool")' + } + function is_json() { + python -c ' +import sys; del sys.path[0]; +import json +try: + json.loads(sys.stdin.read()) + print("true"); sys.exit(0) +except ValueError: + print("false"); sys.exit(1) + ' + } + function urlencode_json() { + python -c ' +import sys; del sys.path[0]; +from urllib.parse import quote_plus +print(quote_plus(sys.stdin.read())) + ' + } + function urldecode_json() { + python -c ' +import sys; del sys.path[0]; +from urllib.parse import unquote_plus +print(unquote_plus(sys.stdin.read())) + ' + } + ;; + ruby) + function pp_json() { + ruby -e ' + require "json" + require "yaml" + puts JSON.parse(STDIN.read).to_yaml + ' + } + function is_json() { + ruby -e ' + require "json" + begin + puts !!JSON.parse(STDIN.read); exit(0) + rescue JSON::ParserError + puts false; exit(1) + end + ' + } + function urlencode_json() { + ruby -e 'require "cgi"; puts CGI.escape(STDIN.read)' + } + function urldecode_json() { + ruby -e 'require "cgi"; puts CGI.unescape(STDIN.read)' + } + ;; +esac unset JSONTOOLS_METHOD + +## Add NDJSON support + +function {pp,is,urlencode,urldecode}_ndjson() { + local json jsonfunc="${0//ndjson/json}" + while read -r json; do + $jsonfunc <<< "$json" + done +} diff --git a/plugins/juju/README.md b/plugins/juju/README.md new file mode 100644 index 000000000..49f8b0d47 --- /dev/null +++ b/plugins/juju/README.md @@ -0,0 +1,117 @@ +# juju plugin + +This plugin provides useful aliases and functions for [juju](https://juju.is/) (for TAB completion, +refer to the [official repo](https://github.com/juju/juju/blob/develop/etc/bash_completion.d/juju)). + +To use this plugin, add `juju` to the plugins array in your zshrc file. + +```zsh +plugins=(... juju) +``` + +## Aliases + +Naming convention: + +- `!` suffix: `--force --no-wait -y`. +- `ds` suffix: `--destroy-storage`. + +### General + +| Alias | Command | Description | +|--------|---------------------------------------------|--------------------------------------------------------| +| `jdl` | `juju debug-log --ms` | Display log, with millisecond resolution | +| `jdlr` | `juju debug-log --ms --replay` | Replay entire log | +| `jh` | `juju help` | Show help on a command or other topic | +| `jssl` | `juju juju show-status-log` | Output past statuses for the specified entity | +| `jstj` | `juju status --format=json` | Show status in json format (more detailed) | +| `jst` | `juju status --relations --storage --color` | Show status, including relations and storage, in color | + +### Bootstrap + +| Alias | Command | Description | +|-------|---------------------------|-------------------------------------------| +| `jb` | `juju bootstrap` | Initializing a Juju cloud environment | +| `jbm` | `juju bootstrap microk8s` | Initializing a MicroK8s cloud environment | + +### Controller + +| Alias | Command | Description | +|----------|---------------------------------------------------------------------------------------|-------------------------------------------------------------------| +| `jdc` | `juju destroy-controller --destroy-all-models` | Destroy a controller | +| `jdc!` | `juju destroy-controller --destroy-all-models --force --no-wait -y` | Destroy a controller | +| `jdcds` | `juju destroy-controller --destroy-all-models --destroy-storage` | Destroy a controller and associated storage | +| `jdcds!` | `juju destroy-controller --destroy-all-models --destroy-storage --force --no-wait -y` | Destroy a controller and associated storage | +| `jkc` | `juju kill-controller -y -t 0` | Forcibly terminate all associated resources for a Juju controller | +| `jsw` | `juju switch` | Select or identify the current controller and model | + +### Model + +| Alias | Command | Description | +|----------|-------------------------------------------------------------|-------------------------------------------------------| +| `jam` | `juju add-model` | Add a hosted model | +| `jdm` | `juju destroy-model` | Non-recoverable, complete removal of a model | +| `jdm!` | `juju destroy-model --force --no-wait -y` | Non-recoverable, complete removal of a model | +| `jdmds` | `juju destroy-model --destroy-storage` | Non-recoverable, complete removal of a model | +| `jdmds!` | `juju destroy-model --destroy-storage --force --no-wait -y` | Non-recoverable, complete removal of a model | +| `jmc` | `juju model-config` | Display or set configuration values on a model | +| `jm` | `juju models` | List models a user can access on a controller | +| `jshm` | `juju show-model` | Show information about the current or specified model | +| `jsw` | `juju switch` | Select or identify the current controller and model | + +### Application / unit + +| Alias | Command | Description | +|----------|---------------------------------------------------------------|---------------------------------------------------------------------------| +| `jc` | `juju config` | Get, set, or reset configuration for a deployed application | +| `jde` | `juju deploy --channel=edge` | Deploy a new application or bundle from the edge channel | +| `jd` | `juju deploy` | Deploy a new application or bundle | +| `jra` | `juju run-action` | Queue an action for execution | +| `jraw` | `juju run-action --wait` | Queue an action for execution and wait for results, with optional timeout | +| `jrm` | `juju remove-application` | Remove application | +| `jrm!` | `juju remove-application --force --no-wait` | Remove application forcefully | +| `jrmds` | `juju remove-application --destroy-storage` | Remove application and destroy attached storage | +| `jrmds!` | `juju remove-application --destroy-storage --force --no-wait` | Remove application forcefully, destroying attached storage | +| `jrp` | `juju refresh --path` | Upgrade charm from local charm file | +| `jsa` | `juju scale-application` | Set the desired number of application units | +| `jsh` | `juju ssh` | Initiate an SSH session or execute a command on a Juju target | +| `jshc` | `juju ssh --container` | Initiate an SSH session or execute a command on a given container | +| `jsu` | `juju show-unit` | Displays information about a unit | + +### Storage + +| Alias | Command | Description | +|---------|-------------------------------|-------------------------------------------------| +| `jrs` | `juju remove-storage` | Remove storage | +| `jrs!` | `juju remove-storage --force` | Remove storage even if it is currently attached | + +### Relation + +| Alias | Command | Description | +|-----------|--------------------------------|-------------------------------------------------------------------| +| `jrel` | `juju relate` | Relate two applications | +| `jrmrel` | `juju remove-relation` | Remove an existing relation between two applications. | +| `jrmrel!` | `juju remove-relation --force` | Remove an existing relation between two applications, forcefully. | + +### Cross-model relation (CMR) + +| Alias | Command | Description | +|----------|--------------------|----------------------------------------------------------------| +| `jex` | `juju expose` | Make an application publicly available over the network | +| `jof` | `juju offer` | Offer application endpoints for use in other models | +| `jcon` | `juju consume` | Add a remote offer to the model | +| `jrmsas` | `juju remove-saas` | Remove consumed applications (SAAS) from the model | +| `junex` | `juju unexpose` | Remove public availability over the network for an application | + +### Bundle + +| Alias | Command | Description | +|-------|----------------------|-------------------------------------------------------------| +| `jeb` | `juju export-bundle` | Export the current model configuration as a reusable bundle | + +## Functions + +- `jaddr [unit_num]`: display app or unit IP address. +- `jreld `: display app and unit relation data. +- `wjst [interval_secs] [args_for_watch]`: watch juju status, with optional interval + (default: 5s); you may pass additional arguments to `watch`. diff --git a/plugins/juju/juju.plugin.zsh b/plugins/juju/juju.plugin.zsh new file mode 100644 index 000000000..07f15b392 --- /dev/null +++ b/plugins/juju/juju.plugin.zsh @@ -0,0 +1,127 @@ +# ---------------------------------------------------------- # +# Aliases and functions for juju (https://juju.is) # +# ---------------------------------------------------------- # + +# Load TAB completions +# You need juju's bash completion script installed. By default bash-completion's +# location will be used (i.e. pkg-config --variable=completionsdir bash-completion). +completion_file="$(pkg-config --variable=completionsdir bash-completion 2>/dev/null)/juju" || \ + completion_file="/usr/share/bash-completion/completions/juju" +[[ -f "$completion_file" ]] && source "$completion_file" +unset completion_file + +# ---------------------------------------------------------- # +# Aliases (in alphabetic order) # +# # +# Generally, # +# - `!` means --force --no-wait -y # +# - `ds` suffix means --destroy-storage # +# ---------------------------------------------------------- # +alias jam="juju add-model --config logging-config=\"=WARNING; unit=DEBUG\"\ + --config update-status-hook-interval=\"60m\"" +alias jb='juju bootstrap' +alias jbm='juju bootstrap microk8s' +alias jc='juju config' +alias jdc='juju destroy-controller --destroy-all-models' +alias 'jdc!'='juju destroy-controller --destroy-all-models --force --no-wait -y' +alias jdcds='juju destroy-controller --destroy-all-models --destroy-storage' +alias 'jdcds!'='juju destroy-controller --destroy-all-models --destroy-storage --force --no-wait -y' +alias jdm='juju destroy-model' +alias 'jdm!'='juju destroy-model --force --no-wait -y' +alias jdmds='juju destroy-model --destroy-storage' +alias 'jdmds!'='juju destroy-model --destroy-storage --force --no-wait -y' +alias jde='juju deploy --channel=edge' +alias jd='juju deploy' +alias jdl='juju debug-log --ms' +alias jdlr='juju debug-log --ms --replay' +alias jcon='juju consume' +alias jeb='juju export-bundle' +alias jex='juju expose' +alias jh='juju help' +alias jkc='juju kill-controller -y -t 0' +alias jm='juju models' +alias jmc='juju model-config' +alias jof='juju offer' +alias jra='juju run-action' +alias jraw='juju run-action --wait' +alias jrel='juju relate' +alias jrm='juju remove-application' +alias 'jrm!'='juju remove-application --force --no-wait' +alias jrmds='juju remove-application --destroy-storage' +alias 'jrmds!'='juju remove-application --destroy-storage --force --no-wait' +alias jrmrel='juju remove-relation' +alias 'jrmrel!'='juju remove-relation --force' +alias jrmsas='juju remove-saas' +alias jrp='juju refresh --path' +alias jrs='juju remove-storage' +alias 'jrs!'='juju remove-storage --force' +alias jsa='juju scale-application' +alias jsh='juju ssh' +alias jshc='juju ssh --container' +alias jshm='juju show-model' +alias jssl='juju show-status-log' +alias jstj='juju status --format=json' +alias jst='juju status --relations --storage --color' +alias jsu='juju show-unit' +alias jsw='juju switch' + +# ---------------------------------------------------------- # +# Functions (in alphabetic order) # +# ---------------------------------------------------------- # + +# Get app or unit address +jaddr() { + # $1 = app name + # $2 = unit number (optional) + if (( ! ${+commands[jq]} )); then + echo "jq is required but could not be found." >&2 + return 1 + fi + + if [[ $# -eq 1 ]]; then + # Get app address + juju status "$1" --format=json \ + | jq -r ".applications.\"$1\".address" + elif [[ $# -eq 2 ]]; then + # Get unit address + juju status "$1/$2" --format=json \ + | jq -r ".applications.\"$1\".units.\"$1/$2\".address" + else + echo "Invalid number of arguments." + echo "Usage: jaddr []" + echo "Example: jaddr karma" + echo "Example: jaddr karma 0" + return 1 + fi +} + +# Display app and unit relation data +jreld() { + # $1 = relation name + # $2 = app name + # $3 = unit number + if [[ $# -ne 3 ]]; then + echo "Invalid number of arguments." + echo "Usage: jreld " + echo "Example: jreld karma-dashboard alertmanager 0" + return 1 + fi + + local relid="$(juju run "relation-ids $1" --unit $2/$3)" + if [[ -z "$relid" ]]; then + return 1 + fi + + echo "App data:" + juju run "relation-get -r $relid --app - $2" --unit $2/$3 + echo + echo "Unit data:" + juju run "relation-get -r $relid - $2" --unit $2/$3 +} + +# Watch juju status, with optional interval (default: 5 sec) +wjst() { + local interval="${1:-5}" + shift $(( $# > 0 )) + watch -n "$interval" --color juju status --relations --storage --color "$@" +} diff --git a/plugins/kubectx/README.md b/plugins/kubectx/README.md index 9a1df2617..98f1cf032 100644 --- a/plugins/kubectx/README.md +++ b/plugins/kubectx/README.md @@ -17,7 +17,7 @@ One can rename default context name for better readability. _Example_. Add to **.zshrc**: ``` -kubectx_mapping[minikube] = "mini" +kubectx_mapping[minikube]="mini" kubectx_mapping[context_name_from_kubeconfig]="$emoji[wolf_face]" kubectx_mapping[production_cluster]="%{$fg[yellow]%}prod!%{$reset_color%}" ``` diff --git a/plugins/lando/lando.plugin.zsh b/plugins/lando/lando.plugin.zsh index aa74c9924..af53e7e5a 100644 --- a/plugins/lando/lando.plugin.zsh +++ b/plugins/lando/lando.plugin.zsh @@ -8,6 +8,7 @@ function artisan \ drush \ gulp \ npm \ + php \ wp \ yarn { if checkForLandoFile; then diff --git a/plugins/osx/osx.plugin.zsh b/plugins/osx/osx.plugin.zsh index 7842e9f73..5455d7c5f 100644 --- a/plugins/osx/osx.plugin.zsh +++ b/plugins/osx/osx.plugin.zsh @@ -219,7 +219,8 @@ function quick-look() { } function man-preview() { - man -t "$@" | open -f -a Preview + # Don't let Preview.app steal focus if the man page doesn't exist + man -w "$@" &>/dev/null && man -t "$@" | open -f -a Preview || man "$@" } compdef _man man-preview diff --git a/plugins/rustup/.gitignore b/plugins/rustup/.gitignore deleted file mode 100644 index ad38ae3bf..000000000 --- a/plugins/rustup/.gitignore +++ /dev/null @@ -1 +0,0 @@ -_rustup diff --git a/plugins/rustup/rustup.plugin.zsh b/plugins/rustup/rustup.plugin.zsh index c7a9b3060..c6efc1b13 100644 --- a/plugins/rustup/rustup.plugin.zsh +++ b/plugins/rustup/rustup.plugin.zsh @@ -1,12 +1,22 @@ -# COMPLETION FUNCTION if (( $+commands[rustup] )); then - if [[ ! -f $ZSH_CACHE_DIR/rustup_version ]] \ - || [[ "$(rustup --version 2> /dev/null)" \ - != "$(< "$ZSH_CACHE_DIR/rustup_version")" ]] \ - || [[ ! -f $ZSH/plugins/rustup/_rustup ]]; then - rustup completions zsh > $ZSH/plugins/rustup/_rustup - rustup --version 2> /dev/null > $ZSH_CACHE_DIR/rustup_version + # remove old generated completion file + command rm -f "${0:A:h}/_rustup" + + ver="$(rustup --version 2>/dev/null)" + ver_file="$ZSH_CACHE_DIR/rustup_version" + comp_file="$ZSH_CACHE_DIR/completions/_rustup" + + mkdir -p "${comp_file:h}" + (( ${fpath[(Ie)${comp_file:h}]} )) || fpath=("${comp_file:h}" $fpath) + + if [[ ! -f "$comp_file" || ! -f "$ver_file" || "$ver" != "$(< "$ver_file")" ]]; then + rustup completions zsh >| "$comp_file" + echo "$ver" >| "$ver_file" fi + + declare -A _comps autoload -Uz _rustup _comps[rustup]=_rustup + + unset ver ver_file comp_file fi diff --git a/plugins/ssh-agent/ssh-agent.plugin.zsh b/plugins/ssh-agent/ssh-agent.plugin.zsh index c2b9546a2..2d7d8a2a0 100644 --- a/plugins/ssh-agent/ssh-agent.plugin.zsh +++ b/plugins/ssh-agent/ssh-agent.plugin.zsh @@ -96,24 +96,7 @@ else _start_agent fi -() { - emulate -L zsh - - command mkdir "$ZSH_CACHE_DIR/ssh-agent.lock" 2>/dev/null || return - - trap " - ret=\$? - - command rm -rf '$ZSH_CACHE_DIR/ssh-agent.lock' - unset agent_forwarding ssh_env_cache - unfunction _start_agent _add_identities 2>/dev/null - - return \$ret - " EXIT INT QUIT - - _add_identities - -} +_add_identities unset agent_forwarding ssh_env_cache unfunction _start_agent _add_identities diff --git a/plugins/vi-mode/README.md b/plugins/vi-mode/README.md index b59d5f279..46bb6d070 100644 --- a/plugins/vi-mode/README.md +++ b/plugins/vi-mode/README.md @@ -64,7 +64,7 @@ NOTE: some of these key bindings are set by zsh by default when using a vi-mode - `vv` : Edit current command line in Vim -NOTE: this used to be bound to `v`. That is now the default (`visual-mode`) +NOTE: this used to be bound to `v`. That is now the default (`visual-mode`). ### Movement @@ -107,3 +107,21 @@ NOTE: this used to be bound to `v`. That is now the default (`visual-mode`) - `R` : Enter replace mode: Each character replaces existing one - `x` : Delete `count` characters under and after the cursor - `X` : Delete `count` characters before the cursor + +## Known issues + +### Low `$KEYTIMEOUT` + +A low `$KEYTIMEOUT` value (< 15) means that key bindings that need multiple characters, +like `vv`, will be very difficult to trigger. `$KEYTIMEOUT` controls the number of +milliseconds that must pass before a key press is read and the appropriate key binding +is triggered. For multi-character key bindings, the key presses need to happen before +the timeout is reached, so on low timeouts the key press happens too slow, and therefore +another key binding is triggered. + +We recommend either setting `$KEYTIMEOUT` to a higher value, or remapping the key bindings +that you want to trigger to a keyboard sequence. For example: + +```zsh +bindkey -M vicmd 'V' edit-command-line # this remaps `vv` to `V` (but overrides `visual-mode`) +``` diff --git a/plugins/vim-interaction/vim-interaction.plugin.zsh b/plugins/vim-interaction/vim-interaction.plugin.zsh index 53ec453e8..b73f9b4da 100644 --- a/plugins/vim-interaction/vim-interaction.plugin.zsh +++ b/plugins/vim-interaction/vim-interaction.plugin.zsh @@ -4,8 +4,7 @@ # Derek Wyatt (derek@{myfirstnamemylastname}.org # -function callvim -{ +function callvim { if [[ $# == 0 ]]; then cat <} == $after ]]; then - after="$after" - fi - if [[ ${before#:} != $before && ${before%} == $before ]]; then - before="$before" - fi - local files - if [[ $# -gt 0 ]]; then - # absolute path of files resolving symlinks (:A) and quoting special chars (:q) - files=':args! '"${@:A:q}" - fi + + # If before or after commands begin with : and don't end with , append it + [[ ${after} = :* && ${after} != *\ ]] && after+="" + [[ ${before} = :* && ${before} != *\ ]] && before+="" + # Open files passed (:A means abs path resolving symlinks, :q means quoting special chars) + [[ $# -gt 0 ]] && files=':args! '"${@:A:q}" + # Pass the built vim command to gvim cmd="$before$files$after" - gvim --servername "$name" --remote-send "$cmd" - if typeset -f postCallVim > /dev/null; then - postCallVim - fi + + # Run the gvim command + gvim --servername "$name" --remote-send "$cmd" || return $? + + # Run postCallVim if defined (maybe to bring focus to gvim, see README) + (( ! $+functions[postCallVim] )) || postCallVim } alias v=callvim diff --git a/templates/zshrc.zsh-template b/templates/zshrc.zsh-template index 65d5ea65b..4a998c2fc 100644 --- a/templates/zshrc.zsh-template +++ b/templates/zshrc.zsh-template @@ -45,8 +45,9 @@ ZSH_THEME="robbyrussell" # ENABLE_CORRECTION="true" # Uncomment the following line to display red dots whilst waiting for completion. -# Caution: this setting can cause issues with multiline prompts (zsh 5.7.1 and newer seem to work) -# See https://github.com/ohmyzsh/ohmyzsh/issues/5765 +# You can also set it to another string to have that shown instead of the default red dots. +# e.g. COMPLETION_WAITING_DOTS="%F{yellow}waiting...%f" +# Caution: this setting can cause issues with multiline prompts in zsh < 5.7.1 (see #5765) # COMPLETION_WAITING_DOTS="true" # Uncomment the following line if you want to disable marking untracked files diff --git a/themes/half-life.zsh-theme b/themes/half-life.zsh-theme index c79027ed6..c4d785126 100644 --- a/themes/half-life.zsh-theme +++ b/themes/half-life.zsh-theme @@ -7,31 +7,22 @@ # git untracked files modification from Brian Carper: # https://briancarper.net/blog/570/git-info-in-your-zsh-prompt -function virtualenv_info { - [ $VIRTUAL_ENV ] && echo '('`basename $VIRTUAL_ENV`') ' -} -PR_GIT_UPDATE=1 - -setopt prompt_subst - -autoload -U add-zsh-hook -autoload -Uz vcs_info - #use extended color palette if available -if [[ $TERM = *256color* || $TERM = *rxvt* ]]; then - turquoise="%F{81}" - orange="%F{166}" - purple="%F{135}" - hotpink="%F{161}" - limegreen="%F{118}" +if [[ $TERM = (*256color|*rxvt*) ]]; then + turquoise="%{${(%):-"%F{81}"}%}" + orange="%{${(%):-"%F{166}"}%}" + purple="%{${(%):-"%F{135}"}%}" + hotpink="%{${(%):-"%F{161}"}%}" + limegreen="%{${(%):-"%F{118}"}%}" else - turquoise="$fg[cyan]" - orange="$fg[yellow]" - purple="$fg[magenta]" - hotpink="$fg[red]" - limegreen="$fg[green]" + turquoise="%{${(%):-"%F{cyan}"}%}" + orange="%{${(%):-"%F{yellow}"}%}" + purple="%{${(%):-"%F{magenta}"}%}" + hotpink="%{${(%):-"%F{red}"}%}" + limegreen="%{${(%):-"%F{green}"}%}" fi +autoload -Uz vcs_info # enable VCS systems you use zstyle ':vcs_info:*' enable git svn @@ -47,10 +38,10 @@ zstyle ':vcs_info:*:prompt:*' check-for-changes true # %R - repository path # %S - path in the repository PR_RST="%{${reset_color}%}" -FMT_BRANCH=" on %{$turquoise%}%b%u%c${PR_RST}" -FMT_ACTION=" performing a %{$limegreen%}%a${PR_RST}" -FMT_UNSTAGED="%{$orange%} ●" -FMT_STAGED="%{$limegreen%} ●" +FMT_BRANCH=" on ${turquoise}%b%u%c${PR_RST}" +FMT_ACTION=" performing a ${limegreen}%a${PR_RST}" +FMT_UNSTAGED="${orange} ●" +FMT_STAGED="${limegreen} ●" zstyle ':vcs_info:*:prompt:*' unstagedstr "${FMT_UNSTAGED}" zstyle ':vcs_info:*:prompt:*' stagedstr "${FMT_STAGED}" @@ -59,38 +50,44 @@ zstyle ':vcs_info:*:prompt:*' formats "${FMT_BRANCH}" zstyle ':vcs_info:*:prompt:*' nvcsformats "" -function steeef_preexec { - case "$2" in - *git*) - PR_GIT_UPDATE=1 - ;; - *svn*) - PR_GIT_UPDATE=1 - ;; - esac -} -add-zsh-hook preexec steeef_preexec - function steeef_chpwd { - PR_GIT_UPDATE=1 + PR_GIT_UPDATE=1 +} + +function steeef_preexec { + case "$2" in + *git*|*svn*) PR_GIT_UPDATE=1 ;; + esac } -add-zsh-hook chpwd steeef_chpwd function steeef_precmd { - if [[ -n "$PR_GIT_UPDATE" ]] ; then - # check for untracked files or updated submodules, since vcs_info doesn't - if [[ ! -z $(git ls-files --other --exclude-standard 2> /dev/null) ]]; then - PR_GIT_UPDATE=1 - FMT_BRANCH="${PM_RST} on %{$turquoise%}%b%u%c%{$hotpink%} ●${PR_RST}" - else - FMT_BRANCH="${PM_RST} on %{$turquoise%}%b%u%c${PR_RST}" - fi - zstyle ':vcs_info:*:prompt:*' formats "${FMT_BRANCH}" + (( PR_GIT_UPDATE )) || return - vcs_info 'prompt' - PR_GIT_UPDATE= - fi + # check for untracked files or updated submodules, since vcs_info doesn't + if [[ -n "$(git ls-files --other --exclude-standard 2>/dev/null)" ]]; then + PR_GIT_UPDATE=1 + FMT_BRANCH="${PM_RST} on ${turquoise}%b%u%c${hotpink} ●${PR_RST}" + else + FMT_BRANCH="${PM_RST} on ${turquoise}%b%u%c${PR_RST}" + fi + zstyle ':vcs_info:*:prompt:*' formats "${FMT_BRANCH}" + + vcs_info 'prompt' + PR_GIT_UPDATE= } -add-zsh-hook precmd steeef_precmd -PROMPT=$'%{$purple%}%n%{$reset_color%} in %{$limegreen%}%~%{$reset_color%}$(ruby_prompt_info " with%{$fg[red]%} " v g "%{$reset_color%}")$vcs_info_msg_0_%{$orange%} λ%{$reset_color%} ' +# vcs_info running hooks +PR_GIT_UPDATE=1 + +autoload -U add-zsh-hook +add-zsh-hook chpwd steeef_chpwd +add-zsh-hook precmd steeef_precmd +add-zsh-hook preexec steeef_preexec + +# ruby prompt settings +ZSH_THEME_RUBY_PROMPT_PREFIX="with%F{red} " +ZSH_THEME_RUBY_PROMPT_SUFFIX="%{$reset_color%}" +ZSH_THEME_RVM_PROMPT_OPTIONS="v g" + +setopt prompt_subst +PROMPT="${purple}%n%{$reset_color%} in ${limegreen}%~%{$reset_color%}\$(ruby_prompt_info)\$vcs_info_msg_0_${orange} λ%{$reset_color%} " diff --git a/tools/install.sh b/tools/install.sh index cfc2808fe..7704107c8 100755 --- a/tools/install.sh +++ b/tools/install.sh @@ -53,39 +53,133 @@ KEEP_ZSHRC=${KEEP_ZSHRC:-no} command_exists() { - command -v "$@" >/dev/null 2>&1 + command -v "$@" >/dev/null 2>&1 +} + +# The [ -t 1 ] check only works when the function is not called from +# a subshell (like in `$(...)` or `(...)`, so this hack redefines the +# function at the top level to always return false when stdout is not +# a tty. +if [ -t 1 ]; then + is_tty() { + true + } +else + is_tty() { + false + } +fi + +# This function uses the logic from supports-hyperlinks[1][2], which is +# made by Kat Marchán (@zkat) and licensed under the Apache License 2.0. +# [1] https://github.com/zkat/supports-hyperlinks +# [2] https://crates.io/crates/supports-hyperlinks +# +# Copyright (c) 2021 Kat Marchán +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +supports_hyperlinks() { + # $FORCE_HYPERLINK must be set and be non-zero (this acts as a logic bypass) + if [ -n "$FORCE_HYPERLINK" ]; then + [ "$FORCE_HYPERLINK" != 0 ] + return $? + fi + + # If stdout is not a tty, it doesn't support hyperlinks + is_tty || return 1 + + # DomTerm terminal emulator (domterm.org) + if [ -n "$DOMTERM" ]; then + return 0 + fi + + # VTE-based terminals above v0.50 (Gnome Terminal, Guake, ROXTerm, etc) + if [ -n "$VTE_VERSION" ]; then + [ $VTE_VERSION -ge 5000 ] + return $? + fi + + # If $TERM_PROGRAM is set, these terminals support hyperlinks + case "$TERM_PROGRAM" in + Hyper|iTerm.app|terminology|WezTerm) return 0 ;; + esac + + # kitty supports hyperlinks + if [ "$TERM" = xterm-kitty ]; then + return 0 + fi + + # Windows Terminal or Konsole also support hyperlinks + if [ -n "$WT_SESSION" ] || [ -n "$KONSOLE_VERSION" ]; then + return 0 + fi + + return 1 +} + +fmt_link() { + # $1: text, $2: url, $3: fallback mode + if supports_hyperlinks; then + printf '\033]8;;%s\a%s\033]8;;\a\n' "$2" "$1" + return + fi + + case "$3" in + --text) printf '%s\n' "$1" ;; + --url|*) fmt_underline "$2" ;; + esac +} + +fmt_underline() { + is_tty && printf '\033[4m%s\033[24m\n' "$*" || printf '%s\n' "$*" +} + +# shellcheck disable=SC2016 # backtick in single-quote +fmt_code() { + is_tty && printf '`\033[2m%s\033[22m`\n' "$*" || printf '`%s`\n' "$*" } fmt_error() { printf '%sError: %s%s\n' "$BOLD$RED" "$*" "$RESET" >&2 } -fmt_underline() { - printf '\033[4m%s\033[24m\n' "$*" -} - -fmt_code() { - # shellcheck disable=SC2016 # backtic in single-quote - printf '`\033[38;5;247m%s%s`\n' "$*" "$RESET" -} - setup_color() { - # Only use colors if connected to a terminal - if [ -t 1 ]; then - RED=$(printf '\033[31m') - GREEN=$(printf '\033[32m') - YELLOW=$(printf '\033[33m') - BLUE=$(printf '\033[34m') - BOLD=$(printf '\033[1m') - RESET=$(printf '\033[m') - else - RED="" - GREEN="" - YELLOW="" - BLUE="" - BOLD="" - RESET="" - fi + # Only use colors if connected to a terminal + if is_tty; then + RAINBOW=" + $(printf '\033[38;5;196m') + $(printf '\033[38;5;202m') + $(printf '\033[38;5;226m') + $(printf '\033[38;5;082m') + $(printf '\033[38;5;021m') + $(printf '\033[38;5;093m') + $(printf '\033[38;5;163m') + " + RED=$(printf '\033[31m') + GREEN=$(printf '\033[32m') + YELLOW=$(printf '\033[33m') + BLUE=$(printf '\033[34m') + BOLD=$(printf '\033[1m') + RESET=$(printf '\033[m') + else + RAINBOW="" + RED="" + GREEN="" + YELLOW="" + BLUE="" + BOLD="" + RESET="" + fi } setup_ohmyzsh() { @@ -114,6 +208,8 @@ setup_ohmyzsh() { -c fsck.zeroPaddedFilemode=ignore \ -c fetch.fsck.zeroPaddedFilemode=ignore \ -c receive.fsck.zeroPaddedFilemode=ignore \ + -c oh-my-zsh.remote=origin \ + -c oh-my-zsh.branch="$BRANCH" \ --depth=1 --branch "$BRANCH" "$REMOTE" "$ZSH" || { fmt_error "git clone of oh-my-zsh repo failed" exit 1 @@ -157,9 +253,9 @@ setup_zshrc() { sed "/^export ZSH=/ c\\ export ZSH=\"$ZSH\" " "$ZSH/templates/zshrc.zsh-template" > ~/.zshrc-omztemp - mv -f ~/.zshrc-omztemp ~/.zshrc + mv -f ~/.zshrc-omztemp ~/.zshrc - echo + echo } setup_shell() { @@ -241,6 +337,26 @@ EOF echo } +# shellcheck disable=SC2183 # printf string has more %s than arguments ($RAINBOW expands to multiple arguments) +print_success() { + printf '%s %s__ %s %s %s %s %s__ %s\n' $RAINBOW $RESET + printf '%s ____ %s/ /_ %s ____ ___ %s__ __ %s ____ %s_____%s/ /_ %s\n' $RAINBOW $RESET + printf '%s / __ \%s/ __ \ %s / __ `__ \%s/ / / / %s /_ / %s/ ___/%s __ \ %s\n' $RAINBOW $RESET + printf '%s/ /_/ /%s / / / %s / / / / / /%s /_/ / %s / /_%s(__ )%s / / / %s\n' $RAINBOW $RESET + printf '%s\____/%s_/ /_/ %s /_/ /_/ /_/%s\__, / %s /___/%s____/%s_/ /_/ %s\n' $RAINBOW $RESET + printf '%s %s %s %s /____/ %s %s %s %s....is now installed!%s\n' $RAINBOW $GREEN $RESET + printf '\n' + printf '\n' + printf "%s %s %s\n" "Before you scream ${BOLD}${YELLOW}Oh My Zsh!${RESET} look over the" \ + "$(fmt_code "$(fmt_link ".zshrc" "file://$HOME/.zshrc" --text)")" \ + "file to select plugins, themes, and options." + printf '\n' + printf '%s\n' "• Follow us on Twitter: $(fmt_link @ohmyzsh https://twitter.com/ohmyzsh)" + printf '%s\n' "• Join our Discord community: $(fmt_link "Discord server" https://discord.gg/ohmyzsh)" + printf '%s\n' "• Get stickers, t-shirts, coffee mugs and more: $(fmt_link "Planet Argon Shop" https://shop.planetargon.com/collections/oh-my-zsh)" + printf '%s\n' $RESET +} + main() { # Run as unattended if stdin is not a tty if [ ! -t 0 ]; then @@ -291,26 +407,7 @@ EOF setup_zshrc setup_shell - printf %s "$GREEN" - cat <<'EOF' - __ __ - ____ / /_ ____ ___ __ __ ____ _____/ /_ - / __ \/ __ \ / __ `__ \/ / / / /_ / / ___/ __ \ -/ /_/ / / / / / / / / / / /_/ / / /_(__ ) / / / -\____/_/ /_/ /_/ /_/ /_/\__, / /___/____/_/ /_/ - /____/ ....is now installed! - - -EOF - cat <