diff --git a/.editorconfig b/.editorconfig
index 1e1705f..116720c 100644
--- a/.editorconfig
+++ b/.editorconfig
@@ -1,15 +1,123 @@
+# Space or Tabs?
+# https://stackoverflow.com/questions/35649847/objective-reasons-for-using-spaces-instead-of-tabs-for-indentation
+# https://stackoverflow.com/questions/12093748/how-to-use-tabs-instead-of-spaces-in-a-shell-script
+#
+# 1. What happens when I press the Tab key in my text editor?
+# 2. What happens when I request my editor to indent one or more lines?
+# 3. What happens when I view a file containing U+0009 HORIZONTAL TAB characters?
+#
+# Answers:
+#
+# 1. Pressing the Tab key should indent the current line (or selected lines) one additional level.
+# 2. As a secondary alternative, I can also tolerate an editor that,
+# like Emacs, uses this key for a context-sensitive fix-my-indentation command.
+# 3. Indenting one or more lines should follow the reigning convention, if consensus is sufficiently strong; otherwise,
+# I greatly prefer 2-space indentation at each level. U+0009 characters should shift subsequent characters to the next tab stop.
+#
# Note: VIM users should use alternate marks [[[ and ]]] as the original ones can confuse nested substitutions, e.g.: ${${${VAR}}}
-# # Space or Tabs? https://stackoverflow.com/questions/35649847/objective-reasons-for-using-spaces-instead-of-tabs-for-indentation
+#
+# -*- mode: zsh; sh-indentation: 2; indent-tabs-mode: nil; sh-basic-offset: 2; -*-
+# vim: ft=zsh sw=2 ts=2 et
root = true
[*]
-indent_style = space
-indent_size = 2
charset = utf-8
end_of_line = lf
-trim_trailing_whitespace = true
insert_final_newline = true
+trim_trailing_whitespace = true
-[**.{md,rst}]
+[*.{md,rst}]
+insert_final_newline = false
trim_trailing_whitespace = false
+
+[*.{sh,bash,zsh,fish}]
+indent_style = space
+indent_size = 2
+tab_width = 2
+
+[Makefile]
+indent_style = tab
+indent_size = 4
+
+[*.{css,less}]
+indent_style = space
+indent_size = 2
+
+[*.{py,rb}]
+indent_style = space
+indent_size = 4
+
+[*.{go,java,scala,groovy,kotlin}]
+indent_style = tab
+indent_size = 4
+
+[*.{js,jsx,html,xml,sass,json,yml,yaml,toml}]
+charset = utf-8
+indent_style = space
+indent_size = 2
+max_line_length = 120
+
+[CHANGELOG.md]
+indent_style = tab
+indent_size = 4
+
+[*.{c++,cc,cpp,cxx,h,h++,hh,hpp,hxx,inl,ipp,tlh,tli}]
+cpp_indent_braces=false
+cpp_indent_multi_line_relative_to=innermost_parenthesis
+cpp_indent_within_parentheses=indent
+cpp_indent_preserve_within_parentheses=false
+cpp_indent_case_labels=false
+cpp_indent_case_contents=true
+cpp_indent_case_contents_when_block=false
+cpp_indent_lambda_braces_when_parameter=true
+cpp_indent_goto_labels=one_left
+cpp_indent_preprocessor=leftmost_column
+cpp_indent_access_specifiers=false
+cpp_indent_namespace_contents=true
+cpp_indent_preserve_comments=false
+cpp_new_line_before_open_brace_namespace=ignore
+cpp_new_line_before_open_brace_type=ignore
+cpp_new_line_before_open_brace_function=ignore
+cpp_new_line_before_open_brace_block=ignore
+cpp_new_line_before_open_brace_lambda=ignore
+cpp_new_line_scope_braces_on_separate_lines=false
+cpp_new_line_close_brace_same_line_empty_type=false
+cpp_new_line_close_brace_same_line_empty_function=false
+cpp_new_line_before_catch=true
+cpp_new_line_before_else=true
+cpp_new_line_before_while_in_do_while=false
+cpp_space_before_function_open_parenthesis=remove
+cpp_space_within_parameter_list_parentheses=false
+cpp_space_between_empty_parameter_list_parentheses=false
+cpp_space_after_keywords_in_control_flow_statements=true
+cpp_space_within_control_flow_statement_parentheses=false
+cpp_space_before_lambda_open_parenthesis=false
+cpp_space_within_cast_parentheses=false
+cpp_space_after_cast_close_parenthesis=false
+cpp_space_within_expression_parentheses=false
+cpp_space_before_block_open_brace=true
+cpp_space_between_empty_braces=false
+cpp_space_before_initializer_list_open_brace=false
+cpp_space_within_initializer_list_braces=true
+cpp_space_preserve_in_initializer_list=true
+cpp_space_before_open_square_bracket=false
+cpp_space_within_square_brackets=false
+cpp_space_before_empty_square_brackets=false
+cpp_space_between_empty_square_brackets=false
+cpp_space_group_square_brackets=true
+cpp_space_within_lambda_brackets=false
+cpp_space_between_empty_lambda_brackets=false
+cpp_space_before_comma=false
+cpp_space_after_comma=true
+cpp_space_remove_around_member_operators=true
+cpp_space_before_inheritance_colon=true
+cpp_space_before_constructor_colon=true
+cpp_space_remove_before_semicolon=true
+cpp_space_after_semicolon=false
+cpp_space_remove_around_unary_operator=true
+cpp_space_around_binary_operator=insert
+cpp_space_around_assignment_operator=insert
+cpp_space_pointer_reference_alignment=left
+cpp_space_around_ternary_operator=insert
+cpp_wrap_preserve_blocks=one_liners
diff --git a/.gitignore b/.gitignore
index 8d4d67b..b5ea715 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,7 +1,7 @@
*.zwc
*zcompdump*
-._zinit
-.zinit_lastupd
+._zi
+.zi_lastupd
zsdoc/data
# Prerequisites
diff --git a/.vscode/settings.json b/.vscode/settings.json
new file mode 100644
index 0000000..93d9db4
--- /dev/null
+++ b/.vscode/settings.json
@@ -0,0 +1,5 @@
+{
+ "conventionalCommits.scopes": [
+ "workspace"
+ ]
+}
diff --git a/docs/README.md b/docs/README.md
index 2de5e0d..67975c6 100644
--- a/docs/README.md
+++ b/docs/README.md
@@ -1,13 +1,6 @@
ZI Annex Test
-## Introduction
-
-> **[?]**
-> This repository not compatible with previous versions (zplugin, zinit).
->
-> Please upgrade to [ZI](https://github.com/z-shell-zi)
-
-A [ZI](https://github.com/z-shell/zi) Annex (extension) that runs tests (via `make test`, for example) – if it finds any of them – after installing and updating
+A [ZI](https://github.com/z-shell/zi) annex (extension) that runs tests (via `make test`, for example) – if it finds any of them – after installing and updating
a plugin or snippet. Simply load it like any other plugin to make it active:
```zsh
@@ -34,8 +27,12 @@ zi load …
Example activation in the default quiet mode:
-![z-a-test activation](https://raw.githubusercontent.com/z-shell/z-a-test/main/images/z-p-test-1.png)
+![z-a-test activation](https://raw.githubusercontent.com/z-shell/z-a-test/main/docs/images/z-p-test-1.png)
Example activation in non-quiet mode:
-![z-a-test activation](https://raw.githubusercontent.com/z-shell/z-a-test/main/images/z-p-test-2.png)
+![z-a-test activation](https://raw.githubusercontent.com/z-shell/z-a-test/main/docs/images/z-p-test-2.png)
+
+---
+
+This repository is compatible with [ZI](https://github.com/z-shell-zi)
diff --git a/images/z-p-test-1.png b/docs/images/z-p-test-1.png
similarity index 100%
rename from images/z-p-test-1.png
rename to docs/images/z-p-test-1.png
diff --git a/images/z-p-test-2.png b/docs/images/z-p-test-2.png
similarity index 100%
rename from images/z-p-test-2.png
rename to docs/images/z-p-test-2.png
diff --git "a/functions/\342\206\222za-test-handler" "b/functions/\342\206\222za-test-handler"
new file mode 100644
index 0000000..713ae74
--- /dev/null
+++ "b/functions/\342\206\222za-test-handler"
@@ -0,0 +1,63 @@
+# -*- mode: zsh; sh-indentation: 2; indent-tabs-mode: nil; sh-basic-offset: 2; -*-
+emulate -RL zsh
+setopt extendedglob warncreateglobal typesetsilent noshortloops
+
+(( ${ICE[test]:-1} )) || return 0
+
+[[ "$1" = plugin ]] && \
+ local type="$1" user="$2" plugin="$3" id_as="$4" dir="$5" || \
+ local type="$1" url="$2" id_as="$3" dir="$4"
+
+(( ${+ICE[notest]} )) && return 0
+
+(
+ builtin cd -q $dir
+
+ if [[ -f Makefile ]]; then
+ →za-test-make-targets Makefile
+ if (( ${reply[(I)test]} )); then
+ [[ "${OPTS[opt_-q,--quiet]}" != 1 ]] && \
+ print -P -- "%F{38}test z-plugin: %F{154}RUNNING MAKEFILE TESTS%f"
+ integer quiet=0
+ zstyle -T ":zi:annex:test" quiet && quiet=1
+ if (( quiet )); then
+ if make test &>/dev/null; then
+ [[ "${OPTS[opt_-q,--quiet]}" != 1 ]] && \
+ print -P -- "%F{38}test z-plugin: %F{154}The tests succeeded%f"
+ else
+ [[ "${OPTS[opt_-q,--quiet]}" != 1 ]] && \
+ print -P -- "%F{38}test z-plugin: %F{160}The tests have failed%f"
+ fi
+ else
+ make test
+ fi
+ fi
+ fi
+ local -a farray
+ farray=( **/*.zunit(N) )
+ if (( ${#farray} )); then
+ if type zunit >/dev/null 2>&1; then
+ [[ "${OPTS[opt_-q,--quiet]}" != 1 ]] && \
+ print -P -- "%F{38}test z-plugin: %F{154}RUNNING ZUNIT TESTS%f"
+ integer quiet=0
+ zstyle -T ":zi:annex:test" quiet && quiet=1
+ if (( quiet )); then
+ if zunit &>/dev/null; then
+ [[ "${OPTS[opt_-q,--quiet]}" != 1 ]] && \
+ print -P -- "%F{38}test z-plugin: %F{154}The tests succeeded%f"
+ else
+ [[ "${OPTS[opt_-q,--quiet]}" != 1 ]] && \
+ print -P -- "%F{38}test z-plugin: %F{160}The tests have failed%f"
+ fi
+ else
+ zunit
+ fi
+ else
+ [[ "${OPTS[opt_-q,--quiet]}" != 1 ]] && \
+ print -P -- "%F{38}test z-plugin: %F{154}Please install zunit (zi for @zunit) to" \
+ " run the zunit tests provided with the plugin%f"
+ fi
+ fi
+)
+
+# vim: ft=zsh sw=2 ts=2 et
diff --git "a/functions/\342\206\222za-test-make-targets" "b/functions/\342\206\222za-test-make-targets"
new file mode 100644
index 0000000..6ef8a5f
--- /dev/null
+++ "b/functions/\342\206\222za-test-make-targets"
@@ -0,0 +1,93 @@
+# -*- mode: zsh; sh-indentation: 2; indent-tabs-mode: nil; sh-basic-offset: 2; -*-
+
+emulate -LR zsh -o extendedglob
+
+local -a TARGETS match mbegin mend
+
+za-test-make-expandVars() {
+ local open close var val front='' rest=$1
+
+ while [[ $rest == (#b)[^$]#($)* ]]; do
+ front=$front${rest[1,$mbegin[1]-1]}
+ rest=${rest[$mbegin[1],-1]}
+
+ case $rest[2] in
+ ($) # '$$'. may not appear in target and variable's value
+ front=$front\$\$
+ rest=${rest[3,-1]}
+ continue
+ ;;
+ (\() # Variable of the form $(foobar)
+ open='('
+ close=')'
+ ;;
+ ({) # ${foobar}
+ open='{'
+ close='}'
+ ;;
+ ([[:alpha:]]) # $foobar. This is exactly $(f)oobar.
+ open=''
+ close=''
+ var=$rest[2]
+ ;;
+ (*) # bad parameter name
+ print -- $front$rest
+ return 1
+ ;;
+ esac
+
+ if [[ -n $open ]]; then
+ if [[ $rest == \$$open(#b)([[:alnum:]_]##)(#B)$close* ]]; then
+ var=$match
+ else # unmatched () or {}, or bad parameter name
+ print -- $front$rest
+ return 1
+ fi
+ fi
+
+ val=''
+ if [[ -n ${VAR_ARGS[(i)$var]} ]]; then
+ val=${VAR_ARGS[$var]}
+ else
+ if [[ -n $opt_args[(I)(-e|--environment-overrides)] ]]; then
+ if [[ $parameters[$var] == scalar-export* ]]; then
+ val=${(P)var}
+ elif [[ -n ${VARIABLES[(i)$var]} ]]; then
+ val=${VARIABLES[$var]}
+ fi
+ else
+ if [[ -n ${VARIABLES[(i)$var]} ]]; then
+ val=${VARIABLES[$var]}
+ elif [[ $parameters[$var] == scalar-export* ]]; then
+ val=${(P)var}
+ fi
+ fi
+ fi
+ rest=${rest//\$$open$var$close/$val}
+ done
+
+ print -- ${front}${rest}
+}
+
+
+za-test-make-parseMakefile () {
+ local input var val target dep TAB=$'\t' tmp IFS=
+
+ while read input
+ do
+ case "$input " in
+ # TARGET: dependencies
+ # TARGET1 TARGET2 TARGET3: dependencies
+ ([[*?[:alnum:]$][^$TAB:=%]#:[^=]*)
+ target=$(za-test-make-expandVars ${input%%:*})
+ TARGETS+=( ${(z)target} )
+ ;;
+ esac
+ done
+}
+
+za-test-make-parseMakefile < "$1"
+
+reply=( "${(u)TARGETS[@]}" )
+
+# vim: ft=zsh sw=2 ts=2 et
diff --git a/z-a-test.plugin.zsh b/z-a-test.plugin.zsh
index 7f6e019..f127dd8 100644
--- a/z-a-test.plugin.zsh
+++ b/z-a-test.plugin.zsh
@@ -1,15 +1,30 @@
-# According to the Zsh Plugin Standard:
-# https://github.com/z-shell/zi/wiki/Zsh-Plugin-Standard
-0="${${ZERO:-${0:#$ZSH_ARGZERO}}:-${(%):-%N}}"
+# -*- mode: zsh; sh-indentation: 2; indent-tabs-mode: nil; sh-basic-offset: 2; -*-
+# Standardized $0 Handling
+# https://z.digitalclouds.dev/community/zsh_plugin_standard#zero-handling
+0="${ZERO:-${${0:#$ZSH_ARGZERO}:-${(%):-%N}}}"
0="${${(M)0:#/*}:-$PWD/$0}"
-autoload -Uz za-test-handler za-test-make-targets
+# Functions directory
+# https://z.digitalclouds.dev/community/zsh_plugin_standard#funtions-directory
+if [[ $PMSPEC != *f* ]] {
+ fpath+=( "${0:h}/functions" )
+}
+
+# The Proposed Function-Name Prefixes
+# https://z.digitalclouds.dev/community/zsh_plugin_standard#the-proposed-function-name-prefixes
+autoload -Uz →za-test-handler →za-test-make-targets
# An empty stub to fill the help handler fields
-za-test-help-null-handler() { :; }
+→za-test-help-null-handler() { :; }
# Register atclone hook
-@zi-register-annex "z-a-test" hook:atclone-110 za-test-handler za-test-help-null-handler "notest|test''" # register a new ice-mod: test''
+@zi-register-annex "z-a-test" hook:atclone-110 \
+ →za-test-handler \
+ →za-test-help-null-handler "notest|test''" # register a new ice-mod: test''
# Register atpull hook
-@zi-register-annex "z-a-test" hook:atpull-110 za-test-handler za-test-help-null-handler
+@zi-register-annex "z-a-test" hook:atpull-110 \
+ →za-test-handler \
+ →za-test-help-null-handler
+
+# vim: ft=zsh sw=2 ts=2 et
diff --git a/za-test-handler b/za-test-handler
deleted file mode 100644
index a6e9d0f..0000000
--- a/za-test-handler
+++ /dev/null
@@ -1,60 +0,0 @@
-emulate -RL zsh
-setopt extendedglob warncreateglobal typesetsilent noshortloops
-
-(( ${ICE[test]:-1} )) || return 0
-
-[[ "$1" = plugin ]] && \
- local type="$1" user="$2" plugin="$3" id_as="$4" dir="$5" || \
- local type="$1" url="$2" id_as="$3" dir="$4"
-
-(( ${+ICE[notest]} )) && return 0
-
-(
- builtin cd -q $dir
-
- if [[ -f Makefile ]]; then
- za-test-make-targets Makefile
- if (( ${reply[(I)test]} )); then
- [[ "${OPTS[opt_-q,--quiet]}" != 1 ]] && \
- print -P -- "%F{38}test z-plugin: %F{154}RUNNING MAKEFILE TESTS%f"
- integer quiet=0
- zstyle -T ":zi:annex:test" quiet && quiet=1
- if (( quiet )); then
- if make test &>/dev/null; then
- [[ "${OPTS[opt_-q,--quiet]}" != 1 ]] && \
- print -P -- "%F{38}test z-plugin: %F{154}The tests succeeded%f"
- else
- [[ "${OPTS[opt_-q,--quiet]}" != 1 ]] && \
- print -P -- "%F{38}test z-plugin: %F{160}The tests have failed%f"
- fi
- else
- make test
- fi
- fi
- fi
- local -a farray
- farray=( **/*.zunit(N) )
- if (( ${#farray} )); then
- if type zunit >/dev/null 2>&1; then
- [[ "${OPTS[opt_-q,--quiet]}" != 1 ]] && \
- print -P -- "%F{38}test z-plugin: %F{154}RUNNING ZUNIT TESTS%f"
- integer quiet=0
- zstyle -T ":zi:annex:test" quiet && quiet=1
- if (( quiet )); then
- if zunit &>/dev/null; then
- [[ "${OPTS[opt_-q,--quiet]}" != 1 ]] && \
- print -P -- "%F{38}test z-plugin: %F{154}The tests succeeded%f"
- else
- [[ "${OPTS[opt_-q,--quiet]}" != 1 ]] && \
- print -P -- "%F{38}test z-plugin: %F{160}The tests have failed%f"
- fi
- else
- zunit
- fi
- else
- [[ "${OPTS[opt_-q,--quiet]}" != 1 ]] && \
- print -P -- "%F{38}test z-plugin: %F{154}Please install molovo/zunit to" \
- " run the zunit tests provided with the plugin%f"
- fi
- fi
-)
diff --git a/za-test-make-targets b/za-test-make-targets
deleted file mode 100644
index f4b6110..0000000
--- a/za-test-make-targets
+++ /dev/null
@@ -1,93 +0,0 @@
-# Copyright (c) 2018 Sebastian Gniazdowski
-
-emulate -LR zsh -o extendedglob
-
-local -a TARGETS match mbegin mend
-
-za-test-make-expandVars() {
- local open close var val front='' rest=$1
-
- while [[ $rest == (#b)[^$]#($)* ]]; do
- front=$front${rest[1,$mbegin[1]-1]}
- rest=${rest[$mbegin[1],-1]}
-
- case $rest[2] in
- ($) # '$$'. may not appear in target and variable's value
- front=$front\$\$
- rest=${rest[3,-1]}
- continue
- ;;
- (\() # Variable of the form $(foobar)
- open='('
- close=')'
- ;;
- ({) # ${foobar}
- open='{'
- close='}'
- ;;
- ([[:alpha:]]) # $foobar. This is exactly $(f)oobar.
- open=''
- close=''
- var=$rest[2]
- ;;
- (*) # bad parameter name
- print -- $front$rest
- return 1
- ;;
- esac
-
- if [[ -n $open ]]; then
- if [[ $rest == \$$open(#b)([[:alnum:]_]##)(#B)$close* ]]; then
- var=$match
- else # unmatched () or {}, or bad parameter name
- print -- $front$rest
- return 1
- fi
- fi
-
- val=''
- if [[ -n ${VAR_ARGS[(i)$var]} ]]; then
- val=${VAR_ARGS[$var]}
- else
- if [[ -n $opt_args[(I)(-e|--environment-overrides)] ]]; then
- if [[ $parameters[$var] == scalar-export* ]]; then
- val=${(P)var}
- elif [[ -n ${VARIABLES[(i)$var]} ]]; then
- val=${VARIABLES[$var]}
- fi
- else
- if [[ -n ${VARIABLES[(i)$var]} ]]; then
- val=${VARIABLES[$var]}
- elif [[ $parameters[$var] == scalar-export* ]]; then
- val=${(P)var}
- fi
- fi
- fi
- rest=${rest//\$$open$var$close/$val}
- done
-
- print -- ${front}${rest}
-}
-
-
-za-test-make-parseMakefile () {
- local input var val target dep TAB=$'\t' tmp IFS=
-
- while read input
- do
- case "$input " in
- # TARGET: dependencies
- # TARGET1 TARGET2 TARGET3: dependencies
- ([[*?[:alnum:]$][^$TAB:=%]#:[^=]*)
- target=$(za-test-make-expandVars ${input%%:*})
- TARGETS+=( ${(z)target} )
- ;;
- esac
- done
-}
-
-za-test-make-parseMakefile < "$1"
-
-reply=( "${(u)TARGETS[@]}" )
-
-# vim:ft=zsh:sw=4:sts=4:et