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