diff --git a/.github/workflows/tests.yaml b/.github/workflows/tests.yaml index 3ba63363c..e4378bc26 100644 --- a/.github/workflows/tests.yaml +++ b/.github/workflows/tests.yaml @@ -72,6 +72,9 @@ jobs: - name: "gh-r" run: zunit run tests/gh-r.zunit + - name: "ices" + run: zunit run tests/ices.zunit + - name: "plugins" run: zunit run tests/plugins.zunit diff --git a/.gitignore b/.gitignore index 6be6dba52..e4ce82ff4 100644 --- a/.gitignore +++ b/.gitignore @@ -21,3 +21,4 @@ txt/ zmodules/ tests/_output/ tests/_support/zunit/ +.idea diff --git a/doc/zsdoc/zinit-install.zsh.adoc b/doc/zsdoc/zinit-install.zsh.adoc index 2432731fc..061c9c35d 100644 --- a/doc/zsdoc/zinit-install.zsh.adoc +++ b/doc/zsdoc/zinit-install.zsh.adoc @@ -703,7 +703,7 @@ ____ FUNCTION: ∞zinit-cp-hook [[[ ____ -Has 27 line(s). Calls functions: +Has 30 line(s). Calls functions: ∞zinit-cp-hook `-- zinit.zsh/@zinit-substitute diff --git a/doc/zsdoc/zinit.zsh.adoc b/doc/zsdoc/zinit.zsh.adoc index e074f154e..4d17125cf 100644 --- a/doc/zsdoc/zinit.zsh.adoc +++ b/doc/zsdoc/zinit.zsh.adoc @@ -1203,7 +1203,9 @@ ____ Registers the z-annex inside Zinit – i.e. an Zinit extension ____ -Has 4 line(s). Doesn't call other functions. +Has 6 line(s). Doesn't call other functions. + +Uses feature(s): _setopt_ Called by: diff --git a/tests/gh-r.zunit b/tests/gh-r.zunit index 46b11f03e..11a355c73 100755 --- a/tests/gh-r.zunit +++ b/tests/gh-r.zunit @@ -145,7 +145,7 @@ $dive --version; assert $state equals 0 } @test 'docker-buildx' { # A monitor of resources - run zinit for as'completions' atclone'buildx* completion zsh > _buildx' lbin'!buildx-* -> buildx' @docker/buildx + run zinit for as'completions' atclone'./buildx* completion zsh > _buildx' lbin'!buildx-* -> buildx' @docker/buildx assert $state equals 0 local buildx="$ZBIN/buildx"; assert "$buildx" is_executable $buildx version; assert $state equals 0 diff --git a/tests/ices.zunit b/tests/ices.zunit new file mode 100644 index 000000000..0cae9d8e9 --- /dev/null +++ b/tests/ices.zunit @@ -0,0 +1,52 @@ +#!/usr/bin/env zunit + +@setup { + ZPLUGINS=$ZINIT[PLUGINS_DIR] + + function _zunit_assert_not_exists() { + local pathname=$1 filepath + + # If filepath is relative, prepend the test directory + if [[ "${pathname:0:1}" != "/" ]]; then + filepath="$testdir/${pathname}" + else + filepath="$pathname" + fi + + [[ ! -e "$filepath" ]] && return 0 + + echo "'$pathname' does exist" + exit 1 + } + +} + +@test 'mv' { + run zinit as"null" id-as"test/mv" mv"readme.md -> mv.md" for zdharma-continuum/null + assert $state equals 0 + assert "$ZPLUGINS/test---mv/mv.md" is_file + assert "$ZPLUGINS/test---mv/mv.md" is_file + assert "$ZPLUGINS/test---mv/readme.md" not_exists +} + +@test 'cp' { + run zinit as"null" id-as"test/cp" cp"readme.md -> cp.md" for zdharma-continuum/null + assert $state equals 0 + assert "$ZPLUGINS/test---cp/cp.md" is_file + assert "$ZPLUGINS/test---cp/cp.md" is_readable + assert "$ZPLUGINS/test---cp/readme.md" is_file +} + +@test 'atclone' { + run zinit as"null" id-as"test/atclone" atclone"mv readme.md atclone.md" for zdharma-continuum/null + assert $state equals 0 + assert "$ZPLUGINS/test---atclone/atclone.md" is_file + assert "$ZPLUGINS/test---atclone/atclone.md" is_readable + assert "$ZPLUGINS/test---atclone/readme.md" not_exists +} + +@test 'make' { + run zinit as"null" id-as"test/make" atclone"printf 'all:\n\ttouch whatever\n' > Makefile" make"" for zdharma-continuum/null + assert $state equals 0 + assert "$ZPLUGINS/test---make/whatever" is_file +} diff --git a/tests/snippets.zunit b/tests/snippets.zunit index 8e3b0203c..37ba4f893 100755 --- a/tests/snippets.zunit +++ b/tests/snippets.zunit @@ -52,9 +52,12 @@ } @test 'tldr-completion::gh-r' { artifact="$ZINIT[PLUGINS_DIR]/tldr-completion---gh-r" - run zinit for as"completion" from"gh-r" id-as'tldr-completion/gh-r' bpick"completions_zsh" @dbrgn/tealdeer + run zinit for as"completion" from"gh-r" id-as'tldr-completion/gh-r' bpick"completions_zsh" mv"completions_zsh -> _tldr_ghr" pick"_tldr_ghr" @dbrgn/tealdeer assert $state equals 0 - assert "$artifact/completions_zsh" is_file; assert $artifact is_readable + assert "$artifact/_tldr_ghr" is_file + assert $artifact/_tldr_ghr is_readable + assert "$ZINIT[COMPLETIONS_DIR]"/_tldr_ghr is_file + assert "$ZINIT[COMPLETIONS_DIR]"/_tldr_ghr is_readable } @test 'zinit local snippet symlink' { mkdir -p "${ZINIT[HOME_DIR]}/external" diff --git a/zinit-autoload.zsh b/zinit-autoload.zsh index b7679dfb0..4cc9027bd 100644 --- a/zinit-autoload.zsh +++ b/zinit-autoload.zsh @@ -1567,9 +1567,9 @@ ZINIT[EXTENDED_GLOB]="" # Run annexes' atpull hooks (the before atpull-ice ones). # The gh-r / GitHub releases block. reply=( - ${(on)ZINIT_EXTS2[(I)zinit hook:e-\\\!atpull-pre <->]} - ${${(M)ICE[atpull]#\!}:+${(on)ZINIT_EXTS[(I)z-annex hook:\\\!atpull-<-> <->]}} - ${(on)ZINIT_EXTS2[(I)zinit hook:e-\\\!atpull-post <->]} + ${(on)ZINIT_EXTS2[(I)zinit hook:e-\!atpull-pre <->]} + ${${(M)ICE[atpull]#\!}:+${(on)ZINIT_EXTS[(I)z-annex hook:\!atpull-<-> <->]}} + ${(on)ZINIT_EXTS2[(I)zinit hook:e-\!atpull-post <->]} ) for key in "${reply[@]}"; do arr=( "${(Q)${(z@)ZINIT_EXTS[$key]:-$ZINIT_EXTS2[$key]}[@]}" ) @@ -1656,9 +1656,9 @@ ZINIT[EXTENDED_GLOB]="" # Run annexes' atpull hooks (the before atpull-ice ones). # The regular Git-plugins block. reply=( - ${(on)ZINIT_EXTS2[(I)zinit hook:e-\\\!atpull-pre <->]} - ${${(M)ICE[atpull]#\!}:+${(on)ZINIT_EXTS[(I)z-annex hook:\\\!atpull-<-> <->]}} - ${(on)ZINIT_EXTS2[(I)zinit hook:e-\\\!atpull-post <->]} + ${(on)ZINIT_EXTS2[(I)zinit hook:e-\!atpull-pre <->]} + ${${(M)ICE[atpull]#\!}:+${(on)ZINIT_EXTS[(I)z-annex hook:\!atpull-<-> <->]}} + ${(on)ZINIT_EXTS2[(I)zinit hook:e-\!atpull-post <->]} ) for key in "${reply[@]}"; do arr=( "${(Q)${(z@)ZINIT_EXTS[$key]:-$ZINIT_EXTS2[$key]}[@]}" ) @@ -1703,9 +1703,9 @@ ZINIT[EXTENDED_GLOB]="" # Run annexes' atpull hooks (the before atpull[^!]…-ice ones). # Block common for Git and gh-r plugins. reply=( - ${(on)ZINIT_EXTS2[(I)zinit hook:no-e-\\\!atpull-pre <->]} - ${${ICE[atpull]:#\!*}:+${(on)ZINIT_EXTS[(I)z-annex hook:\\\!atpull-<-> <->]}} - ${(on)ZINIT_EXTS2[(I)zinit hook:no-e-\\\!atpull-post <->]} + ${(on)ZINIT_EXTS2[(I)zinit hook:no-e-\!atpull-pre <->]} + ${${ICE[atpull]:#\!*}:+${(on)ZINIT_EXTS[(I)z-annex hook:\!atpull-<-> <->]}} + ${(on)ZINIT_EXTS2[(I)zinit hook:no-e-\!atpull-post <->]} ) for key in "${reply[@]}"; do arr=( "${(Q)${(z@)ZINIT_EXTS[$key]:-$ZINIT_EXTS2[$key]}[@]}" ) diff --git a/zinit-install.zsh b/zinit-install.zsh index 5ca602377..62e43ddb0 100644 --- a/zinit-install.zsh +++ b/zinit-install.zsh @@ -451,9 +451,9 @@ builtin source "${ZINIT[BIN_DIR]}/zinit-side.zsh" || { # Store ices at clone of a plugin .zinit-store-ices "$local_path/._zinit" ICE "" "" "" "" reply=( - ${(on)ZINIT_EXTS2[(I)zinit hook:\\\!atclone-pre <->]} - ${(on)ZINIT_EXTS[(I)z-annex hook:\\\!atclone-<-> <->]} - ${(on)ZINIT_EXTS2[(I)zinit hook:\\\!atclone-post <->]} + ${(on)ZINIT_EXTS2[(I)zinit hook:\!atclone-pre <->]} + ${(on)ZINIT_EXTS[(I)z-annex hook:\!atclone-<-> <->]} + ${(on)ZINIT_EXTS2[(I)zinit hook:\!atclone-post <->]} ) for key in "${reply[@]}"; do arr=( "${(Q)${(z@)ZINIT_EXTS[$key]:-$ZINIT_EXTS2[$key]}[@]}" ) @@ -999,9 +999,9 @@ builtin source "${ZINIT[BIN_DIR]}/zinit-side.zsh" || { # Run annexes' atpull hooks (the before atpull-ice ones). # The SVN block. reply=( - ${(on)ZINIT_EXTS2[(I)zinit hook:e-\\\!atpull-pre <->]} - ${${(M)ICE[atpull]#\!}:+${(on)ZINIT_EXTS[(I)z-annex hook:\\\!atpull-<-> <->]}} - ${(on)ZINIT_EXTS2[(I)zinit hook:e-\\\!atpull-post <->]} + ${(on)ZINIT_EXTS2[(I)zinit hook:e-\!atpull-pre <->]} + ${${(M)ICE[atpull]#\!}:+${(on)ZINIT_EXTS[(I)z-annex hook:\!atpull-<-> <->]}} + ${(on)ZINIT_EXTS2[(I)zinit hook:e-\!atpull-post <->]} ) for key in "${reply[@]}"; do arr=( "${(Q)${(z@)ZINIT_EXTS[$key]:-$ZINIT_EXTS2[$key]}[@]}" ) @@ -1093,9 +1093,9 @@ builtin source "${ZINIT[BIN_DIR]}/zinit-side.zsh" || { # The URL-snippet block. if [[ $update = -u && $ZINIT[annex-multi-flag:pull-active] -ge 1 ]] { reply=( - ${(on)ZINIT_EXTS2[(I)zinit hook:e-\\\!atpull-pre <->]} - ${${ICE[atpull]#\!}:+${(on)ZINIT_EXTS[(I)z-annex hook:\\\!atpull-<-> <->]}} - ${(on)ZINIT_EXTS2[(I)zinit hook:e-\\\!atpull-post <->]} + ${(on)ZINIT_EXTS2[(I)zinit hook:e-\!atpull-pre <->]} + ${${ICE[atpull]#\!}:+${(on)ZINIT_EXTS[(I)z-annex hook:\!atpull-<-> <->]}} + ${(on)ZINIT_EXTS2[(I)zinit hook:e-\!atpull-post <->]} ) for key in "${reply[@]}"; do arr=( "${(Q)${(z@)ZINIT_EXTS[$key]:-$ZINIT_EXTS2[$key]}[@]}" ) @@ -1153,9 +1153,9 @@ builtin source "${ZINIT[BIN_DIR]}/zinit-side.zsh" || { # The local-file snippets block. if [[ $update = -u ]] { reply=( - ${(on)ZINIT_EXTS2[(I)zinit hook:e-\\\!atpull-pre <->]} - ${${(M)ICE[atpull]#\!}:+${(on)ZINIT_EXTS[(I)z-annex hook:\\\!atpull-<-> <->]}} - ${(on)ZINIT_EXTS2[(I)zinit hook:e-\\\!atpull-post <->]} + ${(on)ZINIT_EXTS2[(I)zinit hook:e-\!atpull-pre <->]} + ${${(M)ICE[atpull]#\!}:+${(on)ZINIT_EXTS[(I)z-annex hook:\!atpull-<-> <->]}} + ${(on)ZINIT_EXTS2[(I)zinit hook:e-\!atpull-post <->]} ) for key in "${reply[@]}"; do arr=( "${(Q)${(z@)ZINIT_EXTS[$key]:-$ZINIT_EXTS2[$key]}[@]}" ) @@ -1248,9 +1248,9 @@ builtin source "${ZINIT[BIN_DIR]}/zinit-side.zsh" || { # Run annexes' atpull hooks (the before atpull-ice ones). # The block is common to all 3 snippet types. reply=( - ${(on)ZINIT_EXTS2[(I)zinit hook:no-e-\\\!atpull-pre <->]} - ${${ICE[atpull]:#\!*}:+${(on)ZINIT_EXTS[(I)z-annex hook:\\\!atpull-<-> <->]}} - ${(on)ZINIT_EXTS2[(I)zinit hook:no-e-\\\!atpull-post <->]} + ${(on)ZINIT_EXTS2[(I)zinit hook:no-e-\!atpull-pre <->]} + ${${ICE[atpull]:#\!*}:+${(on)ZINIT_EXTS[(I)z-annex hook:\!atpull-<-> <->]}} + ${(on)ZINIT_EXTS2[(I)zinit hook:no-e-\!atpull-post <->]} ) for key in "${reply[@]}"; do arr=( "${(Q)${(z@)ZINIT_EXTS[$key]:-$ZINIT_EXTS2[$key]}[@]}" ) @@ -1265,9 +1265,9 @@ builtin source "${ZINIT[BIN_DIR]}/zinit-side.zsh" || { # Run annexes' atclone hooks (the before atclone-ice ones) # The block is common to all 3 snippet types. reply=( - ${(on)ZINIT_EXTS2[(I)zinit hook:\\\!atclone-pre <->]} - ${(on)ZINIT_EXTS[(I)z-annex hook:\\\!atclone-<-> <->]} - ${(on)ZINIT_EXTS2[(I)zinit hook:\\\!atclone-post <->]} + ${(on)ZINIT_EXTS2[(I)zinit hook:\!atclone-pre <->]} + ${(on)ZINIT_EXTS[(I)z-annex hook:\!atclone-<-> <->]} + ${(on)ZINIT_EXTS2[(I)zinit hook:\!atclone-post <->]} ) for key in "${reply[@]}"; do arr=( "${(Q)${(z@)ZINIT_EXTS[$key]:-$ZINIT_EXTS2[$key]}[@]}" ) @@ -2360,18 +2360,23 @@ zimv() { @zinit-substitute from to - local -a afr + local -a afr retval ( () { setopt localoptions noautopushd; builtin cd -q "$dir"; } || return 1 afr=( ${~from}(DN) ) if (( ${#afr} )) { if (( !OPTS[opt_-q,--quiet] )) { command cp -vf "${afr[1]}" "$to" + retval=$? + # ignore errors if no compiled file is found command cp -vf "${afr[1]}".zwc "$to".zwc 2>/dev/null } else { command cp -f "${afr[1]}" "$to" + retval=$? + # ignore errors if no compiled file is found command cp -f "${afr[1]}".zwc "$to".zwc 2>/dev/null } } + return $retval ) } # ]]] diff --git a/zinit.zsh b/zinit.zsh index 39cedeb5f..822010303 100644 --- a/zinit.zsh +++ b/zinit.zsh @@ -1184,6 +1184,12 @@ builtin setopt noaliases # FUNCTION: @zinit-register-hook. [[[ # Registers the z-annex inside Zinit – i.e. an Zinit extension @zinit-register-hook() { + builtin emulate -LR zsh ${=${options[xtrace]:#off}:+-o xtrace} + # zsh per default behaves differently in interactive sessions (escapes !) and + # non-interactive ones (does not). Setting 'nobanghist' option disables backslash + # escaping for "!" even in interactive sessions. + # Exclamation marks are used in a lot of hock names. + builtin setopt extendedglob nobanghist noshortloops typesetsilent warncreateglobal local name="$1" type="$2" handler="$3" icemods="$4" key="zinit ${(q)2}" ZINIT_EXTS2[seqno]=$(( ${ZINIT_EXTS2[seqno]:-0} + 1 )) ZINIT_EXTS2[$key${${(M)type#hook:}:+ ${ZINIT_EXTS2[seqno]}}]="${ZINIT_EXTS2[seqno]} z-annex-data: ${(q)name} ${(q)type} ${(q)handler} '' ${(q)icemods}" @@ -1391,7 +1397,7 @@ builtin setopt noaliases ZINIT[CUR_USPL2]="$id_as" ZINIT_REPORTS[$id_as]= - reply=( ${(on)ZINIT_EXTS[(I)z-annex hook:\\\!atinit-<-> <->]} ) + reply=( ${(on)ZINIT_EXTS[(I)z-annex hook:\!atinit-<-> <->]} ) for key in "${reply[@]}"; do arr=( "${(Q)${(z@)ZINIT_EXTS[$key]}[@]}" ) "${arr[5]}" snippet "$save_url" "$id_as" "$local_dir/$dirname" \!atinit || \ @@ -1453,7 +1459,7 @@ builtin setopt noaliases [[ -n ${ICE[multisrc]} ]] && { local ___oldcd="$PWD"; () { setopt localoptions noautopushd; builtin cd -q "$local_dir/$dirname"; }; eval "reply=(${ICE[multisrc]})"; () { setopt localoptions noautopushd; builtin cd -q "$___oldcd"; }; local fname; for fname in "${reply[@]}"; do ZERO="${${(M)fname:#/*}:-$local_dir/$dirname/$fname}"; (( ${+ICE[silent]} )) && { { [[ -n $precm ]] && { builtin ${precm[@]} 'source "$ZERO"'; ((1)); } || { ((1)); builtin source "$ZERO"; }; } 2>/dev/null 1>&2; (( retval += $? )); ((1)); } || { ((1)); { [[ -n $precm ]] && { builtin ${precm[@]} 'source "$ZERO"'; ((1)); } || { ((1)); builtin source "$ZERO"; }; }; (( retval += $? )); }; done; } # Run the atload hooks right before atload ice. - reply=( ${(on)ZINIT_EXTS[(I)z-annex hook:\\\!atload-<-> <->]} ) + reply=( ${(on)ZINIT_EXTS[(I)z-annex hook:\!atload-<-> <->]} ) for key in "${reply[@]}"; do arr=( "${(Q)${(z@)ZINIT_EXTS[$key]}[@]}" ) "${arr[5]}" snippet "$save_url" "$id_as" "$local_dir/$dirname" \!atload @@ -1507,7 +1513,7 @@ builtin setopt noaliases [[ -n ${ICE[multisrc]} ]] && { local ___oldcd="$PWD"; () { setopt localoptions noautopushd; builtin cd -q "$local_dir/$dirname"; }; eval "reply=(${ICE[multisrc]})"; () { setopt localoptions noautopushd; builtin cd -q "$___oldcd"; }; local fname; for fname in "${reply[@]}"; do ZERO="${${(M)fname:#/*}:-$local_dir/$dirname/$fname}"; (( ${+ICE[silent]} )) && { { [[ -n $precm ]] && { builtin ${precm[@]} 'source "$ZERO"'; ((1)); } || { ((1)); builtin source "$ZERO"; }; } 2>/dev/null 1>&2; (( retval += $? )); ((1)); } || { ((1)); { [[ -n $precm ]] && { builtin ${precm[@]} 'source "$ZERO"'; ((1)); } || { ((1)); builtin source "$ZERO"; }; }; (( retval += $? )); }; done; } # Run the atload hooks right before atload ice. - reply=( ${(on)ZINIT_EXTS[(I)z-annex hook:\\\!atload-<-> <->]} ) + reply=( ${(on)ZINIT_EXTS[(I)z-annex hook:\!atload-<-> <->]} ) for key in "${reply[@]}"; do arr=( "${(Q)${(z@)ZINIT_EXTS[$key]}[@]}" ) "${arr[5]}" snippet "$save_url" "$id_as" "$local_dir/$dirname" \!atload @@ -1624,7 +1630,7 @@ builtin setopt noaliases .zinit-setup-params && local ${(Q)reply[@]} } - reply=( ${(on)ZINIT_EXTS[(I)z-annex hook:\\\!atinit-<-> <->]} ) + reply=( ${(on)ZINIT_EXTS[(I)z-annex hook:\!atinit-<-> <->]} ) for ___key in "${reply[@]}"; do ___arr=( "${(Q)${(z@)ZINIT_EXTS[$___key]}[@]}" ) "${___arr[5]}" plugin "$___user" "$___plugin" "$___id_as" "${${${(M)___user:#%}:+$___plugin}:-${ZINIT[PLUGINS_DIR]}/${___id_as//\//---}}" \!atinit || \ @@ -1725,7 +1731,7 @@ builtin setopt noaliases [[ -n ${ICE[multisrc]} ]] && { local ___oldcd="$PWD"; () { setopt localoptions noautopushd; builtin cd -q "$___pdir_orig"; }; eval "reply=(${ICE[multisrc]})"; () { setopt localoptions noautopushd; builtin cd -q "$___oldcd"; }; local ___fname; for ___fname in "${reply[@]}"; do ZERO="${${(M)___fname:#/*}:-$___pdir_orig/$___fname}"; (( ${+ICE[silent]} )) && { { [[ -n $___precm ]] && { builtin ${___precm[@]} 'source "$ZERO"'; ((1)); } || { ((1)); $___builtin source "$ZERO"; }; } 2>/dev/null 1>&2; (( ___retval += $? )); ((1)); } || { ((1)); { [[ -n $___precm ]] && { builtin ${___precm[@]} 'source "$ZERO"'; ((1)); } || { ((1)); $___builtin source "$ZERO"; }; }; (( ___retval += $? )); }; done; } # Run the atload hooks right before atload ice. - reply=( ${(on)ZINIT_EXTS[(I)z-annex hook:\\\!atload-<-> <->]} ) + reply=( ${(on)ZINIT_EXTS[(I)z-annex hook:\!atload-<-> <->]} ) for ___key in "${reply[@]}"; do ___arr=( "${(Q)${(z@)ZINIT_EXTS[$___key]}[@]}" ) "${___arr[5]}" plugin "$___user" "$___plugin" "$___id_as" "$___pdir_orig" \!atload @@ -1776,7 +1782,7 @@ builtin setopt noaliases [[ -n ${ICE[multisrc]} ]] && { local ___oldcd="$PWD"; () { setopt localoptions noautopushd; builtin cd -q "$___pdir_orig"; }; eval "reply=(${ICE[multisrc]})"; () { setopt localoptions noautopushd; builtin cd -q "$___oldcd"; }; for ___fname in "${reply[@]}"; do ZERO="${${(M)___fname:#/*}:-$___pdir_orig/$___fname}"; (( ${+ICE[silent]} )) && { { [[ -n $___precm ]] && { builtin ${___precm[@]} 'source "$ZERO"'; ((1)); } || { ((1)); $___builtin source "$ZERO"; }; } 2>/dev/null 1>&2; (( ___retval += $? )); ((1)); } || { { [[ -n $___precm ]] && { builtin ${___precm[@]} 'source "$ZERO"'; ((1)); } || { ((1)); $___builtin source "$ZERO"; }; }; (( ___retval += $? )); } done; } # Run the atload hooks right before atload ice. - reply=( ${(on)ZINIT_EXTS[(I)z-annex hook:\\\!atload-<-> <->]} ) + reply=( ${(on)ZINIT_EXTS[(I)z-annex hook:\!atload-<-> <->]} ) for ___key in "${reply[@]}"; do ___arr=( "${(Q)${(z@)ZINIT_EXTS[$___key]}[@]}" ) "${___arr[5]}" plugin "$___user" "$___plugin" "$___id_as" "$___pdir_orig" \!atload