diff --git a/.editorconfig b/.editorconfig index 25ba80b..13d5139 100644 --- a/.editorconfig +++ b/.editorconfig @@ -31,7 +31,12 @@ trim_trailing_whitespace = true insert_final_newline = false trim_trailing_whitespace = false -[*.{sh,bash,zsh,fish}] +[*.{sh,bash,zsh,fish,lzui}] +indent_style = space +indent_size = 2 +tab_width = 2 + +[zui-*] indent_style = space indent_size = 2 tab_width = 2 @@ -60,4 +65,4 @@ max_line_length = 120 [CHANGELOG.md] indent_style = tab -indent_size = 4 \ No newline at end of file +indent_size = 4 diff --git a/.github/.cspell/project-ignored.txt b/.github/.cspell/project-ignored.txt new file mode 100644 index 0000000..0447f92 --- /dev/null +++ b/.github/.cspell/project-ignored.txt @@ -0,0 +1,77 @@ +actlen +addwin +altmark +assgn +autoload +bindkey +bools +BTAB +builtins +cidx +circpath +colorpair +curx +cvar +datetime +delwin +dirpath +elems +ganchor +ganchors +hidx +hpfx +iidx +isset +lanchors +lbox +linerev +lineund +lzui +midx +nmap +nohyp +NONSELECTABLE +nonselectables +obal +regen +Regen +runtimes +SBUFFER +segs +sidx +SIDX +skeys +slist +stalog +stdlib +stext +strftime +syslib +tfield +THEWORD +timestr +trivy +trufflehog +unfunction +usetty +utillib +varname +xpos +ypos +zcurses +zgen +Zgen +zmodload +zstat +zstyle +zuiaction +zuianchor +zuianchoraglobal +zuicheckbox +zuieanchor +zuiel +zuiiaction +zuilbox +ZUILIST +zuilog +zuitfield diff --git a/.github/.cspell/project-words.txt b/.github/.cspell/project-words.txt new file mode 100644 index 0000000..4c43f7c --- /dev/null +++ b/.github/.cspell/project-words.txt @@ -0,0 +1,10 @@ +EPOCHSECONDS +FPATH +mbegin +PMSPEC +setopt +subshell +unsetopt +zcompile +Zshell +ZSTYLES diff --git a/.github/workflows/check_zsh.yml b/.github/workflows/check_zsh.yml new file mode 100644 index 0000000..2b55995 --- /dev/null +++ b/.github/workflows/check_zsh.yml @@ -0,0 +1,53 @@ +--- +name: "✅ Zsh" +on: + push: + branches: [main] + tags: ["v*.*.*"] + paths: + - "*.zsh" + - "*.lzui" + - "functions/*" + pull_request: + paths: + - "*.zsh" + - "*.lzui" + - "functions/*" + workflow_dispatch: {} + +jobs: + zsh-matrix: + runs-on: ubuntu-latest + outputs: + output1: ${{ steps.set-matrix.outputs.files }} + steps: + - name: "⤵️ Check out code from GitHub" + uses: actions/checkout@v4 + - name: "Set matrix output" + id: set-matrix + run: | + MATRIX="$(find . -type d -name 'doc' -prune -o -type f \( -iname '*.zsh' -o -iname '*.lzui' -o -iname 'zui-*' -o -iname '-zui-*' \) -print | jq -ncR '{"include": [{"file": inputs}]}')" + echo "files=${MATRIX}" >> $GITHUB_OUTPUT + + zsh-n: + runs-on: ubuntu-latest + needs: zsh-matrix + strategy: + fail-fast: false + matrix: ${{ fromJSON(needs.zsh-matrix.outputs.output1) }} + steps: + - name: ⤵️ Check out code from GitHub + uses: actions/checkout@v4 + - name: "⚡ Install dependencies" + run: sudo apt update && sudo apt-get install -yq zsh + - name: "⚡ zsh -n: ${{ matrix.file }}" + env: + ZSH_FILE: ${{ matrix.file }} + run: | + zsh -n "${ZSH_FILE}" + - name: "⚡ zcompile ${{ matrix.file }}" + env: + ZSH_FILE: ${{ matrix.file }} + run: | + zsh -fc "zcompile ${ZSH_FILE}"; rc=$? + ls -al "${ZSH_FILE}.zwc"; exit "$rc" diff --git a/.github/workflows/doxygen.yml b/.github/workflows/doxygen.yml index af3c70d..2705d27 100644 --- a/.github/workflows/doxygen.yml +++ b/.github/workflows/doxygen.yml @@ -3,10 +3,12 @@ name: 📖 Doxygen on: push: + branches: [main] paths: - "functions/**" - "lib/**" pull_request: + branches: [main] paths: - "functions/**" - "lib/**" diff --git a/.github/workflows/sync-labels.yml b/.github/workflows/sync-labels.yml index b9b9843..c1b192a 100644 --- a/.github/workflows/sync-labels.yml +++ b/.github/workflows/sync-labels.yml @@ -1,5 +1,5 @@ --- -name: "♻️ Sync Labels" +name: ♻️ Sync Labels on: schedule: @@ -8,5 +8,5 @@ on: jobs: labels: - name: "♻️ Sync labels" + name: ♻️ Sync labels uses: z-shell/.github/.github/workflows/sync-labels.yml@main diff --git a/.github/workflows/trunk_check.yml b/.github/workflows/trunk_check.yml index 67eeadd..0b0df52 100644 --- a/.github/workflows/trunk_check.yml +++ b/.github/workflows/trunk_check.yml @@ -1,23 +1,14 @@ --- -name: "⭕ Trunk" +name: ⭕ Trunk on: push: branches: [main] tags: ["v*.*.*"] pull_request: types: [opened, synchronize] - schedule: - - cron: "0 07 * * 5" workflow_dispatch: {} jobs: check: - if: github.event.schedule != '0 07 * * 5' - name: "⚡" + name: ⚡ uses: z-shell/.github/.github/workflows/trunk.yml@main - upload: - if: github.event.schedule == '0 07 * * 5' - name: "🆙" - uses: z-shell/.github/.github/workflows/trunk.yml@main - secrets: - trunk-token: ${{ secrets.TRUNK_TOKEN }} diff --git a/.markdownlint.yaml b/.markdownlint.yaml deleted file mode 100644 index fb94039..0000000 --- a/.markdownlint.yaml +++ /dev/null @@ -1,10 +0,0 @@ -# Autoformatter friendly markdownlint config (all formatting rules disabled) -default: true -blank_lines: false -bullet: false -html: false -indentation: false -line_length: false -spaces: false -url: false -whitespace: false diff --git a/.trunk/.gitignore b/.trunk/.gitignore new file mode 100644 index 0000000..1e24652 --- /dev/null +++ b/.trunk/.gitignore @@ -0,0 +1,8 @@ +*out +*logs +*actions +*notifications +*tools +plugins +user_trunk.yaml +user.yaml diff --git a/.github/.markdownlint.yaml b/.trunk/configs/.markdownlint.yaml similarity index 100% rename from .github/.markdownlint.yaml rename to .trunk/configs/.markdownlint.yaml diff --git a/.trunk/configs/.yamllint.yaml b/.trunk/configs/.yamllint.yaml new file mode 100644 index 0000000..4d44466 --- /dev/null +++ b/.trunk/configs/.yamllint.yaml @@ -0,0 +1,10 @@ +rules: + quoted-strings: + required: only-when-needed + extra-allowed: ["{|}"] + empty-values: + forbid-in-block-mappings: true + forbid-in-flow-mappings: true + key-duplicates: {} + octal-values: + forbid-implicit-octal: true diff --git a/.trunk/trunk.yaml b/.trunk/trunk.yaml index ac1191b..4141cb7 100644 --- a/.trunk/trunk.yaml +++ b/.trunk/trunk.yaml @@ -1,19 +1,34 @@ +# This file controls the behavior of Trunk: https://docs.trunk.io/cli +# To learn more about the format of this file, see https://docs.trunk.io/reference/trunk-yaml version: 0.1 cli: - version: 0.12.1-beta -repo: - repo: - host: github.com - owner: z-shell - name: zui + version: 1.18.1 +# Trunk provides extensibility via plugins. (https://docs.trunk.io/plugins) +plugins: + sources: + - id: trunk + ref: v1.4.1 + uri: https://github.com/trunk-io/plugins +# Many linters and tools depend on runtime - configure them here. (https://docs.trunk.io/runtimes) +runtimes: + enabled: + - node@18.12.1 + - python@3.10.8 +# This is the section where you manage your linters. (https://docs.trunk.io/check/configuration) lint: + disabled: + - checkov + - yamllint + - trivy + - trufflehog + enabled: + - actionlint@1.6.26 + - git-diff-check + - markdownlint@0.38.0 + - prettier@3.1.1 +actions: enabled: - - actionlint@1.6.13 - - gitleaks@8.8.5 - - markdownlint@0.31.1 - - prettier@2.6.2 - - shfmt@3.4.0 - linters: - - name: markdownlint - command: [markdownlint, -q, --config, .github/.markdownlint.yaml, "${target}"] - direct_configs: [.github/.markdownlint.yaml] + - trunk-announce + - trunk-check-pre-push + - trunk-fmt-pre-commit + - trunk-upgrade-available diff --git a/demos/zui-demo-anchors b/demos/zui-demo-anchors index 903b06a..5d56d5d 100644 --- a/demos/zui-demo-anchors +++ b/demos/zui-demo-anchors @@ -1,3 +1,8 @@ +# -*- mode: zsh; sh-indentation: 2; indent-tabs-mode: nil; sh-basic-offset: 2; -*- +# vim: ft=zsh sw=2 ts=2 et +# +# ZUI demo: anchors +# # Started from Zle or from command line # # Shows all types of anchors: external/regenerating, internal, @@ -5,7 +10,10 @@ -zui_std_cleanup deserialize:"zui-demo-anchors" -zui_std_init app:"zui-demo-anchors" app_name:"ZUI Anchors" -emulate -LR zsh -o extendedglob -o typesetsilent -o warncreateglobal + +builtin emulate -LR zsh +builtin setopt extended_glob typeset_silent warn_create_global + -zui_std_init2 # after emulate -LR -zui_std_store_default_app_config b:border 1 diff --git a/demos/zui-demo-append b/demos/zui-demo-append index 87f74b0..80287bc 100644 --- a/demos/zui-demo-append +++ b/demos/zui-demo-append @@ -1,10 +1,18 @@ +# -*- mode: zsh; sh-indentation: 2; indent-tabs-mode: nil; sh-basic-offset: 2; -*- +# vim: ft=zsh sw=2 ts=2 et +# +# ZUI demo: append +# # Started from Zle or from command line # # A demo showing how to add module instances to already generated document -zui_std_cleanup deserialize:"zui-demo-append" -zui_std_init app:"zui-demo-append" app_name:"ZUI On-The-Fly Append" -emulate -LR zsh -o extendedglob -o typesetsilent -o warncreateglobal + +builtin emulate -LR zsh +builtin setopt extended_glob typeset_silent warn_create_global + -zui_std_init2 # after emulate -LR -zui_std_store_default_app_config b:border 1 @@ -13,22 +21,22 @@ emulate -LR zsh -o extendedglob -o typesetsilent -o warncreateglobal # Generator for module 1 demo_generator_A() { - local mod="$1" ice="$2" - - # Anchor only in last instance - -zui_std_get_mod_factor "$mod" - if [[ "$ice" = "$REPLY" ]]; then - # 1+2 - from 1st line of this module, jump 2 beyond this module - # Regenerate $mod/$ice, and $mod/$ice+1, first running handler - local -a output - -zui_std_anchor "append_next" "1+2" "" ",mod${mod}_ice${ice},mod${mod}_ice$(( ice + 1 ))," "" "${ZUI[MAGENTA]}Append next!${ZUI[FMT_END]}" "-zui_std_set_mod_factor $mod $(( REPLY + 1 ))" output - fi - - # Content - reply=( "This is module $mod, instance $ice" ${output[1]} ) - - # Non-selectable lines Hops to jump with [ and ] Local anchors (if output[1] not empty ...) - reply2=( 1 ) reply3=( 1 ) reply4=( ${output[1]:+append_next} ) + local mod="$1" ice="$2" + + # Anchor only in last instance + -zui_std_get_mod_factor "$mod" + if [[ "$ice" = "$REPLY" ]]; then + # 1+2 - from 1st line of this module, jump 2 beyond this module + # Regenerate $mod/$ice, and $mod/$ice+1, first running handler + local -a output + -zui_std_anchor "append_next" "1+2" "" ",mod${mod}_ice${ice},mod${mod}_ice$(( ice + 1 ))," "" "${ZUI[MAGENTA]}Append next!${ZUI[FMT_END]}" "-zui_std_set_mod_factor $mod $(( REPLY + 1 ))" output + fi + + # Content + reply=( "This is module $mod, instance $ice" ${output[1]} ) + + # Non-selectable lines Hops to jump with [ and ] Local anchors (if output[1] not empty ...) + reply2=( 1 ) reply3=( 1 ) reply4=( ${output[1]:+append_next} ) } ## Start application ## diff --git a/demos/zui-demo-buttons b/demos/zui-demo-buttons index 57dffc4..317ab5d 100644 --- a/demos/zui-demo-buttons +++ b/demos/zui-demo-buttons @@ -1,10 +1,18 @@ +# -*- mode: zsh; sh-indentation: 2; indent-tabs-mode: nil; sh-basic-offset: 2; -*- +# vim: ft=zsh sw=2 ts=2 et +# +# ZUI demo: buttons +# # Started from Zle or from command line # # Shows all types of hyperlinks, from raw-links to internal-inline links -zui_std_cleanup deserialize:"zui-demo-buttons" -zui_std_init app:"zui-demo-buttons" app_name:"ZUI Buttons" -emulate -LR zsh -o extendedglob -o typesetsilent -o warncreateglobal + +builtin emulate -LR zsh +builtin setopt extended_glob typeset_silent warn_create_global + -zui_std_init2 # after emulate -LR -zui_std_store_default_app_config b:border 1 @@ -62,5 +70,3 @@ zui-event-loop 1:demo_generator_A -zui_std_cleanup serialize return 0 - -# vim:ft=zsh diff --git a/demos/zui-demo-configure b/demos/zui-demo-configure index 1d17620..4ac1a8c 100644 --- a/demos/zui-demo-configure +++ b/demos/zui-demo-configure @@ -1,8 +1,16 @@ +# -*- mode: zsh; sh-indentation: 2; indent-tabs-mode: nil; sh-basic-offset: 2; -*- +# vim: ft=zsh sw=2 ts=2 et +# +# ZUI demo: configure/make +# # Started from Zle or from command line -zui_std_cleanup deserialize:"zui-demo-configure" -zui_std_init app:"zui-demo-configure" app_name:"ZUI Configure/Make wrapper" -emulate -LR zsh -o extendedglob -o typesetsilent -o warncreateglobal + +builtin emulate -LR zsh +builtin setopt extended_glob typeset_silent warn_create_global + -zui_std_init2 # after emulate -LR -zui_std_store_default_app_config s:timeout 300 @@ -12,45 +20,45 @@ local -a coproc_output local cstarted=0 mstarted=0 # denote if configure/make is running demo_generator_A() { - local mod="$1" ice="$2" + local mod="$1" ice="$2" - reply=() - -zui_std_rc_button "button1" "${ZUI[MAGENTA]}Run configure${ZUI[FMT_END]}" 'internal=1; coproc 2>&1 ./configure; cstarted=1' - -zui_std_rc_button "button2" "${ZUI[MAGENTA]}Get CFLAGS${ZUI[FMT_END]}" 'internal=1; get_cflags' - -zui_std_rc_button "button3" "${ZUI[MAGENTA]}Run make${ZUI[FMT_END]}" 'internal=1; coproc 2>&1 make; mstarted=1' + reply=() + -zui_std_rc_button "button1" "${ZUI[MAGENTA]}Run configure${ZUI[FMT_END]}" 'internal=1; coproc 2>&1 ./configure; cstarted=1' + -zui_std_rc_button "button2" "${ZUI[MAGENTA]}Get CFLAGS${ZUI[FMT_END]}" 'internal=1; get_cflags' + -zui_std_rc_button "button3" "${ZUI[MAGENTA]}Run make${ZUI[FMT_END]}" 'internal=1; coproc 2>&1 make; mstarted=1' - # Content - reply=( "${reply[1]} ${reply[2]} ${reply[3]}" ) + # Content + reply=( "${reply[1]} ${reply[2]} ${reply[3]}" ) - # Non-selectable lines Hops to jump with [ and ] Local anchors - reply2=( ) reply3=( 1 ) reply4=( ) + # Non-selectable lines Hops to jump with [ and ] Local anchors + reply2=( ) reply3=( 1 ) reply4=( ) } demo_generator_B() { - reply=() - -zui_std_special_text "Configure/Make output" - -zui_std_button "button4" "${ZUI[MAGENTA]}(clear)${ZUI[FMT_END]}" 'internal=1; coproc_output=( ); -zui_std_fly_mod_regen 2 1' - reply=( "${ZUI[YELLOW]}${reply[1]}${ZUI[FMT_END]} ${reply[2]}" "${coproc_output[@]}" ) reply2=( ) reply3=( 1 ) reply4=( ) + reply=() + -zui_std_special_text "Configure/Make output" + -zui_std_button "button4" "${ZUI[MAGENTA]}(clear)${ZUI[FMT_END]}" 'internal=1; coproc_output=( ); -zui_std_fly_mod_regen 2 1' + reply=( "${ZUI[YELLOW]}${reply[1]}${ZUI[FMT_END]} ${reply[2]}" "${coproc_output[@]}" ) reply2=( ) reply3=( 1 ) reply4=( ) } # Read & publish configure/make output -zui-standard-timeout-callback() { - (( mstarted + cstarted == 0 )) && return + (( mstarted + cstarted == 0 )) && return - local line had_read=0 - repeat 20; do - read -r -p -t 0 line 2>/dev/null && { had_read=1; coproc_output+=( "$line" ); } || break - done + local line had_read=0 + repeat 20; do + read -r -p -t 0 line 2>/dev/null && { had_read=1; coproc_output+=( "$line" ); } || break + done - (( had_read )) && -zui_std_fly_mod_regen 2 1 - (( mstarted != 0 && had_read == 0 )) && [[ "${jobtexts[*]}" != *make* ]] && { ZUI[redraw]=1; mstarted=0; -zui_std_stalog "Message: " "make ended"; } - (( cstarted != 0 && had_read == 0 )) && [[ "${jobtexts[*]}" != *configure* ]] && { ZUI[redraw]=1; cstarted=0; -zui_std_stalog "Message: " "configure ended"; } + (( had_read )) && -zui_std_fly_mod_regen 2 1 + (( mstarted != 0 && had_read == 0 )) && [[ "${jobtexts[*]}" != *make* ]] && { ZUI[redraw]=1; mstarted=0; -zui_std_stalog "Message: " "make ended"; } + (( cstarted != 0 && had_read == 0 )) && [[ "${jobtexts[*]}" != *configure* ]] && { ZUI[redraw]=1; cstarted=0; -zui_std_stalog "Message: " "configure ended"; } } get_cflags() { - local CFLAGS=`grep '^CFLAGS[[:space:]]*=' Makefile` - -zui_std_stalog "Obtained: " "CFLAGS = ${CFLAGS#*=[[:space:]]##}" - return 1 + local CFLAGS=`grep '^CFLAGS[[:space:]]*=' Makefile` + -zui_std_stalog "Obtained: " "CFLAGS = ${CFLAGS#*=[[:space:]]##}" + return 1 } ## Start application ## @@ -59,5 +67,3 @@ zui-event-loop 1:demo_generator_A 1:demo_generator_B -zui_std_cleanup serialize return 0 - -# vim:ft=zsh diff --git a/demos/zui-demo-edit b/demos/zui-demo-edit index 3a12e8b..8e1010f 100644 --- a/demos/zui-demo-edit +++ b/demos/zui-demo-edit @@ -1,10 +1,18 @@ +# -*- mode: zsh; sh-indentation: 2; indent-tabs-mode: nil; sh-basic-offset: 2; -*- +# vim: ft=zsh sw=2 ts=2 et +# +# ZUI demo: edit +# # Started from Zle or from command line # # Text editor supporting maximum 1000 lines, 6000 with Zsh 5.3.2 -zui_std_cleanup deserialize:"zui-demo-edit" -zui_std_init app:"zui-demo-edit" app_name:"ZUI Text Editor" -emulate -LR zsh -o extendedglob -o typesetsilent -o warncreateglobal + +builtin emulate -LR zsh +builtin setopt extended_glob typeset_silent warn_create_global + -zui_std_init2 # after emulate -LR -zui_std_store_default_app_config s:status_size 3 @@ -18,34 +26,34 @@ local -a lines logs { lines=( "${(@f)"$(<$edited_file)"}" ); } 2>/dev/null demo_generator_A() { - local mod="$1" ice="$2" + local mod="$1" ice="$2" - reply=() - -zui_std_rc_button "button_save_$ice" "${ZUI[RED]}Save${ZUI[FMT_END]}" 'internal=1; print -rl -- "${lines[@]}" > "$edited_file" && logs+=( "File saved" ) || logs+=( "Save failed" )' - -zui_std_rc_button "button_relo_$ice" "${ZUI[RED]}Reload${ZUI[FMT_END]}" 'internal=1; lines=( "${(@f)"$(<$edited_file)"}" ) && logs+=( "File \`$edited_file'"'"' loaded" ); -zui_std_fly_mod_regen 2 1' - -zui_std_rc_button "button_addl_$ice" "${ZUI[RED]}Add line${ZUI[FMT_END]}" 'internal=1; lines+=( "" ); -zui_std_fly_mod_regen 2 1' - -zui_std_rc_button "button_remo_$ice" "${ZUI[RED]}Remove line${ZUI[FMT_END]}" 'internal=1; lines[-1]=( ); -zui_std_fly_mod_regen 2 1' + reply=() + -zui_std_rc_button "button_save_$ice" "${ZUI[RED]}Save${ZUI[FMT_END]}" 'internal=1; print -rl -- "${lines[@]}" > "$edited_file" && logs+=( "File saved" ) || logs+=( "Save failed" )' + -zui_std_rc_button "button_relo_$ice" "${ZUI[RED]}Reload${ZUI[FMT_END]}" 'internal=1; lines=( "${(@f)"$(<$edited_file)"}" ) && logs+=( "File \`$edited_file'"'"' loaded" ); -zui_std_fly_mod_regen 2 1' + -zui_std_rc_button "button_addl_$ice" "${ZUI[RED]}Add line${ZUI[FMT_END]}" 'internal=1; lines+=( "" ); -zui_std_fly_mod_regen 2 1' + -zui_std_rc_button "button_remo_$ice" "${ZUI[RED]}Remove line${ZUI[FMT_END]}" 'internal=1; lines[-1]=( ); -zui_std_fly_mod_regen 2 1' - # Content - reply=( "${ZUI[YELLOW]}$edited_file${ZUI[FMT_END]}" "${reply[*]}" ) + # Content + reply=( "${ZUI[YELLOW]}$edited_file${ZUI[FMT_END]}" "${reply[*]}" ) - # Non-selectable lines Hops to jump with [ and ] Local anchors - reply2=( 1 ) reply3=( 1 ) reply4=( ) + # Non-selectable lines Hops to jump with [ and ] Local anchors + reply2=( 1 ) reply3=( 1 ) reply4=( ) } demo_generator_B() { - local mod="$1" ice="$2" - - integer size=${#lines} idx - local -a output - for (( idx=1; idx <= size; idx ++ )); do - reply=() # use the output immediately to utilize array-append optimizations of zsh 5.3.2 - noglob -zui_std_text_field "tfield${idx}" width offset lines[$idx] - output+=( "${reply[1]}" ) - done - - # Content Non-selectable lines Hops to jump with [ and ] Local anchors - reply=( $output ) reply2=( ) reply3=( 1 ) reply4=( ) + local mod="$1" ice="$2" + + integer size=${#lines} idx + local -a output + for (( idx=1; idx <= size; idx ++ )); do + reply=() # use the output immediately to utilize array-append optimizations of zsh 5.3.2 + noglob -zui_std_text_field "tfield${idx}" width offset lines[$idx] + output+=( "${reply[1]}" ) + done + + # Content Non-selectable lines Hops to jump with [ and ] Local anchors + reply=( $output ) reply2=( ) reply3=( 1 ) reply4=( ) } -zui-standard-status-callback() { [[ "${#logs}" -gt 0 ]] && { reply=( "Message: " "${logs[1]}" ); logs=( ${(@)logs[2,-1]} ); return 1; }; return 0; } @@ -56,5 +64,3 @@ zui-event-loop 1:demo_generator_A 1:demo_generator_B 1:demo_generator_A -zui_std_cleanup serialize return 0 - -# vim:ft=zsh diff --git a/demos/zui-demo-fly b/demos/zui-demo-fly index c16a0b7..2f5cf34 100644 --- a/demos/zui-demo-fly +++ b/demos/zui-demo-fly @@ -1,8 +1,16 @@ +# -*- mode: zsh; sh-indentation: 2; indent-tabs-mode: nil; sh-basic-offset: 2; -*- +# vim: ft=zsh sw=2 ts=2 et +# +# ZUI demo: fly +# # Started from Zle or from command line -zui_std_cleanup deserialize:"zui-demo-fly" -zui_std_init app:"zui-demo-fly" app_name:"ZUI On-The-Fly Regeneration" -emulate -LR zsh -o extendedglob -o typesetsilent -o warncreateglobal + +builtin emulate -LR zsh +builtin setopt extended_glob typeset_silent warn_create_global + -zui_std_init2 # after emulate -LR -zui_std_store_default_app_config b:border 1 @@ -13,31 +21,31 @@ local internal # trick variable to make a handler no-restart # Generator for module 1 demo_generator_A() { - local mod="$1" ice="$2" + local mod="$1" ice="$2" - reply=() - -zui_std_rc_button_ext "restart" "" "" ",mod1_ice1," "" "${ZUI[MAGENTA]}restart${ZUI[FMT_END]}" - -zui_std_rc_button "on-the-fly" "${ZUI[MAGENTA]}on-the-fly${ZUI[FMT_END]}" 'internal=1; -zui_std_fly_mod_regen "'"$mod"'" "'"$ice"'"' + reply=() + -zui_std_rc_button_ext "restart" "" "" ",mod1_ice1," "" "${ZUI[MAGENTA]}restart${ZUI[FMT_END]}" + -zui_std_rc_button "on-the-fly" "${ZUI[MAGENTA]}on-the-fly${ZUI[FMT_END]}" 'internal=1; -zui_std_fly_mod_regen "'"$mod"'" "'"$ice"'"' - # Content - reply=( "${ZUI[YELLOW]}ZUI${ZUI[FMT_END]} can regenerate module instance with ${reply[1]} or ${reply[2]}!" "Random number: $RANDOM" ) + # Content + reply=( "${ZUI[YELLOW]}ZUI${ZUI[FMT_END]} can regenerate module instance with ${reply[1]} or ${reply[2]}!" "Random number: $RANDOM" ) - # Non-selectable lines Hops to jump with [ and ] Local anchors - reply2=( 2 ) reply3=( 1 ) reply4=( ) + # Non-selectable lines Hops to jump with [ and ] Local anchors + reply2=( 2 ) reply3=( 1 ) reply4=( ) } # Show handler code in status window -zui-standard-status-callback() { - local tpe="$1" selectable="$2" uniq="$3" search="$4" line="$5" segment="$6" - [[ "$tpe" = "0" ]] && return 0 # Filter out non-hyperlinks + local tpe="$1" selectable="$2" uniq="$3" search="$4" line="$5" segment="$6" + [[ "$tpe" = "0" ]] && return 0 # Filter out non-hyperlinks - shift 6; local id="$1" data1="$2" data2="$3" data3="$4" data4="$5" - id="${id#(zuiiaction|zuiaction|zuicheckbox|zuieanchor|zuianchor|zuitfield)}" - handler="${ZUI[zuiiaction$id]}" - reply=( "Handler: " "$handler" ) + shift 6; local id="$1" data1="$2" data2="$3" data3="$4" data4="$5" + id="${id#(zuiiaction|zuiaction|zuicheckbox|zuieanchor|zuianchor|zuitfield)}" + handler="${ZUI[zuiiaction$id]}" + reply=( "Handler: " "$handler" ) - # Resulting type: 1 - log message - return 1 + # Resulting type: 1 - log message + return 1 } ## Start application ## @@ -46,5 +54,3 @@ zui-event-loop 1:demo_generator_A -zui_std_cleanup serialize return 0 - -# vim:ft=zsh diff --git a/demos/zui-demo-ganchors b/demos/zui-demo-ganchors index e3ea3e6..33581b5 100644 --- a/demos/zui-demo-ganchors +++ b/demos/zui-demo-ganchors @@ -1,35 +1,43 @@ +# -*- mode: zsh; sh-indentation: 2; indent-tabs-mode: nil; sh-basic-offset: 2; -*- +# vim: ft=zsh sw=2 ts=2 et +# +# ZUI demo: global anchors +# # Started from Zle or from command line -zui_std_cleanup deserialize:"zui-demo-ganchors" -zui_std_init app:"zui-demo-ganchors" app_name:"ZUI Global Anchors" -emulate -LR zsh -o extendedglob -o typesetsilent -o warncreateglobal + +builtin emulate -LR zsh +builtin setopt extended_glob typeset_silent warn_create_global + -zui_std_init2 # after emulate -LR -zui_std_store_default_app_config b:text_mode off -zui_std_store_default_app_config b:top_anchors 0 # no top-anchors demo_generator_A() { - local mod="$1" ice="$2" + local mod="$1" ice="$2" - reply=() - -zui_std_get_ganchor 2 1 "[Module2]" - -zui_std_get_ganchor 3 1 "[Module3]" - -zui_std_get_ganchor 4 1 "[Module4/1]" - -zui_std_get_ganchor 4 2 "[Module4/2]" + reply=() + -zui_std_get_ganchor 2 1 "[Module2]" + -zui_std_get_ganchor 3 1 "[Module3]" + -zui_std_get_ganchor 4 1 "[Module4/1]" + -zui_std_get_ganchor 4 2 "[Module4/2]" - # Content - reply=( "There are no top-anchors, but you can fetch them and use in modules:" "" "Jump to ${reply[1]}, ${reply[2]}, ${reply[3]}, ${reply[4]}" ) + # Content + reply=( "There are no top-anchors, but you can fetch them and use in modules:" "" "Jump to ${reply[1]}, ${reply[2]}, ${reply[3]}, ${reply[4]}" ) - # Non-selectable lines Hops to jump with [ and ] Local anchors - reply2=( 1 2 ) reply3=( 1 ) reply4=( ) + # Non-selectable lines Hops to jump with [ and ] Local anchors + reply2=( 1 2 ) reply3=( 1 ) reply4=( ) } # Generator for module 1 demo_generator_B() { - local mod="$1" ice="$2" + local mod="$1" ice="$2" - # Content, no hyper-links Non-selectable lines Hops to jump with [ and ] Local anchors - reply=( "-> Module $mod, instance $ice." ) reply2=( ) reply3=( 1 ) reply4=( ) + # Content, no hyper-links Non-selectable lines Hops to jump with [ and ] Local anchors + reply=( "-> Module $mod, instance $ice." ) reply2=( ) reply3=( 1 ) reply4=( ) } ## Start application ## @@ -38,5 +46,3 @@ zui-event-loop 1:demo_generator_A 1:demo_generator_B 1:demo_generator_B 2:demo_g -zui_std_cleanup serialize return 0 - -# vim:ft=zsh diff --git a/demos/zui-demo-hello-world b/demos/zui-demo-hello-world index 941557f..70f1e6c 100644 --- a/demos/zui-demo-hello-world +++ b/demos/zui-demo-hello-world @@ -1,21 +1,26 @@ +# -*- mode: zsh; sh-indentation: 2; indent-tabs-mode: nil; sh-basic-offset: 2; -*- +# vim: ft=zsh sw=2 ts=2 et +# # Started from Zle or from command line -zui_std_cleanup deserialize:"zui-demo-hello-world" -zui_std_init app:"zui-demo-hello-world" app_name:"ZUI Hello World" -emulate -LR zsh -o extendedglob -o typesetsilent -o warncreateglobal --zui_std_init2 # after emulate -LR +builtin emulate -LR zsh +builtin setopt extended_glob typeset_silent warn_create_global + +-zui_std_init2 # after emulate -LR -zui_std_store_default_app_config b:border 1 # Generator for module 1 demo_generator_A() { - local mod="$1" ice="$2" + local mod="$1" ice="$2" - # Content, no hyper-links - reply=( "Hello World from ${ZUI[YELLOW]}ZUI${ZUI[FMT_END]}! Module $mod, instance $ice." ) + # Content, no hyper-links + reply=( "Hello World from ${ZUI[YELLOW]}ZUI${ZUI[FMT_END]}! Module $mod, instance $ice." ) - # Non-selectable lines Hops to jump with [ and ] Local anchors - reply2=( ) reply3=( 1 ) reply4=( ) + # Non-selectable lines Hops to jump with [ and ] Local anchors + reply2=( ) reply3=( 1 ) reply4=( ) } ## Start application ## @@ -24,5 +29,3 @@ zui-event-loop 1:demo_generator_A -zui_std_cleanup serialize return 0 - -# vim:ft=zsh diff --git a/demos/zui-demo-history b/demos/zui-demo-history index 9c85a70..db37474 100644 --- a/demos/zui-demo-history +++ b/demos/zui-demo-history @@ -1,8 +1,16 @@ +# -*- mode: zsh; sh-indentation: 2; indent-tabs-mode: nil; sh-basic-offset: 2; -*- +# vim: ft=zsh sw=2 ts=2 et +# +# ZUI demo: history +# # Started from Zle or from command line -zui_std_cleanup deserialize:"zui-demo-history" -zui_std_init app:"zui-demo-history" app_name:"ZUI History" -emulate -LR zsh -o extendedglob -o typesetsilent -o warncreateglobal + +builtin emulate -LR zsh +builtin setopt extended_glob typeset_silent warn_create_global + -zui_std_init2 # after emulate -LR -zui_std_store_default_app_config b:border 1 @@ -34,5 +42,3 @@ print -zr -- "$REPLY" -zui_std_cleanup serialize return 0 - -# vim:ft=zsh diff --git a/demos/zui-demo-list-boxes b/demos/zui-demo-list-boxes index 042001e..080d5ce 100644 --- a/demos/zui-demo-list-boxes +++ b/demos/zui-demo-list-boxes @@ -1,8 +1,16 @@ +# -*- mode: zsh; sh-indentation: 2; indent-tabs-mode: nil; sh-basic-offset: 2; -*- +# vim: ft=zsh sw=2 ts=2 et +# +# ZUI demo: list-boxes +# # Started from Zle or from command line -zui_std_cleanup deserialize:"zui-demo-list-boxes" -zui_std_init app:"zui-demo-list-boxes" app_name:"ZUI List-Boxes" -emulate -LR zsh -o extendedglob -o typesetsilent -o warncreateglobal + +builtin emulate -LR zsh +builtin setopt extended_glob typeset_silent warn_create_global + -zui_std_init2 # after emulate -LR -zui_std_store_default_app_config b:border 1 @@ -13,21 +21,21 @@ local xtra # extra line of text, loaded from list box # Generator for module 1 demo_generator_A() { - local mod="$1" ice="$2" + local mod="$1" ice="$2" - # Variables of the list box - (( ${+ZUI[my_lbox1_width]} == 0 )) && ZUI[my_lbox1_width]=8 - (( ${+ZUI[my_lbox1_idx]} == 0 )) && ZUI[my_lbox1_idx]=2 - (( ${+ZUI[my_lbox1_opts]} == 0 )) && ZUI[my_lbox1_opts]="Option 1;Option 2;Option 3" + # Variables of the list box + (( ${+ZUI[my_lbox1_width]} == 0 )) && ZUI[my_lbox1_width]=8 + (( ${+ZUI[my_lbox1_idx]} == 0 )) && ZUI[my_lbox1_idx]=2 + (( ${+ZUI[my_lbox1_opts]} == 0 )) && ZUI[my_lbox1_opts]="Option 1;Option 2;Option 3" - reply=() - noglob -zui_std_list_box "lbox1_$mod" ZUI[my_lbox1_width] ZUI[my_lbox1_idx] ZUI[my_lbox1_opts] "" "" "" 'xtra="Received: ${ZUI[CYAN]}${${(s:;:)ZUI[my_lbox1_opts]}[${ZUI[my_lbox1_idx]}]}${ZUI[FMT_END]}"; -zui_std_fly_mod_regen "'"$mod"'" "'"$ice"'"' + reply=() + noglob -zui_std_list_box "lbox1_$mod" ZUI[my_lbox1_width] ZUI[my_lbox1_idx] ZUI[my_lbox1_opts] "" "" "" 'xtra="Received: ${ZUI[CYAN]}${${(s:;:)ZUI[my_lbox1_opts]}[${ZUI[my_lbox1_idx]}]}${ZUI[FMT_END]}"; -zui_std_fly_mod_regen "'"$mod"'" "'"$ice"'"' - # Content - reply=( "${ZUI[YELLOW]}ZUI${ZUI[FMT_END]} list-box example: <${reply[1]}>" $xtra ) + # Content + reply=( "${ZUI[YELLOW]}ZUI${ZUI[FMT_END]} list-box example: <${reply[1]}>" $xtra ) - # Non-selectable lines Hops to jump with [ and ] Local anchors - reply2=( ${xtra:+2} ) reply3=( 1 ) reply4=( ) + # Non-selectable lines Hops to jump with [ and ] Local anchors + reply2=( ${xtra:+2} ) reply3=( 1 ) reply4=( ) } ## Start application ## @@ -36,5 +44,3 @@ zui-event-loop 1:demo_generator_A -zui_std_cleanup serialize return 0 - -# vim:ft=zsh diff --git a/demos/zui-demo-nmap b/demos/zui-demo-nmap index 20ef374..e7b3b6d 100644 --- a/demos/zui-demo-nmap +++ b/demos/zui-demo-nmap @@ -1,8 +1,16 @@ +# -*- mode: zsh; sh-indentation: 2; indent-tabs-mode: nil; sh-basic-offset: 2; -*- +# vim: ft=zsh:syntax=sh sw=2 ts=2 et +# +# ZUI demo: nmap TUI +# # Started from Zle or from command line -zui_std_cleanup deserialize:"zui-demo-nmap" -zui_std_init app:"zui-demo-nmap" app_name:"ZUI Nmap TUI" -emulate -LR zsh -o extendedglob -o typesetsilent -o warncreateglobal + +builtin emulate -LR zsh +builtin setopt extended_glob typeset_silent warn_create_global + -zui_std_init2 # after emulate -LR -zui_std_store_default_app_config s:timeout 300 @@ -20,95 +28,95 @@ hosts=( "${(@f)"$(<$cfg_dir/hosts.txt)"}" ) [[ -z "${hosts[1]}" ]] && { hosts[1]="127.0.0.1"; hosts[2]="192.168.0.*"; } demo_generator_A() { - local mod="$1" ice="$2" - - reply=() - -zui_std_rc_button "Abutton1" "${ZUI[MAGENTA]}Run nmap${ZUI[FMT_END]}" 'internal=1; run_sudo; report_options; run_nmap; ZUI[redraw]=1' - -zui_std_rc_button "Abutton2" "${ZUI[MAGENTA]}Add set${ZUI[FMT_END]}" 'internal=1; opts+=( "" ); -zui_std_fly_mod_regen 1 1' - -zui_std_rc_button "Abutton3" "${ZUI[MAGENTA]}Remove set${ZUI[FMT_END]}" 'internal=1; opts[-1]=(); -zui_std_fly_mod_regen 1 1' - -zui_std_rc_button "Abutton4" "${ZUI[MAGENTA]}Save${ZUI[FMT_END]}" 'internal=1; print -rl -- ${opts[@]} > $cfg_dir/opts.txt; opts=( ${opts[@]} ); -zui_std_fly_mod_regen 1 1' - -zui_std_rc_button "Abutton5" "${ZUI[YELLOW]}Add ->${ZUI[FMT_END]}" 'internal=1; hosts+=( "${ZUI[my_host_data]}" ); print -rl -- "${hosts[@]}" > $cfg_dir/hosts.txt; -zui_std_fly_mod_regen 1 1' - -zui_std_rc_button "Abutton6" "${ZUI[YELLOW]}<- Delete${ZUI[FMT_END]}" 'internal=1; hosts[${ZUI[my_select_idx]}]=(); print -rl -- "${hosts[@]}" > $cfg_dir/hosts.txt; ZUI[my_select_idx]=1; -zui_std_fly_mod_regen 1 1' - - ZUI[my_host_width]=35 - ZUI[my_host_idx]=1 - (( ${+ZUI[my_host_data]} == 0 )) && ZUI[my_host_data]="" - noglob -zui_std_text_field "Atextfield1" ZUI[my_host_width] ZUI[my_host_idx] ZUI[my_host_data] - - ZUI[my_select_width]=30 - (( ${+ZUI[my_select_idx]} == 0 )) && ZUI[my_select_idx]=1 - ZUI[my_select_data]=${(j,;,)hosts} - noglob -zui_std_list_box "Alistbox1" ZUI[my_select_width] ZUI[my_select_idx] ZUI[my_select_data] "" "" "" 'ZUI[my_host_data]=${${(As,;,)ZUI[my_select_data]}[${ZUI[my_select_idx]}]}' - - integer size=${#opts} i - for (( i=1; i<=size; ++i )); do - ZUI[my_line_width_$i]=50 - ZUI[my_line_idx_$i]=1 - noglob -zui_std_text_field "line_$i" ZUI[my_line_width_$i] ZUI[my_line_idx_$i] opts[$i] "" "" "" "set_opts $i" - done - - # Content - reply=( "${reply[1]}" "" - "Host: ${reply[7]} ${reply[5]} Choose: ${reply[8]} ${reply[6]}" - "" - "${ZUI[RED]}Option-sets (edit to activate)${ZUI[FMT_END]} ${reply[2]} ${reply[3]} ${reply[4]}" - "${(@)reply[9,-1]}" - ) - - # Non-selectable lines Hops to jump with [ and ] Local anchors - reply2=( ) reply3=( 1 ) reply4=( ) + local mod="$1" ice="$2" + + reply=() + -zui_std_rc_button "Abutton1" "${ZUI[MAGENTA]}Run nmap${ZUI[FMT_END]}" 'internal=1; run_sudo; report_options; run_nmap; ZUI[redraw]=1' + -zui_std_rc_button "Abutton2" "${ZUI[MAGENTA]}Add set${ZUI[FMT_END]}" 'internal=1; opts+=( "" ); -zui_std_fly_mod_regen 1 1' + -zui_std_rc_button "Abutton3" "${ZUI[MAGENTA]}Remove set${ZUI[FMT_END]}" 'internal=1; opts[-1]=(); -zui_std_fly_mod_regen 1 1' + -zui_std_rc_button "Abutton4" "${ZUI[MAGENTA]}Save${ZUI[FMT_END]}" 'internal=1; print -rl -- ${opts[@]} > $cfg_dir/opts.txt; opts=( ${opts[@]} ); -zui_std_fly_mod_regen 1 1' + -zui_std_rc_button "Abutton5" "${ZUI[YELLOW]}Add ->${ZUI[FMT_END]}" 'internal=1; hosts+=( "${ZUI[my_host_data]}" ); print -rl -- "${hosts[@]}" > $cfg_dir/hosts.txt; -zui_std_fly_mod_regen 1 1' + -zui_std_rc_button "Abutton6" "${ZUI[YELLOW]}<- Delete${ZUI[FMT_END]}" 'internal=1; hosts[${ZUI[my_select_idx]}]=(); print -rl -- "${hosts[@]}" > $cfg_dir/hosts.txt; ZUI[my_select_idx]=1; -zui_std_fly_mod_regen 1 1' + + ZUI[my_host_width]=35 + ZUI[my_host_idx]=1 + (( ${+ZUI[my_host_data]} == 0 )) && ZUI[my_host_data]="" + noglob -zui_std_text_field "Atextfield1" ZUI[my_host_width] ZUI[my_host_idx] ZUI[my_host_data] + + ZUI[my_select_width]=30 + (( ${+ZUI[my_select_idx]} == 0 )) && ZUI[my_select_idx]=1 + ZUI[my_select_data]=${(j,;,)hosts} + noglob -zui_std_list_box "Alistbox1" ZUI[my_select_width] ZUI[my_select_idx] ZUI[my_select_data] "" "" "" 'ZUI[my_host_data]=${${(As,;,)ZUI[my_select_data]}[${ZUI[my_select_idx]}]}' + + integer size=${#opts} i + for (( i=1; i<=size; ++i )); do + ZUI[my_line_width_$i]=50 + ZUI[my_line_idx_$i]=1 + noglob -zui_std_text_field "line_$i" ZUI[my_line_width_$i] ZUI[my_line_idx_$i] opts[$i] "" "" "" "set_opts $i" + done + + # Content + reply=( "${reply[1]}" "" + "Host: ${reply[7]} ${reply[5]} Choose: ${reply[8]} ${reply[6]}" + "" + "${ZUI[RED]}Option-sets (edit to activate)${ZUI[FMT_END]} ${reply[2]} ${reply[3]} ${reply[4]}" + "${(@)reply[9,-1]}" + ) + + # Non-selectable lines Hops to jump with [ and ] Local anchors + reply2=( ) reply3=( 1 ) reply4=( ) } demo_generator_B() { - reply=() - -zui_std_button "Bbutton1" "${ZUI[MAGENTA]}(clear)${ZUI[FMT_END]}" 'internal=1; coproc_output=( ); -zui_std_fly_mod_regen 2 1' - -zui_std_button "Bbutton2" "${ZUI[MAGENTA]}Save${ZUI[FMT_END]}" 'internal=1; print -rl -- "${coproc_output[@]}" > ${~ZUI[my_path_data]}; -zui_std_stalog "Saved to: " ${~ZUI[my_path_data]}' + reply=() + -zui_std_button "Bbutton1" "${ZUI[MAGENTA]}(clear)${ZUI[FMT_END]}" 'internal=1; coproc_output=( ); -zui_std_fly_mod_regen 2 1' + -zui_std_button "Bbutton2" "${ZUI[MAGENTA]}Save${ZUI[FMT_END]}" 'internal=1; print -rl -- "${coproc_output[@]}" > ${~ZUI[my_path_data]}; -zui_std_stalog "Saved to: " ${~ZUI[my_path_data]}' - ZUI[my_path_width]=20 - ZUI[my_path_idx]=1 - (( ${+ZUI[my_path_data]} == 0 )) && ZUI[my_path_data]="~/scan.txt" - noglob -zui_std_text_field "Atextfield1" ZUI[my_path_width] ZUI[my_path_idx] ZUI[my_path_data] + ZUI[my_path_width]=20 + ZUI[my_path_idx]=1 + (( ${+ZUI[my_path_data]} == 0 )) && ZUI[my_path_data]="~/scan.txt" + noglob -zui_std_text_field "Atextfield1" ZUI[my_path_width] ZUI[my_path_idx] ZUI[my_path_data] - reply=( "${ZUI[YELLOW]}Nmap output${ZUI[FMT_END]} ${reply[1]} ${reply[3]} ${reply[2]}" "${coproc_output[@]}" ) reply2=( ) reply3=( 1 ) reply4=( ) + reply=( "${ZUI[YELLOW]}Nmap output${ZUI[FMT_END]} ${reply[1]} ${reply[3]} ${reply[2]}" "${coproc_output[@]}" ) reply2=( ) reply3=( 1 ) reply4=( ) } # Read & publish configure/make output -zui-standard-timeout-callback() { - (( nstarted == 0 )) && return + (( nstarted == 0 )) && return - local line had_read=0 - repeat 20; do - read -r -p -t 0 line 2>/dev/null && { had_read=1; coproc_output+=( "$line" ); } || break - done + local line had_read=0 + repeat 20; do + read -r -p -t 0 line 2>/dev/null && { had_read=1; coproc_output+=( "$line" ); } || break + done - (( had_read == 1 )) && -zui_std_fly_mod_regen 2 1 - (( had_read == 0 )) && [[ "${jobtexts[*]}" != *nmap* ]] && { ZUI[redraw]=1; nstarted=0; -zui_std_stalog "Message: " "nmap ended"; } + (( had_read == 1 )) && -zui_std_fly_mod_regen 2 1 + (( had_read == 0 )) && [[ "${jobtexts[*]}" != *nmap* ]] && { ZUI[redraw]=1; nstarted=0; -zui_std_stalog "Message: " "nmap ended"; } } run_sudo() { - zcurses end - sudo true - zcurses refresh + zcurses end + sudo true + zcurses refresh } report_options() { - -zui_std_stalog "Using options: " ${ZUI[my_nmap_options]} " to scan host(s): " ${ZUI[my_host_data]} - if [[ "${#coproc_output}" -gt 0 ]]; then - coproc_output+=( "${ZUI[YELLOW]}"------------------------------------------------------------------------"${ZUI[FMT_END]}" ) - fi + -zui_std_stalog "Using options: " ${ZUI[my_nmap_options]} " to scan host(s): " ${ZUI[my_host_data]} + if [[ "${#coproc_output}" -gt 0 ]]; then + coproc_output+=( "${ZUI[YELLOW]}"------------------------------------------------------------------------"${ZUI[FMT_END]}" ) + fi } run_nmap() { - [[ -z "${ZUI[my_nmap_options]}" ]] && { -zui_std_stalog "No options selected, not running"; return; } - [[ -z "${ZUI[my_host_data]}" || "${ZUI[my_host_data]}" = "&1 sudo nmap ${=ZUI[my_nmap_options]} ${ZUI[my_host_data]%%[[:space:]]##\#*} + nstarted=1 + coproc 2>&1 sudo nmap ${=ZUI[my_nmap_options]} ${ZUI[my_host_data]%%[[:space:]]##\#*} } set_opts() { - local index="$1" - ZUI[my_nmap_options]="${opts[index]%%[[:space:]]#\#*}" + local index="$1" + ZUI[my_nmap_options]="${opts[index]%%[[:space:]]#\#*}" } ZUI[COLORING_PATTERN]="(PORT|STATE|SERVICE|VERSION|NetBIOS)" ZUI[COLORING_MATCH_MULTIPLE]=1 @@ -118,5 +126,3 @@ zui-event-loop 1:demo_generator_A 1:demo_generator_B -zui_std_cleanup serialize return 0 - -# vim:ft=zsh:syntax=sh diff --git a/demos/zui-demo-special-text b/demos/zui-demo-special-text index a0aa3f8..a472bc1 100644 --- a/demos/zui-demo-special-text +++ b/demos/zui-demo-special-text @@ -1,10 +1,18 @@ +# -*- mode: zsh; sh-indentation: 2; indent-tabs-mode: nil; sh-basic-offset: 2; -*- +# vim: ft=zsh sw=2 ts=2 et +# +# ZUI demo: special text +# # Started from Zle or from command line # # Shows how to embed a text with special characters -zui_std_cleanup deserialize:"zui-demo-buttons" -zui_std_init app:"zui-demo-buttons" app_name:"ZUI Buttons" -emulate -LR zsh -o extendedglob -o typesetsilent -o warncreateglobal + +builtin emulate -LR zsh +builtin setopt extended_glob typeset_silent warn_create_global + -zui_std_init2 # after emulate -LR -zui_std_store_default_app_config b:text_select 1 @@ -12,28 +20,28 @@ emulate -LR zsh -o extendedglob -o typesetsilent -o warncreateglobal local internal # trick variable to make a handler no-restart demo_generator_A() { - local mod="$1" ice="$2" arg="$3" + local mod="$1" ice="$2" arg="$3" - reply=() - -zui_std_special_text "Here's" - -zui_std_rc_button "button1" "${ZUI[MAGENTA]}button1${ZUI[FMT_END]}" 'internal=1; -zui_std_stalog "Button 1 pressed"' - -zui_std_rc_button "button2" "${ZUI[MAGENTA]}button2${ZUI[FMT_END]}" 'internal=1; -zui_std_stalog "Button 2 pressed"' + reply=() + -zui_std_special_text "Here's" + -zui_std_rc_button "button1" "${ZUI[MAGENTA]}button1${ZUI[FMT_END]}" 'internal=1; -zui_std_stalog "Button 1 pressed"' + -zui_std_rc_button "button2" "${ZUI[MAGENTA]}button2${ZUI[FMT_END]}" 'internal=1; -zui_std_stalog "Button 2 pressed"' - reply=( "BROKEN: Here's special text, ${reply[2]} and ${reply[3]}" - "CORRECT: ${reply[1]} special text, ${reply[2]} and ${reply[3]}" ) + reply=( "BROKEN: Here's special text, ${reply[2]} and ${reply[3]}" + "CORRECT: ${reply[1]} special text, ${reply[2]} and ${reply[3]}" ) - # Non-selectable lines Hops to jump with [ and ] Local anchors - reply2=( ) reply3=( 1 ) reply4=( ) + # Non-selectable lines Hops to jump with [ and ] Local anchors + reply2=( ) reply3=( 1 ) reply4=( ) } -zui-standard-status-callback() { - [[ -n "${ZUI[pure_text_selected]}" ]] && { - REPLY="${ZUI[pure_text_selected]}" - -zui_std_get_stext "$REPLY" # no change to REPLY if no special text - reply=( "Text: " "$REPLY" ) - return 1 - } - return 0 # no message + [[ -n "${ZUI[pure_text_selected]}" ]] && { + REPLY="${ZUI[pure_text_selected]}" + -zui_std_get_stext "$REPLY" # no change to REPLY if no special text + reply=( "Text: " "$REPLY" ) + return 1 + } + return 0 # no message } ## Start application ## @@ -42,5 +50,3 @@ zui-event-loop 1:demo_generator_A -zui_std_cleanup serialize return 0 - -# vim:ft=zsh diff --git a/demos/zui-demo-text-fields b/demos/zui-demo-text-fields index e3e7d2b..af35efd 100644 --- a/demos/zui-demo-text-fields +++ b/demos/zui-demo-text-fields @@ -1,8 +1,16 @@ +# -*- mode: zsh; sh-indentation: 2; indent-tabs-mode: nil; sh-basic-offset: 2; -*- +# vim: ft=zsh sw=2 ts=2 et +# +# ZUI demo: text fields +# # Started from Zle or from command line -zui_std_cleanup deserialize:"zui-demo-text-fields" -zui_std_init app:"zui-demo-text-fields" app_name:"ZUI Text Fields" -emulate -LR zsh -o extendedglob -o typesetsilent -o warncreateglobal + +builtin emulate -LR zsh +builtin setopt extended_glob typeset_silent warn_create_global + -zui_std_init2 # after emulate -LR -zui_std_store_default_app_config b:border 1 @@ -13,21 +21,21 @@ local xtra # extra line of text, loaded from text field # Generator for module 1 demo_generator_A() { - local mod="$1" ice="$2" + local mod="$1" ice="$2" - # Variables of the text field - (( ${+ZUI[my_tfield1_width]} == 0 )) && ZUI[my_tfield1_width]=50 - (( ${+ZUI[my_tfield1_start]} == 0 )) && ZUI[my_tfield1_start]=1 - (( ${+ZUI[my_tfield1_data]} == 0 )) && ZUI[my_tfield1_data]="Enter accepts, ESC cancels, UP/DOWN resizes" + # Variables of the text field + (( ${+ZUI[my_tfield1_width]} == 0 )) && ZUI[my_tfield1_width]=50 + (( ${+ZUI[my_tfield1_start]} == 0 )) && ZUI[my_tfield1_start]=1 + (( ${+ZUI[my_tfield1_data]} == 0 )) && ZUI[my_tfield1_data]="Enter accepts, ESC cancels, UP/DOWN resizes" - reply=() - noglob -zui_std_text_field "tfield1_$mod" ZUI[my_tfield1_width] ZUI[my_tfield1_start] ZUI[my_tfield1_data] "" "" "" 'xtra="Received text: ${ZUI[CYAN]}${ZUI[my_tfield1_data]}${ZUI[FMT_END]}"; -zui_std_fly_mod_regen "'"$mod"'" "'"$ice"'"' + reply=() + noglob -zui_std_text_field "tfield1_$mod" ZUI[my_tfield1_width] ZUI[my_tfield1_start] ZUI[my_tfield1_data] "" "" "" 'xtra="Received text: ${ZUI[CYAN]}${ZUI[my_tfield1_data]}${ZUI[FMT_END]}"; -zui_std_fly_mod_regen "'"$mod"'" "'"$ice"'"' - # Content - reply=( "${ZUI[YELLOW]}ZUI${ZUI[FMT_END]} text-field example: ${reply[1]}" $xtra ) + # Content + reply=( "${ZUI[YELLOW]}ZUI${ZUI[FMT_END]} text-field example: ${reply[1]}" $xtra ) - # Non-selectable lines Hops to jump with [ and ] Local anchors - reply2=( ${xtra:+2} ) reply3=( 1 ) reply4=( ) + # Non-selectable lines Hops to jump with [ and ] Local anchors + reply2=( ${xtra:+2} ) reply3=( 1 ) reply4=( ) } ## Start application ## @@ -36,5 +44,3 @@ zui-event-loop 1:demo_generator_A -zui_std_cleanup serialize return 0 - -# vim:ft=zsh diff --git a/demos/zui-demo-timeout b/demos/zui-demo-timeout index a6a5848..d3aab6a 100644 --- a/demos/zui-demo-timeout +++ b/demos/zui-demo-timeout @@ -1,20 +1,28 @@ +# -*- mode: zsh; sh-indentation: 2; indent-tabs-mode: nil; sh-basic-offset: 2; -*- +# vim: ft=zsh sw=2 ts=2 et +# +# ZUI demo: timeout +# # Started from Zle or from command line -zui_std_cleanup deserialize:"zui-demo-timeout" -zui_std_init app:"zui-demo-timeout" app_name:"ZUI Timeout Demo" -emulate -LR zsh -o extendedglob -o typesetsilent -o warncreateglobal + +builtin emulate -LR zsh +builtin setopt extended_glob typeset_silent warn_create_global + -zui_std_init2 # after emulate -LR -zui_std_store_default_app_config s:timeout 500 demo_generator_A() { - local mod="$1" ice="$2" + local mod="$1" ice="$2" - # Content - reply=( "${ZUI[YELLOW]}ZUI${ZUI[FMT_END]} can invoke timeout-callback when no input - random number: $RANDOM" ) + # Content + reply=( "${ZUI[YELLOW]}ZUI${ZUI[FMT_END]} can invoke timeout-callback when no input - random number: $RANDOM" ) - # Non-selectable lines Hops to jump with [ and ] Local anchors - reply2=( 2 ) reply3=( 1 ) reply4=( ) + # Non-selectable lines Hops to jump with [ and ] Local anchors + reply2=( 2 ) reply3=( 1 ) reply4=( ) } -zui-standard-timeout-callback() { -zui_std_fly_mod_regen 1 1; } @@ -26,5 +34,3 @@ zui-event-loop 1:demo_generator_A -zui_std_cleanup serialize return 0 - -# vim:ft=zsh diff --git a/demos/zui-demo-toggles b/demos/zui-demo-toggles index 0a5c707..f36b309 100644 --- a/demos/zui-demo-toggles +++ b/demos/zui-demo-toggles @@ -1,8 +1,16 @@ +# -*- mode: zsh; sh-indentation: 2; indent-tabs-mode: nil; sh-basic-offset: 2; -*- +# vim: ft=zsh sw=2 ts=2 et +# +# ZUI demo: toggle buttons +# # Started from Zle or from command line -zui_std_cleanup deserialize:"zui-demo-toggles" -zui_std_init app:"zui-demo-toggles" app_name:"ZUI Toggle Buttons" -emulate -LR zsh -o extendedglob -o typesetsilent -o warncreateglobal + +builtin emulate -LR zsh +builtin setopt extended_glob typeset_silent warn_create_global + -zui_std_init2 # after emulate -LR -zui_std_store_default_app_config s:text_mode off @@ -11,36 +19,36 @@ local internal # trick variable to make a handler no-restart # Generator for module 1 demo_generator_A() { - local mod="$1" ice="$2" + local mod="$1" ice="$2" - local dat1 col2 col3 - -zui_util_map_bools "ZUI[my_toggle1]" "dat1" "x" " " - -zui_util_map_bools "ZUI[my_toggle2];ZUI[my_toggle3]" "col2;col3" "${ZUI[BG_GREEN]}" "${ZUI[GREEN]}" + local dat1 col2 col3 + -zui_util_map_bools "ZUI[my_toggle1]" "dat1" "x" " " + -zui_util_map_bools "ZUI[my_toggle2];ZUI[my_toggle3]" "col2;col3" "${ZUI[BG_GREEN]}" "${ZUI[GREEN]}" - reply=() - -zui_std_button "toggle1" "[${dat1}] Checkbox" '(( ZUI[my_toggle1]=1-ZUI[my_toggle1] )); -zui_std_fly_mod_regen 1 1; internal=1' - -zui_std_rc_button "toggle2" "${col2}Toggle 1${ZUI[FMT_END]}" '(( ZUI[my_toggle2]=1-ZUI[my_toggle2] )); -zui_std_fly_mod_regen 1 1; internal=1' - -zui_std_rc_button "toggle3" "${col3}Toggle 2${ZUI[FMT_END]}" '(( ZUI[my_toggle3]=1-ZUI[my_toggle3] )); -zui_std_fly_mod_regen 1 1; internal=1' + reply=() + -zui_std_button "toggle1" "[${dat1}] Checkbox" '(( ZUI[my_toggle1]=1-ZUI[my_toggle1] )); -zui_std_fly_mod_regen 1 1; internal=1' + -zui_std_rc_button "toggle2" "${col2}Toggle 1${ZUI[FMT_END]}" '(( ZUI[my_toggle2]=1-ZUI[my_toggle2] )); -zui_std_fly_mod_regen 1 1; internal=1' + -zui_std_rc_button "toggle3" "${col3}Toggle 2${ZUI[FMT_END]}" '(( ZUI[my_toggle3]=1-ZUI[my_toggle3] )); -zui_std_fly_mod_regen 1 1; internal=1' - # Content - reply=( "${reply[1]}" "${reply[2]} ${reply[3]}" ) + # Content + reply=( "${reply[1]}" "${reply[2]} ${reply[3]}" ) - # Non-selectable lines Hops to jump with [ and ] Local anchors - reply2=( ) reply3=( 1 ) reply4=( ) + # Non-selectable lines Hops to jump with [ and ] Local anchors + reply2=( ) reply3=( 1 ) reply4=( ) } # Show handler code in status window -zui-standard-status-callback() { - local tpe="$1" selectable="$2" uniq="$3" search="$4" line="$5" segment="$6" - [[ "$tpe" = "0" ]] && return 0 # Filter out non-hyperlinks + local tpe="$1" selectable="$2" uniq="$3" search="$4" line="$5" segment="$6" + [[ "$tpe" = "0" ]] && return 0 # Filter out non-hyperlinks - shift 6; local id="$1" data1="$2" data2="$3" data3="$4" data4="$5" - id="${id#(zuiiaction|zuiaction|zuicheckbox|zuieanchor|zuianchor|zuitfield)}" - handler="${ZUI[zuiiaction$id]}" - [[ "$id" = "toggle1" ]] && reply=( "" "" "Handler: " "$handler" ) || reply=( "Handler: " "$handler" ) + shift 6; local id="$1" data1="$2" data2="$3" data3="$4" data4="$5" + id="${id#(zuiiaction|zuiaction|zuicheckbox|zuieanchor|zuianchor|zuitfield)}" + handler="${ZUI[zuiiaction$id]}" + [[ "$id" = "toggle1" ]] && reply=( "" "" "Handler: " "$handler" ) || reply=( "Handler: " "$handler" ) - # Resulting type: 1 - log message - return 1 + # Resulting type: 1 - log message + return 1 } ## Start application ## @@ -49,5 +57,3 @@ zui-event-loop 1:demo_generator_A -zui_std_cleanup serialize return 0 - -# vim:ft=zsh diff --git a/demos/zui-demo-various b/demos/zui-demo-various index f4bc527..5116ad3 100644 --- a/demos/zui-demo-various +++ b/demos/zui-demo-various @@ -1,17 +1,22 @@ +# -*- mode: zsh; sh-indentation: 2; indent-tabs-mode: nil; sh-basic-offset: 2; -*- +# vim: ft=zsh sw=2 ts=2 et # # Started from Zle or from command line -# # Cleanup $ZUI hash runtime data, deserialize previous state -zui_std_cleanup deserialize:"zui-demo-various" + # Initialize ZUI app -zui_std_init app:"zui-demo-various" app_name:"ZUI Large Demo" -emulate -LR zsh -o extendedglob -o typesetsilent -o warncreateglobal + +builtin emulate -LR zsh +builtin setopt extended_glob typeset_silent warn_create_global + -zui_std_init2 # after emulate -LR -zui-standard-text-select-callback() { - -zui_util_strip_codes "$2" - print -r -- "Obtained text selection: [$1] $REPLY" >> /tmp/zui.out + -zui_util_strip_codes "$2" + print -r -- "Obtained text selection: [$1] $REPLY" >> /tmp/zui.out } -zui_std_store_default_app_config s:status_size "5" @@ -53,12 +58,12 @@ local internal ## -demo_mod1_external_action_1() { - local id="$1" mod="$2" ice="$3" - local var_name="mod${mod}_ice${ice}_extra_line" - : ${(P)var_name::=Function set this line, regeneration used it} + local id="$1" mod="$2" ice="$3" + local var_name="mod${mod}_ice${ice}_extra_line" + : ${(P)var_name::=Function set this line, regeneration used it} - # Request regeneration with no user data - reply=( ",mod${mod}_ice${ice}," "" ) + # Request regeneration with no user data + reply=( ",mod${mod}_ice${ice}," "" ) } ## @@ -70,33 +75,33 @@ local internal # on-the-fly updates submitted by stdlib function # -zui_std_submit_list_update) -zui-standard-global-anchors-callback() { - local id="$1" initial_line="$2" mod="$3" ice="$4" - - if [[ "$mod" = "1" ]]; then - -zui_util_has_default_color && { - # Can reveal transparency, if terminal - # has background image or is transparent - zcurses bg "status" "white/default" - ZUI[status_colorpair]="white/default" - } - - # This is internal zui-list variable, - # accessible because internal actions - # are called from within the list - ZUI[bold]=1 - elif [[ "$mod" = "3" && "$ice" = "1" ]]; then - mod3_internal_action "$id" "$mod" "$ice" "$initial_line" "" - fi + local id="$1" initial_line="$2" mod="$3" ice="$4" + + if [[ "$mod" = "1" ]]; then + -zui_util_has_default_color && { + # Can reveal transparency, if terminal + # has background image or is transparent + zcurses bg "status" "white/default" + ZUI[status_colorpair]="white/default" + } + + # This is internal zui-list variable, + # accessible because internal actions + # are called from within the list + ZUI[bold]=1 + elif [[ "$mod" = "3" && "$ice" = "1" ]]; then + mod3_internal_action "$id" "$mod" "$ice" "$initial_line" "" + fi } mod3_internal_action() { - local id="$1" mod="$2" ice="$3" data3="$4" data4="" + local id="$1" mod="$2" ice="$3" data3="$4" data4="" - # Line at generation time, and at run time, - # after transformations of other modules - # that could shift it up or down. {...:+...} - # is: if not empty, then value is ... - -zui_std_fly_mod_regen "$mod" "$ice" ${data3:+"Extra line from top anchor (initial line: $data3, updated line: ${ZUI[zuianchor$id]})"} + # Line at generation time, and at run time, + # after transformations of other modules + # that could shift it up or down. {...:+...} + # is: if not empty, then value is ... + -zui_std_fly_mod_regen "$mod" "$ice" ${data3:+"Extra line from top anchor (initial line: $data3, updated line: ${ZUI[zuianchor$id]})"} } ## @@ -108,67 +113,67 @@ mod3_internal_action() { # from data of highlighted button. How to just pass # messages for display is shown in zui-demo-buttons. -zui-standard-status-callback() { - local tpe="$1" selectable="$2" uniq="$3" search="$4" line="$5" segment="$6" - shift 6 - - # No fast log messages - [[ -n "$EPOCHREALTIME" ]] && (( EPOCHREALTIME - ${ZUI[my_prev_log_time]:-(${EPOCHREALTIME}-1)} < 0.14 )) && return 0 - ZUI[my_prev_log_time]="$EPOCHREALTIME" - - local pressed="${ZUI[pressed_now]#(zuiiaction|zuiaction|zuieanchor|zuianchor|zuitfield)}" - [[ "$pressed" = log_append* ]] && pressed="LOG: ${(U)ZUI[log_append]} " || pressed="${pressed:+<> }" - - # Zero-type means callback is called on a non-hyperlink - if [[ "$tpe" = "0" ]]; then - if [[ -n "${ZUI[pure_text_selected]}" ]]; then - -zui_util_strip_codes "$segment" - reply=( "$pressed" "Pure-text selected: " "$REPLY" ) - elif [[ -n "${ZUI[line_selected]}" ]]; then - -zui_util_strip_codes "$line" - reply=( "$pressed" "Line selected: " "$REPLY" ) - elif (( $selectable || $uniq || $search )); then - # 1/0 selectable or not || 1/0 uniq mode || 1/0 non-empty search query - # Any of those means no hops and no non-selectables are relevant - -zui_util_strip_codes "$segment" - reply=( "$pressed" "" "Text: " "$REPLY" ) - else - # Detect if current line is also a hop - local on_hop - if [[ "${(t)ZUILIST_HOP_INDICES}" = array* && -n "${ZUILIST_HOP_INDICES[(r)${ZUI[CURRENT_IDX]}]}" ]]; then - on_hop=", also a hop" - fi - - reply=( "$pressed" ) - [[ -z "$pressed" ]] && reply+=( "(A non-selectable line$on_hop)" ) - fi - - # Resulting type: 1 - log message - return 1 + local tpe="$1" selectable="$2" uniq="$3" search="$4" line="$5" segment="$6" + shift 6 + + # No fast log messages + [[ -n "$EPOCHREALTIME" ]] && (( EPOCHREALTIME - ${ZUI[my_prev_log_time]:-(${EPOCHREALTIME}-1)} < 0.14 )) && return 0 + ZUI[my_prev_log_time]="$EPOCHREALTIME" + + local pressed="${ZUI[pressed_now]#(zuiiaction|zuiaction|zuieanchor|zuianchor|zuitfield)}" + [[ "$pressed" = log_append* ]] && pressed="LOG: ${(U)ZUI[log_append]} " || pressed="${pressed:+<> }" + + # Zero-type means callback is called on a non-hyperlink + if [[ "$tpe" = "0" ]]; then + if [[ -n "${ZUI[pure_text_selected]}" ]]; then + -zui_util_strip_codes "$segment" + reply=( "$pressed" "Pure-text selected: " "$REPLY" ) + elif [[ -n "${ZUI[line_selected]}" ]]; then + -zui_util_strip_codes "$line" + reply=( "$pressed" "Line selected: " "$REPLY" ) + elif (( $selectable || $uniq || $search )); then + # 1/0 selectable or not || 1/0 uniq mode || 1/0 non-empty search query + # Any of those means no hops and no non-selectable are relevant + -zui_util_strip_codes "$segment" + reply=( "$pressed" "" "Text: " "$REPLY" ) else - # No message on text field input - [[ -z "${ZUI[pressed_now]}" && -n "${ZUI[current_tfield]}" ]] && return 0 + # Detect if current line is also a hop + local on_hop + if [[ "${(t)ZUILIST_HOP_INDICES}" = array* && -n "${ZUILIST_HOP_INDICES[(r)${ZUI[CURRENT_IDX]}]}" ]]; then + on_hop=", also a hop" + fi + + reply=( "$pressed" ) + [[ -z "$pressed" ]] && reply+=( "(A non-selectable line$on_hop)" ) + fi - [[ "$1" = *(tfield|lbox)* ]] && local id="$1" width="$2" index="$3" text="$4" data1="$5" data2="$6" data3="$7" || - local id="$1" data1="$2" data2="$3" data3="$4" data4="$5" + # Resulting type: 1 - log message + return 1 + else + # No message on text field input + [[ -z "${ZUI[pressed_now]}" && -n "${ZUI[current_tfield]}" ]] && return 0 - [[ $id = (zuiiaction|zuianchor|zuitfield|zuilbox)* ]] && local exint="NO-RESTART" || local exint="RESTART" - [[ $id = (zuianchor|zuieanchor)* ]] && local aindex="Index: $data1" - # A raw link? (i.e. no handler and no dynamic function) - [[ $id != (zuiaction|zuiiaction|zuianchor|zuieanchor|zuitfield|zuilbox)* ]] && exint+=" " + [[ "$1" = *(tfield|lbox)* ]] && local id="$1" width="$2" index="$3" text="$4" data1="$5" data2="$6" data3="$7" || + local id="$1" data1="$2" data2="$3" data3="$4" data4="$5" - id="${id#(zuiaction|zuiiaction|zuianchor|zuieanchor|zuitfield|zuilbox)}" + [[ $id = (zuiiaction|zuianchor|zuitfield|zuilbox)* ]] && local exint="NO-RESTART" || local exint="RESTART" + [[ $id = (zuianchor|zuieanchor)* ]] && local aindex="Index: $data1" + # A raw link? (i.e. no handler and no dynamic function) + [[ $id != (zuiaction|zuiiaction|zuianchor|zuieanchor|zuitfield|zuilbox)* ]] && exint+=" " - handler="$ZUI[zuiiaction$id]" - [[ -z "$handler" ]] && handler="${ZUI[zuiaction$id]}" - [[ -z "$handler" ]] && handler="${ZUI[zuitfield$id]}" - [[ -z "$handler" ]] && handler="${ZUI[zuilbox$id]}" + id="${id#(zuiaction|zuiiaction|zuianchor|zuieanchor|zuitfield|zuilbox)}" - reply=( "$pressed" ) - [[ -z "$pressed" ]] && reply+=( "Id: $id" "${aindex+ $aindex}" " $exint" " Handler:" " $handler" ) + handler="$ZUI[zuiiaction$id]" + [[ -z "$handler" ]] && handler="${ZUI[zuiaction$id]}" + [[ -z "$handler" ]] && handler="${ZUI[zuitfield$id]}" + [[ -z "$handler" ]] && handler="${ZUI[zuilbox$id]}" - # Resulting type: 1 - log message - return 1 - fi + reply=( "$pressed" ) + [[ -z "$pressed" ]] && reply+=( "Id: $id" "${aindex+ $aindex}" " $exint" " Handler:" " $handler" ) + + # Resulting type: 1 - log message + return 1 + fi } ## @@ -177,141 +182,141 @@ mod3_internal_action() { # Generator for module 1 demo_generator_A() { - local mod="$1" ice="$2" user_data=${3:+ \[Obtained regeneration user data: $3\]} - - reply=( ) - # To request regeneration via external anchor (it will jump to given line, - # and also regenerate the given modules) or via raw link (button with no - # handler, so it is external) pass sequence of ",modX_iceY," strings as - # penultimate, and user-data as last argument. - -zui_std_anchor "regenerateA_$mod" "1" "" ",mod1_ice1," "$RANDOM" "[${ZUI[MAGENTA]}Regenerate${ZUI[FMT_END]}]" - -zui_std_rc_button_ext "regenerateB_$mod" "$mod" "$ice" "" "" "${ZUI[MAGENTA]}Regenerate${ZUI[FMT_END]}" -demo_mod1_external_action_1 - -zui_std_rc_button_ext "regenerateC_$mod" "" "" ",mod2_ice1," "" "${ZUI[MAGENTA]}Regenerate${ZUI[FMT_END]}" - - # Content - reply=( - "Restart-regeneration module (this is a non-selectable line, a header)" - "${reply[1]} this module via ${ZUI[YELLOW]}list_restart${ZUI[FMT_END]} and ${ZUI[CYAN]}external_anchor${ZUI[FMT_END]}${user_data}" - "${reply[2]} this module via ${ZUI[YELLOW]}list_restart${ZUI[FMT_END]} and ${ZUI[CYAN]}function_call${ZUI[FMT_END]}" - "${reply[3]} the module via ${ZUI[YELLOW]}list_restart${ZUI[FMT_END]} and ${ZUI[CYAN]}raw_link${ZUI[FMT_END]}" - "Random number: $RANDOM" - - # This is set in -demo_mod1_external_action_1 - $mod1_ice1_extra_line - ) - - # Jump 2 lines after last line. Note that - # the line index is written as: - # - maximum local line number - # - remaining lines to reach next module - local -a next - -zui_std_anchor "jumpA_$mod" "${#reply}+3" "" "" "" "[${ZUI[YELLOW]}NEXT${ZUI[FMT_END]}]" "" next - reply[4]="${reply[4]//${next[1]}}" - - # Non-selectables (:+ is "if not empty, then...") - reply2=( 1 5 ${mod1_ice1_extra_line:+${#reply}} ) - # Hops - reply3=( 1 ) - # Local anchors - reply4=( regenerateA_$mod jumpA_$mod ) + local mod="$1" ice="$2" user_data=${3:+ \[Obtained regeneration user data: $3\]} + + reply=( ) + # To request regeneration via external anchor (it will jump to given line, + # and also regenerate the given modules) or via raw link (button with no + # handler, so it is external) pass sequence of ",modX_iceY," strings as + # penultimate, and user-data as last argument. + -zui_std_anchor "regenerateA_$mod" "1" "" ",mod1_ice1," "$RANDOM" "[${ZUI[MAGENTA]}Regenerate${ZUI[FMT_END]}]" + -zui_std_rc_button_ext "regenerateB_$mod" "$mod" "$ice" "" "" "${ZUI[MAGENTA]}Regenerate${ZUI[FMT_END]}" -demo_mod1_external_action_1 + -zui_std_rc_button_ext "regenerateC_$mod" "" "" ",mod2_ice1," "" "${ZUI[MAGENTA]}Regenerate${ZUI[FMT_END]}" + + # Content + reply=( + "Restart-regeneration module (this is a non-selectable line, a header)" + "${reply[1]} this module via ${ZUI[YELLOW]}list_restart${ZUI[FMT_END]} and ${ZUI[CYAN]}external_anchor${ZUI[FMT_END]}${user_data}" + "${reply[2]} this module via ${ZUI[YELLOW]}list_restart${ZUI[FMT_END]} and ${ZUI[CYAN]}function_call${ZUI[FMT_END]}" + "${reply[3]} the module via ${ZUI[YELLOW]}list_restart${ZUI[FMT_END]} and ${ZUI[CYAN]}raw_link${ZUI[FMT_END]}" + "Random number: $RANDOM" + + # This is set in -demo_mod1_external_action_1 + $mod1_ice1_extra_line + ) + + # Jump 2 lines after last line. Note that + # the line index is written as: + # - maximum local line number + # - remaining lines to reach next module + local -a next + -zui_std_anchor "jumpA_$mod" "${#reply}+3" "" "" "" "[${ZUI[YELLOW]}NEXT${ZUI[FMT_END]}]" "" next + reply[4]="${reply[4]//${next[1]}}" + + # Non-selectables (:+ is "if not empty, then...") + reply2=( 1 5 ${mod1_ice1_extra_line:+${#reply}} ) + # Hops + reply3=( 1 ) + # Local anchors + reply4=( regenerateA_$mod jumpA_$mod ) } demo_generator_B() { - local mod="$1" ice="$2" - - # Prepare toggle button's states. Every expression - # in first string will be evaluated and mapped as - # boolean to corresponding variable in second string, - # using bool true - $3, bool false - $4. - local col_bld col_tmd col_tsel col_lap col_sptr col_sb - -zui_util_map_bools "ZUI[bold];ZUI[text_select];[[ \"${ZUI[log_append]}\" = below ]];ZUI[status_pointer];ZUI[status_border]" \ - "col_bld;col_tsel;col_lap;col_sptr;col_sb" "${ZUI[BG_BLUE]}" "${ZUI[GREEN]}" - - reply=( ) - # internal=1 is a trick to make action internal - -zui_std_rc_button "bold_$mod" "${col_bld}bold${ZUI[FMT_END]}" 'internal=1; (( ZUI[bold]=1-ZUI[bold] )); -zui_std_fly_mod_regen "'"$mod"'" "'"$ice"'"' - -zui_std_rc_button "text_select_$mod" "${col_tsel}text_select${ZUI[FMT_END]}" 'internal=1; (( ZUI[text_select]=1-ZUI[text_select] )); -zui_std_fly_mod_regen "'"$mod"'" "'"$ice"'"' - -zui_std_rc_button "log_append_$mod" "${col_lap}log_append${ZUI[FMT_END]}" 'internal=1; [[ ${ZUI[log_append]} = "below" ]] && ZUI[log_append]=above || ZUI[log_append]=below; -zui_std_fly_mod_regen "'"$mod"'" "'"$ice"'"' - -zui_std_rc_button "status_pointer_$mod" "${col_sptr}status_pointer${ZUI[FMT_END]}" 'internal=1; (( ZUI[status_pointer]=1-ZUI[status_pointer] )); -zui_std_fly_mod_regen "'"$mod"'" "'"$ice"'"' - -zui_std_rc_button "status_border_$mod" "${col_sb}status_border${ZUI[FMT_END]}" 'internal=1; (( ZUI[status_border]=1-ZUI[status_border] )); -zui_std_fly_mod_regen "'"$mod"'" "'"$ice"'"' - -zui_std_rc_button "log_colors_$mod" "${ZUI[GREEN]}log_colors${ZUI[FMT_END]}" 'internal=1; zui_log_colors=( $zui_log_colors[-1] ${(@)zui_log_colors[1,-2]} )' - - # Variables of the list box - (( ${+ZUI[my_lbox1_width]} == 0 )) && ZUI[my_lbox1_width]=5 - (( ${+ZUI[my_lbox1_idx]} == 0 )) && ZUI[my_lbox1_idx]=1 - (( ${+ZUI[my_lbox1_opts]} == 0 )) && ZUI[my_lbox1_opts]="off;hyp;nohyp;all" - noglob -zui_std_list_box "lbox1_$mod" ZUI[my_lbox1_width] ZUI[my_lbox1_idx] ZUI[my_lbox1_opts] "" "" "" 'ZUI[text_mode]=${${(s:;:)ZUI[my_lbox1_opts]}[${ZUI[my_lbox1_idx]}]}' - - # Don't overwrite user changes - (( ${+ZUI[my_tfield1_width]} == 0 )) && ZUI[my_tfield1_width]=20 - (( ${+ZUI[my_tfield1_start]} == 0 )) && ZUI[my_tfield1_start]=4 - (( ${+ZUI[my_tfield1_data]} == 0 )) && ZUI[my_tfield1_data]="An example text" - noglob -zui_std_text_field "tfield1_$mod" ZUI[my_tfield1_width] ZUI[my_tfield1_start] ZUI[my_tfield1_data] "" "" "" 'mod2_ice1_extra_line="Received text (with no restart): ${ZUI[CYAN]}${ZUI[my_tfield1_data]}${ZUI[FMT_END]}"; -zui_std_fly_mod_regen "'"$mod"'" "'"$ice"'"' - - (( ${+ZUI[my_tfield2_width]} == 0 )) && ZUI[my_tfield2_width]=40 - (( ${+ZUI[my_tfield2_start]} == 0 )) && ZUI[my_tfield2_start]=1 - (( ${+ZUI[my_tfield2_data]} == 0 )) && ZUI[my_tfield2_data]="I'm wider and start at the beginning" - noglob -zui_std_text_field "tfield2_$mod" ZUI[my_tfield2_width] ZUI[my_tfield2_start] ZUI[my_tfield2_data] "" "" "" 'mod2_ice1_extra_line="Received 2nd text (with no restart): ${ZUI[CYAN]}${ZUI[my_tfield2_data]}${ZUI[FMT_END]}"; -zui_std_fly_mod_regen "'"$mod"'" "'"$ice"'"' - - # Content - reply=( - "Toggle ${reply[1]} with inlined (no function!) code, text mode: <${reply[7]}>, ${reply[2]}" - "Toggle ${reply[3]} - status logs appended at end, or at top, rotate ${reply[6]}" - "Toggle ${reply[4]} - status position pointer, ${reply[5]}" - "Random number: $RANDOM" - "Enter text! |${reply[8]}|, try keys UP/DOWN, [${reply[9]}]" - - $mod2_ice1_extra_line - ) - - # Non-selectables Hops Local anchors # Spacing - reply2=( 4 ${mod2_ice1_extra_line:+6} ) reply3=( 1 ) reply4=( ) reply5=2 + local mod="$1" ice="$2" + + # Prepare toggle button's states. Every expression + # in first string will be evaluated and mapped as + # boolean to corresponding variable in second string, + # using bool true - $3, bool false - $4. + local col_bld col_tmd col_tsel col_lap col_sptr col_sb + -zui_util_map_bools "ZUI[bold];ZUI[text_select];[[ \"${ZUI[log_append]}\" = below ]];ZUI[status_pointer];ZUI[status_border]" \ + "col_bld;col_tsel;col_lap;col_sptr;col_sb" "${ZUI[BG_BLUE]}" "${ZUI[GREEN]}" + + reply=( ) + # internal=1 is a trick to make action internal + -zui_std_rc_button "bold_$mod" "${col_bld}bold${ZUI[FMT_END]}" 'internal=1; (( ZUI[bold]=1-ZUI[bold] )); -zui_std_fly_mod_regen "'"$mod"'" "'"$ice"'"' + -zui_std_rc_button "text_select_$mod" "${col_tsel}text_select${ZUI[FMT_END]}" 'internal=1; (( ZUI[text_select]=1-ZUI[text_select] )); -zui_std_fly_mod_regen "'"$mod"'" "'"$ice"'"' + -zui_std_rc_button "log_append_$mod" "${col_lap}log_append${ZUI[FMT_END]}" 'internal=1; [[ ${ZUI[log_append]} = "below" ]] && ZUI[log_append]=above || ZUI[log_append]=below; -zui_std_fly_mod_regen "'"$mod"'" "'"$ice"'"' + -zui_std_rc_button "status_pointer_$mod" "${col_sptr}status_pointer${ZUI[FMT_END]}" 'internal=1; (( ZUI[status_pointer]=1-ZUI[status_pointer] )); -zui_std_fly_mod_regen "'"$mod"'" "'"$ice"'"' + -zui_std_rc_button "status_border_$mod" "${col_sb}status_border${ZUI[FMT_END]}" 'internal=1; (( ZUI[status_border]=1-ZUI[status_border] )); -zui_std_fly_mod_regen "'"$mod"'" "'"$ice"'"' + -zui_std_rc_button "log_colors_$mod" "${ZUI[GREEN]}log_colors${ZUI[FMT_END]}" 'internal=1; zui_log_colors=( $zui_log_colors[-1] ${(@)zui_log_colors[1,-2]} )' + + # Variables of the list box + (( ${+ZUI[my_lbox1_width]} == 0 )) && ZUI[my_lbox1_width]=5 + (( ${+ZUI[my_lbox1_idx]} == 0 )) && ZUI[my_lbox1_idx]=1 + (( ${+ZUI[my_lbox1_opts]} == 0 )) && ZUI[my_lbox1_opts]="off;hyp;nohyp;all" + noglob -zui_std_list_box "lbox1_$mod" ZUI[my_lbox1_width] ZUI[my_lbox1_idx] ZUI[my_lbox1_opts] "" "" "" 'ZUI[text_mode]=${${(s:;:)ZUI[my_lbox1_opts]}[${ZUI[my_lbox1_idx]}]}' + + # Don't overwrite user changes + (( ${+ZUI[my_tfield1_width]} == 0 )) && ZUI[my_tfield1_width]=20 + (( ${+ZUI[my_tfield1_start]} == 0 )) && ZUI[my_tfield1_start]=4 + (( ${+ZUI[my_tfield1_data]} == 0 )) && ZUI[my_tfield1_data]="An example text" + noglob -zui_std_text_field "tfield1_$mod" ZUI[my_tfield1_width] ZUI[my_tfield1_start] ZUI[my_tfield1_data] "" "" "" 'mod2_ice1_extra_line="Received text (with no restart): ${ZUI[CYAN]}${ZUI[my_tfield1_data]}${ZUI[FMT_END]}"; -zui_std_fly_mod_regen "'"$mod"'" "'"$ice"'"' + + (( ${+ZUI[my_tfield2_width]} == 0 )) && ZUI[my_tfield2_width]=40 + (( ${+ZUI[my_tfield2_start]} == 0 )) && ZUI[my_tfield2_start]=1 + (( ${+ZUI[my_tfield2_data]} == 0 )) && ZUI[my_tfield2_data]="I'm wider and start at the beginning" + noglob -zui_std_text_field "tfield2_$mod" ZUI[my_tfield2_width] ZUI[my_tfield2_start] ZUI[my_tfield2_data] "" "" "" 'mod2_ice1_extra_line="Received 2nd text (with no restart): ${ZUI[CYAN]}${ZUI[my_tfield2_data]}${ZUI[FMT_END]}"; -zui_std_fly_mod_regen "'"$mod"'" "'"$ice"'"' + + # Content + reply=( + "Toggle ${reply[1]} with inlined (no function!) code, text mode: <${reply[7]}>, ${reply[2]}" + "Toggle ${reply[3]} - status logs appended at end, or at top, rotate ${reply[6]}" + "Toggle ${reply[4]} - status position pointer, ${reply[5]}" + "Random number: $RANDOM" + "Enter text! |${reply[8]}|, try keys UP/DOWN, [${reply[9]}]" + + $mod2_ice1_extra_line + ) + + # Non-selectable Hops Local anchors # Spacing + reply2=( 4 ${mod2_ice1_extra_line:+6} ) reply3=( 1 ) reply4=( ) reply5=2 } # Generator for module 2 demo_generator_C() { - local mod="$1" ice="$2" extra_line="$3" - - # Optional lines - local regenerate jump append_third - - local rand_line="Random number: $RANDOM" - integer rand_line_nr=2 - - # 1st instance? - if [[ "$ice" = "1" ]]; then - reply=( ) - # IDs of anchors have own namespace - -zui_std_rc_button_ext "regenerateD_${mod}_${ice}" "$mod" "$ice" "" "" "${ZUI[BOLD]}${ZUI[BLUE]}Regenerate${ZUI[FMT_END]}" mod3_internal_action - -zui_std_anchor "jumpB_${mod}_${ice}" "1" "" "" "" "[${ZUI[YELLOW]}Jump${ZUI[FMT_END]}]" - regenerate="${reply[1]} this module ${ZUI[RED]}ON-THE-FLY${ZUI[FMT_END]}, ${ZUI[YELLOW]}without${ZUI[FMT_END]} list restart" - jump="${reply[2]} to 1st line" - rand_line="Random number: ${ZUI[YELLOW]}$RANDOM${ZUI[FMT_END]}" - rand_line_nr=4 - fi + local mod="$1" ice="$2" extra_line="$3" - -zui_std_get_mod_factor "$mod" + # Optional lines + local regenerate jump append_third - # 2nd instance? Also, is it last instance? - if [[ "$ice" = "2" && "$REPLY" = "2" ]]; then - reply=( ) - -zui_std_anchor "append_third_${mod}_${ice}" "2+2" "" ",mod${mod}_ice${ice},mod${mod}_ice$(( ice + 1 ))," "" "${ZUI[MAGENTA]}Append third!${ZUI[FMT_END]}" "-zui_std_set_mod_factor $mod 3" - append_third="${reply[1]}" - fi + local rand_line="Random number: $RANDOM" + integer rand_line_nr=2 - # Content - reply=( - "Module 3, instance ${ZUI[CYAN]}#$ice${ZUI[FMT_END]}" - $regenerate - $jump - "$rand_line" - $extra_line - $append_third - ) - - # Non-selectables Hops Local anchors (:+ - replace if not null) - # 1 is omitted - reply2=( $rand_line_nr ) reply3=( 1 ) reply4=( ${jump:+jumpB_${mod}_${ice}} ${append_third:+append_third_${mod}_${ice}} ) + # 1st instance? + if [[ "$ice" = "1" ]]; then + reply=( ) + # IDs of anchors have own namespace + -zui_std_rc_button_ext "regenerateD_${mod}_${ice}" "$mod" "$ice" "" "" "${ZUI[BOLD]}${ZUI[BLUE]}Regenerate${ZUI[FMT_END]}" mod3_internal_action + -zui_std_anchor "jumpB_${mod}_${ice}" "1" "" "" "" "[${ZUI[YELLOW]}Jump${ZUI[FMT_END]}]" + regenerate="${reply[1]} this module ${ZUI[RED]}ON-THE-FLY${ZUI[FMT_END]}, ${ZUI[YELLOW]}without${ZUI[FMT_END]} list restart" + jump="${reply[2]} to 1st line" + rand_line="Random number: ${ZUI[YELLOW]}$RANDOM${ZUI[FMT_END]}" + rand_line_nr=4 + fi + + -zui_std_get_mod_factor "$mod" + + # 2nd instance? Also, is it last instance? + if [[ "$ice" = "2" && "$REPLY" = "2" ]]; then + reply=( ) + -zui_std_anchor "append_third_${mod}_${ice}" "2+2" "" ",mod${mod}_ice${ice},mod${mod}_ice$(( ice + 1 ))," "" "${ZUI[MAGENTA]}Append third!${ZUI[FMT_END]}" "-zui_std_set_mod_factor $mod 3" + append_third="${reply[1]}" + fi + + # Content + reply=( + "Module 3, instance ${ZUI[CYAN]}#$ice${ZUI[FMT_END]}" + $regenerate + $jump + "$rand_line" + $extra_line + $append_third + ) + + # Non-selectable Hops Local anchors (:+ - replace if not null) + # 1 is omitted + reply2=( $rand_line_nr ) reply3=( 1 ) reply4=( ${jump:+jumpB_${mod}_${ice}} ${append_third:+append_third_${mod}_${ice}} ) } ## @@ -327,5 +332,3 @@ zui-event-loop 1:demo_generator_A 1:demo_generator_B 2:demo_generator_C \ -zui_std_cleanup serialize return 0 - -# vim:ft=zsh diff --git a/docs/README.md b/docs/README.md index a484a47..ea67860 100644 --- a/docs/README.md +++ b/docs/README.md @@ -1,78 +1,81 @@

- - Logo - -❮ ZI ❯ - ⬢ ZUI +

+ + Logo❮ Zi ❯ + - + ⬢ ZUI +

## ZUI – CGI+DHTML-like User Interface Library for Zsh / ZCurses -This is a RAD (Rapid Application Development) textual user interface library for Zsh. It in many aspects resembles typical CGI+(D)HTML setup. There are: +This is a RAD (Rapid Application Development) textual user interface library for Zsh. -- generators ran on "server" side (basic Zshell-code that is just generating text!), -- event loop that turns the generated text into document with active elements (buttons, anchors, toggle buttons, text fields, list boxes), -- mechanism to regenerate document parts from the original generators. +It in many aspects resembles a typical CGI+(D)HTML setup. There are: -So, a Zshell code generates text. It is then turned into document with hyperlinks. DHTML-like calls are possible that will regenerate document parts on the fly. Page can be also reloaded with input data, just like an HTML page. +- generators ran on the "server" side (basic Zshell code that is just generating text!) +- event loop that turns the generated text into a document with active elements (buttons, anchors, toggle buttons, text fields, list boxes) +- mechanism to regenerate document parts from the original generators -A voiced [video tutorial](https://youtu.be/TfZ8b_RS_Bg) shows how to create an application – Nmap network scanner frontend. - -> See also [ZSTYLES](ZSTYLES.md) - -## Hello World - -```zsh -# Started from Zle or from command line +So, a Zshell code generates text. It is then turned into a document with hyperlinks. DHTML-like calls are possible that will regenerate document parts on the fly. Page can be also reloaded with input data, just like an HTML page. --zui_std_cleanup deserialize:"zui-demo-hello-world" --zui_std_init app:"zui-demo-hello-world" app_name:"ZUI Hello World" -emulate -LR zsh -o extendedglob -o typesetsilent -o warncreateglobal --zui_std_init2 # after emulate -LR +A voiced [video tutorial](https://youtu.be/TfZ8b_RS_Bg) shows how to create an application – Nmap network scanner frontend. --zui_std_store_default_app_config b:border 1 +The API is described in the [wiki](https://wiki.zshell.dev/ecosystem/plugins/zui). -demo_generator_A() { - local mod="$1" ice="$2" - # Content, no hyper-links - reply=( "Hello World from ${ZUI[YELLOW]}ZUI${ZUI[FMT_END]}! Module $mod, instance $ice." ) - # Non-selectable lines Hops to jump with [ and ] Local anchors - reply2=( ) reply3=( 1 ) reply4=( ) -} +## Demo Applications -## Start application ## -zui-event-loop 1:demo_generator_A +Enable: --zui_std_cleanup serialize +```zsh +typeset -A ZUI; ZUI[DEMOS]=1 ``` -Other example which uses list-box: [zui-demo-list-box](https://github.com/z-shell/zui/blob/main/demos/zui-demo-list-boxes) - -The API is described at the [wiki](https://wiki.zshell.dev/ecosystem/plugins/zui). +> **Note**: +> +> - The above must be set before loading ZUI. + +Available: + +- [zui-demo-anchors](/demos/zui-demo-anchors) +- [zui-demo-buttons](/demos/zui-demo-buttons) +- [zui-demo-edit](/demos/zui-demo-edit) +- [zui-demo-ganchors](/demos/zui-demo-ganchors) +- [zui-demo-history](/demos/zui-demo-history) +- [zui-demo-nmap](/demos/zui-demo-nmap) +- [zui-demo-text-fields](/demos/zui-demo-text-fields) +- [zui-demo-toggles](/demos/zui-demo-toggles) +- [zui-demo-append](/demos/zui-demo-append) +- [zui-demo-configure](/demos/zui-demo-configure) +- [zui-demo-fly](/demos/zui-demo-fly) +- [zui-demo-hello-world](/demos/zui-demo-hello-world) +- [zui-demo-list-boxes](/demos/zui-demo-list-boxes) +- [zui-demo-special-text](/demos/zui-demo-special-text) +- [zui-demo-timeout](/demos/zui-demo-timeout) +- [zui-demo-various](/demos/zui-demo-various) ## Installation -**The plugin is "standalone"**, which means that only sourcing it is needed. To install, unpack `zui` somewhere and add to `zshrc`: +**The plugin is "standalone"**, which means that only sourcing it is needed. To install, unpack zui and load from .zshrc: ```zsh source {where-zui-is}/zui.plugin.zsh ``` -If using a plugin manager, then `ZI` is recommended, but you can use any other too, and also install with `Oh My Zsh` (by copying directory to `~/.oh-my-zsh/custom/plugins`). - -### [ZI](https://github.com/z-shell/zi) +### [Zi](https://github.com/z-shell/zi) -Add `zi load z-shell/zui` to your `.zshrc` file. ZI will handle the rest automatically the next time you start zsh. To update (i.e. to pull from origin) issue `zi update z-shell/zui`. +Add zi load z-shell/zui to your .zshrc file. ZI will handle the rest automatically the next time you start zsh. To update (i.e. to pull from origin) issue zi update z-shell/zui. ### Antigen -Add `antigen bundle z-shell/zui` to your `.zshrc` file. Antigen will handle cloning the plugin for you automatically the next time you start zsh. +Add antigen bundle z-shell/zui to your .zshrc file. Antigen will handle cloning the plugin for you automatically the next time you start zsh. ### Oh-My-Zsh -1. `cd ~/.oh-my-zsh/custom/plugins` -2. `git clone git@github.com:z-shell/zui.git` -3. Add `zui` to your plugin list +1. cd ~/.oh-my-zsh/custom/plugins +2. git clone https://github.com/z-shell/zui.git +3. Add zui to your plugin list ### Zgen -Add `zgen load z-shell/zui` to your .zshrc file in the same place you're doing your other `zgen load` calls in. +Add zgen load z-shell/zui to your .zshrc file in the same place you're doing your other zgen load calls in. diff --git a/docs/stdlib.lzui.adoc b/docs/stdlib.lzui.adoc deleted file mode 100644 index 2575e8f..0000000 --- a/docs/stdlib.lzui.adoc +++ /dev/null @@ -1,1053 +0,0 @@ -stdlib.lzui(1) -============== -:compat-mode!: - -NAME ----- -stdlib.lzui - a shell script - -SYNOPSIS --------- -Documentation automatically generated with `zsdoc' - -FUNCTIONS ---------- - - -zui_std_anchor - -zui_std_button - -zui_std_button_ext - -zui_std_cleanup - -zui_std_decode - -zui_std_decode_hyperlink - -zui_std_decode_list_box - -zui_std_decode_text_field - -zui_std_deserialize - -zui_std_fly_array_refresh - -zui_std_fly_mod_regen - -zui_std_fly_mod_regen_ext - -zui_std_get_ganchor - -zui_std_get_mod_factor - -zui_std_get_mod_spacing - -zui_std_get_stext - -zui_std_has_any_hyperlinks - -zui_std_init - -zui_std_init2 - -zui_std_is_any_hyperlink - -zui_std_is_hyperlink - -zui_std_is_list_box - -zui_std_is_special_text - -zui_std_is_text_field - -zui_std_list_box - -zui_std_load_config - -zui_std_load_global_index_and_size - -zui_std_map_replies - -zui_std_pack_hyperlinks_into_box - -zui_std_rc_button - -zui_std_rc_button_ext - -zui_std_refresh_configs - -zui_std_reset_replies - -zui_std_serialize - -zui_std_set_mod_factor - -zui_std_set_mod_spacing - -zui_std_special_text - -zui_std_stalog - -zui_std_store_default_app_config - -zui_std_strip_color_codes - -zui_std_strip_meta_data - -zui_std_submit_fly_from_gen_replies - -zui_std_submit_hops - -zui_std_submit_lanchors - -zui_std_submit_list_update - -zui_std_submit_nonselectables - -zui_std_text_field - -DETAILS -------- - -Script Body -~~~~~~~~~~~ - -Has 32 line(s). No functions are called (may set up e.g. a hook, a Zle widget bound to a key, etc.). - --zui_std_anchor -~~~~~~~~~~~~~~~ - -____ - - Appends anchor hyperlink into "reply" output array - (or to array given by name via $8). - - Arguments are initially the same as in -zui_std_\ - button, except: - - - the first data argument (data1, $2) needs to be - index of line to jump to, - - - you normally also want to pass instance ID as data2 - (module, $3) and data3 (instance, $4) if you assign - a handler that is shared between modules, - - - instead of handler you might use data3 and data4 - ($4 & $5) as a module regeneration instruction, - i.e. pass e.g.: ",mod2_ice1," "arg", to regenerate - some module numbered 2, instance 1, with passed - user-data "arg". - - If the handler is external (i.e. doesn't have "internal" - in its name), then it might too deploy list regeneration, - by doing reply=( ",mod2_ice1," "arg"), for example. - - Anchor of which data3 matches ",*," is set to be external. - If handler doesn't have word "internal" in its name, then - anchor is also set to be external. - - Example call: - -zui_std_anchor "regen1" "4" "" ",mod1_ice2," "$RANDOM" "[${ZUI[MAGENTA]}Regen${ZUI[FMT_END]}]" - - Generator has instance ID (mod and ice) in $1 and $2 - by the design of restart-regeneration loop. So, this - instructs to regenerate module 1 instance 2, with no - handler call, with $RANDOM as generator's third input - - regeneration user-data. "4" is the line number on - which the cursor will be placed. - -____ - -Has 18 line(s). Doesn't call other functions. - -Uses feature(s): _setopt_ - -Not called by script or any function (may be e.g. a hook, a Zle widget, etc.). - --zui_std_button -~~~~~~~~~~~~~~~ - -____ - - Short button function - no user data - - $1 - action ID - $2 - text - $3 - optional handler function name, can be empty text - $4 - optional output variable name (defualt: 'reply') -____ - -Has 2 line(s). Calls functions: - - -zui_std_button - `-- -zui_std_button_ext - -Not called by script or any function (may be e.g. a hook, a Zle widget, etc.). - --zui_std_button_ext -~~~~~~~~~~~~~~~~~~~ - -____ - - Appends hyperlink into output array. It's an action button - shown without surrounding "[" and "]". - - $1 - action ID - $2 - data1, e.g. timestamp - $3 - data2, e.g. command - $4 - data3, e.g. active path - $5 - data4, e.g. file path, file name, URL, other data - $6 - text - $7 - optional handler function name, can be empty text - $8 - optional output variable name (defualt: 'reply') - - Output array is extended by hyperlink's text (one new element) - -____ - -Has 15 line(s). Doesn't call other functions. - -Called by: - - -zui_std_button - --zui_std_cleanup -~~~~~~~~~~~~~~~~ - -____ - - This function clears application data - from $ZUI global hash. To be called at - exit and at start of zui application -____ - -Has 58 line(s). Calls functions: - - -zui_std_cleanup - |-- -zui_std_deserialize - `-- -zui_std_serialize - -Uses feature(s): _unfunction_ - -Not called by script or any function (may be e.g. a hook, a Zle widget, etc.). - --zui_std_decode -~~~~~~~~~~~~~~~ - -____ - - Tries various decoding functions, testable. Returns (in REPLY) - "1" if hyperlink (anchor, button, raw link), "2" if text field, - "3" if list-box - - $1 - hyperlink - $2 - output parameter name, for type (default: REPLY) - $3 - output array name, for hyperlink data (default: reply) -____ - -Has 7 line(s). Calls functions: - - -zui_std_decode - |-- -zui_std_decode_hyperlink - |-- -zui_std_decode_list_box - `-- -zui_std_decode_text_field - -Not called by script or any function (may be e.g. a hook, a Zle widget, etc.). - --zui_std_decode_hyperlink -~~~~~~~~~~~~~~~~~~~~~~~~~ - -____ - - Decodes given button/anchor/raw hyperlink returning - data contained. Testable - test to check if string - was correctly decoded. - - $1 - hyperlink string - $2 - optional output array name (default: "reply") - - $reply[1] - ID (of button, anchor or raw link) - $reply[2] - data1 - $reply[3] - data2 - $reply[4] - data3 - $reply[5] - data4 - -____ - -Has 19 line(s). Doesn't call other functions. - -Called by: - - -zui_std_decode - --zui_std_decode_list_box -~~~~~~~~~~~~~~~~~~~~~~~~ - -____ - - Decodes given list-box and returns data contained. - Testable - test to check if hyperlink was correctly - decoded. - - $1 - hyperlink string - $2 - optional output array name (default: "reply") - - $reply[1] - ID (of action) - $reply[2] - width parameter name - $reply[3] - start-index parameter name - $reply[4] - text parameter name - $reply[5] - data1 - $reply[6] - data2 - $reply[7] - data3 - -____ - -Has 22 line(s). Doesn't call other functions. - -Called by: - - -zui_std_decode - syslib.lzui/-zui_sys_get_tfield_cursor_boundaries - --zui_std_decode_text_field -~~~~~~~~~~~~~~~~~~~~~~~~~~ - -____ - - Decodes given text-field and returns data contained. - Testable - test to check if hyperlink was correctly - decoded. - - $1 - hyperlink string - $2 - optional output array name (default: "reply") - - $reply[1] - ID (of action) - $reply[2] - width parameter name - $reply[3] - start-index parameter name - $reply[4] - text parameter name - $reply[5] - data1 - $reply[6] - data2 - $reply[7] - data3 - -____ - -Has 22 line(s). Doesn't call other functions. - -Called by: - - -zui_std_decode - syslib.lzui/-zui_sys_get_tfield_cursor_boundaries - --zui_std_deserialize -~~~~~~~~~~~~~~~~~~~~ - -____ - - Reads ZUI[serialized_${ZUI[app]}] and maps - the content onto ZUI keys, normally my_* - keys. Use this to restore application state - after exit and consecutive start. -____ - -Has 9 line(s). Doesn't call other functions. - -Called by: - - -zui_std_cleanup - --zui_std_fly_array_refresh -~~~~~~~~~~~~~~~~~~~~~~~~~~ - -____ - - Submits on-the-fly array refresh. The given instance ID - should point to an array ("a:" prefix at zui-event-loop). - The array will be read again and pasted into document - replacing previous content. - - No instance index is requested, because arrays have only - single instance. - - $1 - module's index -____ - -Has 14 line(s). Calls functions: - - -zui_std_fly_array_refresh - |-- -zui_std_map_replies - |-- -zui_std_reset_replies - `-- -zui_std_submit_fly_from_gen_replies - |-- -zui_std_submit_hops - |-- -zui_std_submit_lanchors - |-- -zui_std_submit_list_update - `-- -zui_std_submit_nonselectables - -Not called by script or any function (may be e.g. a hook, a Zle widget, etc.). - --zui_std_fly_mod_regen -~~~~~~~~~~~~~~~~~~~~~~ - -____ - - Submits on-the-fly module update. Needs only instance ID, - the generator to run is the one specified for zui-event-loop - - $1 - module's index - $2 - instance index - $3, $4, ... - additional arguments for - the generator -____ - -Has 12 line(s). Calls functions: - - -zui_std_fly_mod_regen - |-- -zui_std_map_replies - |-- -zui_std_reset_replies - `-- -zui_std_submit_fly_from_gen_replies - |-- -zui_std_submit_hops - |-- -zui_std_submit_lanchors - |-- -zui_std_submit_list_update - `-- -zui_std_submit_nonselectables - -Not called by script or any function (may be e.g. a hook, a Zle widget, etc.). - --zui_std_fly_mod_regen_ext -~~~~~~~~~~~~~~~~~~~~~~~~~~ - -____ - - Submits on-the-fly module update. Needs - generator to run and instance ID. - - $1 - name of generator function - $2 - module's index - $3 - instance index - $4, $5, ... - additional arguments for - the generator -____ - -Has 10 line(s). Calls functions: - - -zui_std_fly_mod_regen_ext - |-- -zui_std_map_replies - |-- -zui_std_reset_replies - `-- -zui_std_submit_fly_from_gen_replies - |-- -zui_std_submit_hops - |-- -zui_std_submit_lanchors - |-- -zui_std_submit_list_update - `-- -zui_std_submit_nonselectables - -Not called by script or any function (may be e.g. a hook, a Zle widget, etc.). - --zui_std_get_ganchor -~~~~~~~~~~~~~~~~~~~~ - -____ - - Doesn't have data1 (normally index to jump to) nor other data, and - also doesn't have handler. Returns anchor button that jumps to given - GLOBAL anchor and calls its handler (which invokes -zui-standard-gl\ - obal-anchors-callback). - - $1 - module index - $2 - instance index - $3 - visible text of the anchor - $4 - optional output array name -____ - -Has 6 line(s). Doesn't call other functions. - -Not called by script or any function (may be e.g. a hook, a Zle widget, etc.). - --zui_std_get_mod_factor -~~~~~~~~~~~~~~~~~~~~~~~ - -____ - - Returns factor of given module (it's the number - of instances of the module that are generated) - - $1 - module index - $2 - output parameter name (default: REPLY) -____ - -Has 2 line(s). Doesn't call other functions. - -Not called by script or any function (may be e.g. a hook, a Zle widget, etc.). - --zui_std_get_mod_spacing -~~~~~~~~~~~~~~~~~~~~~~~~ - -____ - - Gets module's spacing, either from the transport place - - ZUI[SPACING_${mod}_${ice}] hash field, or from the - destination place - mod${1}_ice${2}_spacing parameter - directly used during on-the-fly generation or event-loop - generation. - - Testable, but errors will not happen. - - $1 - module index - $2 - instance index - $3 - "tra" or "dst" - transport or destination -____ - -Has 12 line(s). Doesn't call other functions. - -Not called by script or any function (may be e.g. a hook, a Zle widget, etc.). - --zui_std_get_stext -~~~~~~~~~~~~~~~~~~ - -____ - - - $1 - special-text string - $2 - optional output parameter name (default: "REPLY") - - REPLY: decoded text contained in the special string - -____ - -Has 8 line(s). Doesn't call other functions. - -Called by: - - syslib.lzui/-zui_sys_get_tfield_cursor_boundaries - --zui_std_has_any_hyperlinks -~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -____ - - Checks if given text has any hyperlinks (buttons/anchors/raws, - text fields, list boxes) -____ - -Has 3 line(s). Doesn't call other functions. - -Not called by script or any function (may be e.g. a hook, a Zle widget, etc.). - --zui_std_init -~~~~~~~~~~~~~ - -____ - - Initializes ZUI application. To be called before any emulate -L - Can take two arguments, prefixed with app: or app_name:, to set - ZUI[app] or ZUI[app_name] -____ - -Has 9 line(s). Doesn't call other functions. - -Not called by script or any function (may be e.g. a hook, a Zle widget, etc.). - --zui_std_init2 -~~~~~~~~~~~~~~ - -____ - - Initializes ZUI application. To - be called after any emulate -L -____ - -Has 9 line(s). Doesn't call other functions. - -Uses feature(s): _setopt_ - -Not called by script or any function (may be e.g. a hook, a Zle widget, etc.). - --zui_std_is_any_hyperlink -~~~~~~~~~~~~~~~~~~~~~~~~~ - -____ - - Tests if given text is a hyperlink. Returns (in REPLY) - "1" if plain hyperlink (anchor, button, raw link), "2" - if text field, "3" if list-box - - $1 - hyperlink - $2 - output parameter name, for type (default: REPLY) -____ - -Has 6 line(s). Calls functions: - - -zui_std_is_any_hyperlink - |-- -zui_std_is_hyperlink - |-- -zui_std_is_list_box - `-- -zui_std_is_text_field - -Not called by script or any function (may be e.g. a hook, a Zle widget, etc.). - --zui_std_is_hyperlink -~~~~~~~~~~~~~~~~~~~~~ - -____ - - Checks if given text is a button/anchor/raw hyperlink -____ - -Has 1 line(s). Doesn't call other functions. - -Called by: - - -zui_std_is_any_hyperlink - syslib.lzui/-zui_sys_get_tfield_cursor_boundaries - --zui_std_is_list_box -~~~~~~~~~~~~~~~~~~~~ - -____ - - Checks if given text is a list box hyperlink -____ - -Has 1 line(s). Doesn't call other functions. - -Called by: - - -zui_std_is_any_hyperlink - --zui_std_is_special_text -~~~~~~~~~~~~~~~~~~~~~~~~ - -____ - - Checks if given text is a button/anchor/raw hyperlink -____ - -Has 1 line(s). Doesn't call other functions. - -Not called by script or any function (may be e.g. a hook, a Zle widget, etc.). - --zui_std_is_text_field -~~~~~~~~~~~~~~~~~~~~~~ - -____ - - Checks if given text is a text field hyperlink -____ - -Has 1 line(s). Doesn't call other functions. - -Called by: - - -zui_std_is_any_hyperlink - --zui_std_list_box -~~~~~~~~~~~~~~~~~ - -____ - - Appends list-box hyperlink into output array (default: reply) - - $1 - action ID - $2 - width parameter (min and max text width - padding with spaces) - $3 - index parameter - what option is active - $4 - options parameter - name of parameter holding ";" separated options - $5 - data1 - $6 - data2 - $7 - data3 - $8 - handler (function name) - $9 - optional output array name (default: reply) - -____ - -Has 21 line(s). Doesn't call other functions. - -Not called by script or any function (may be e.g. a hook, a Zle widget, etc.). - --zui_std_load_config -~~~~~~~~~~~~~~~~~~~~ - -____ - - Loads variable from configuration if it's older than - e.g. 2 seconds. The point is: I expect users to not - always manage ZUI hash well: forgot to call *cleanup, - not reset ZUI[app], etc. This will be covered here: - if config field in ZUI is fresh, less than say 2 - seconds old, it means it's probably correctly aimed - at the ZUI application starting. If it's older, it's - a stray value from previous app. - - This applies only to configuration variables stored in - ZUI hash ($4 = ZUI\[*\]). Other target variables are - just being read, without age examination. - - $1 - Zstyle variable to load, with "s:" or "b:" prefix - for string or boolean - $2 - default value, 0 or 1 for bools - $3 - time limit - $4 - output parameter to fill (name) -____ - -Has 33 line(s). Doesn't call other functions. - -Uses feature(s): _zstyle_ - -Not called by script or any function (may be e.g. a hook, a Zle widget, etc.). - --zui_std_load_global_index_and_size -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -____ - - Use this to quickly load variables: - - - mod${midx}_ice${iidx}_global_index - - mod${midx}_ice${iidx}_size - - into parameters given by names. - - Has default target parameters' names - (REPLY & REPLY2), this might lead to - silent errors, but I prefer that to - error-revealing crash.. Hm.. - - $1 - module index - $2 - instance index - $3 - output parameter name for global index - $4 - output parameter name for size -____ - -Has 13 line(s). Doesn't call other functions. - -Not called by script or any function (may be e.g. a hook, a Zle widget, etc.). - --zui_std_map_replies -~~~~~~~~~~~~~~~~~~~~ - -____ - - Maps reply{,2..5} parameters onto module - parameters: - mod${midx}_ice${iidx}_output mod${midx}_ice${iidx}_size - mod${midx}_ice${iidx}_nonselectables mod${midx}_ice${iidx}_hops - mod${midx}_ice${iidx}_lanchors mod${midx}_ice${iidx}_spacing - - $1 - module index - $2 - instance index -____ - -Has 13 line(s). Doesn't call other functions. - -Called by: - - -zui_std_fly_array_refresh - -zui_std_fly_mod_regen - -zui_std_fly_mod_regen_ext - --zui_std_pack_hyperlinks_into_box -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -____ - - Puts given links in a box, i.e. into sequence of lines - that are limited in length. The sequence is returned - in reply array. The length of a link is the length of - its text, i.e. it doesn't include meta-data. - - $1 - box width (line length) - $2 - max box height (i.e. max # of lines) - $3 - hyperlink 1 - $4 - hyperlink 2 - $5 - ... - -____ - -Has 44 line(s). Doesn't call other functions. - -Not called by script or any function (may be e.g. a hook, a Zle widget, etc.). - --zui_std_rc_button -~~~~~~~~~~~~~~~~~~ - -____ - - Short rectangle button function - no user data - - $1 - action ID - $2 - text - $3 - optional handler function name, can be empty text - $4 - optional output variable name (defualt: 'reply') -____ - -Has 2 line(s). Calls functions: - - -zui_std_rc_button - `-- -zui_std_rc_button_ext - -Not called by script or any function (may be e.g. a hook, a Zle widget, etc.). - --zui_std_rc_button_ext -~~~~~~~~~~~~~~~~~~~~~~ - -____ - - Appends hyperlink into output array. It's an action button - shown with surrounding [ and ]. - - Arguments are the same as in -zui_std_button_ext - -____ - -Has 15 line(s). Doesn't call other functions. - -Called by: - - -zui_std_rc_button - --zui_std_refresh_configs -~~~~~~~~~~~~~~~~~~~~~~~~ - -____ - - Causes -zui_std_load_config to think - the configuration variable is freshly - loaded. Use this when restarting list - and updating ZUI[config] manually, with - no Zstyle update - - $1, $2 ... – keys in ZUI to update, config - variables' names -____ - -Has 6 line(s). Doesn't call other functions. - -Not called by script or any function (may be e.g. a hook, a Zle widget, etc.). - --zui_std_reset_replies -~~~~~~~~~~~~~~~~~~~~~~ - -____ - - Resets parameters reply{,2..5}, i.e. sets them - to empty arrays or strings -____ - -Has 1 line(s). Doesn't call other functions. - -Called by: - - -zui_std_fly_array_refresh - -zui_std_fly_mod_regen - -zui_std_fly_mod_regen_ext - --zui_std_serialize -~~~~~~~~~~~~~~~~~~ - -____ - - Stores my_* keys of ZUI hash into - "serialized_${ZUI[app]}" key, which - can be read with *deserialize() call -____ - -Has 11 line(s). Doesn't call other functions. - -Called by: - - -zui_std_cleanup - --zui_std_set_mod_factor -~~~~~~~~~~~~~~~~~~~~~~~ - -____ - - Modifies how many instances of a module should be generated. - A regeneration (no on-the-fly support) should be called on - the new instances. - - $1 - module index - $2 - new factor -____ - -Has 2 line(s). Doesn't call other functions. - -Not called by script or any function (may be e.g. a hook, a Zle widget, etc.). - --zui_std_set_mod_spacing -~~~~~~~~~~~~~~~~~~~~~~~~ - -____ - - It sets corresponding ZUI[SPACING_$mod_$ice] variable, - which then can be read in generator, and returned via - reply5, and from that point actually used in drawing, - either on-the-fly, or via restart to zui-event-loop. - So this is only a transport of data into generator, the - thing that directly sets spacing is reply5. Spacing is - the number of blank lines before the module's instance. - - TODO: on-the-fly regeneration ignores reply5 - - $1 - module index - $2 - instance index - $3 - the spacing to set (i.e. number of blank lines) -____ - -Has 1 line(s). Doesn't call other functions. - -Not called by script or any function (may be e.g. a hook, a Zle widget, etc.). - --zui_std_special_text -~~~~~~~~~~~~~~~~~~~~~ - -____ - - Appends special-text into output array. The text can contain special - characters like ', `, (, [, space. - - $1 - text - $2 - optional output array name - -____ - -Has 9 line(s). Doesn't call other functions. - -Not called by script or any function (may be e.g. a hook, a Zle widget, etc.). - --zui_std_stalog -~~~~~~~~~~~~~~~ - -Has 1 line(s). Calls functions: - - -zui_std_stalog - `-- syslib.lzui/-zui_sys_add_message - -Not called by script or any function (may be e.g. a hook, a Zle widget, etc.). - --zui_std_store_default_app_config -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -____ - - Stores given ZUI[app] configuration if it is not - already set by user, i.e. if given Zstyle is empty, - it is then set to given value, so that ZUI will - read it as the application default, overriding ZUI - global default. - - $1 - Zstyle variable to write, with "s:" or "b:" prefix - for string or boolean - $2 - value to write, 0 or 1 for bools - - Returns 0 if written, 1 if Zstyle was already set -____ - -Has 18 line(s). Doesn't call other functions. - -Uses feature(s): _zstyle_ - -Not called by script or any function (may be e.g. a hook, a Zle widget, etc.). - --zui_std_strip_color_codes -~~~~~~~~~~~~~~~~~~~~~~~~~~ - -Has 1 line(s). Doesn't call other functions. - -Not called by script or any function (may be e.g. a hook, a Zle widget, etc.). - --zui_std_strip_meta_data -~~~~~~~~~~~~~~~~~~~~~~~~ - -Has 9 line(s). Doesn't call other functions. - -Not called by script or any function (may be e.g. a hook, a Zle widget, etc.). - --zui_std_submit_fly_from_gen_replies -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -____ - - Internal action can call this function in - order to replace module with new version. - But see call -zui_std_fly_mod_regen. - - It uses parameters reply{,2..5} normally - returned from a module generator. It covers - calls to multiple submit functions: - - - -zui_std_submit_list_update - - -zui_std_submit_nonselectables - - -zui_std_submit_hops - - -zui_std_submit_lanchors - - $1 - module index - $2 - instance index -____ - -Has 9 line(s). Calls functions: - - -zui_std_submit_fly_from_gen_replies - |-- -zui_std_submit_hops - |-- -zui_std_submit_lanchors - |-- -zui_std_submit_list_update - `-- -zui_std_submit_nonselectables - -Called by: - - -zui_std_fly_array_refresh - -zui_std_fly_mod_regen - -zui_std_fly_mod_regen_ext - --zui_std_submit_hops -~~~~~~~~~~~~~~~~~~~~ - -____ - - Internal action can call this function when - replacing part of list to provide new hops, - by submitting local indices. They will be - automatically translated to global indices. - - $1, $2, ... - local indices of hops in the - substituted fragment -____ - -Has 1 line(s). Doesn't call other functions. - -Called by: - - -zui_std_submit_fly_from_gen_replies - --zui_std_submit_lanchors -~~~~~~~~~~~~~~~~~~~~~~~~ - -____ - - Internal action can call this function when - replacing part of list to provide new local - anchors (their IDs). Their indices (stored - in $ZUI) will be globalized. - - $1, $2, ... - IDs of anchors to be globalized -____ - -Has 1 line(s). Doesn't call other functions. - -Called by: - - -zui_std_submit_fly_from_gen_replies - --zui_std_submit_list_update -~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -____ - - Internal action can call this function in - order to replace part of list with new text. - - $1 - module index, can be empty for stray list update - $2 - instance index, can be empty as above - $3 - beginning line number of area to replace - $4 - end line number of area to replace - $5, $6, ... - new elements to replace lines $1..$2 -____ - -Has 3 line(s). Doesn't call other functions. - -Called by: - - -zui_std_submit_fly_from_gen_replies - --zui_std_submit_nonselectables -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -____ - - Internal action can call this function when - replacing part of list to provide new local - indices that are non-selectable. They will - be translated to global indices. - - $1, $2, ... - local indices of nonselectables - in the substituted fragment -____ - -Has 1 line(s). Doesn't call other functions. - -Called by: - - -zui_std_submit_fly_from_gen_replies - --zui_std_text_field -~~~~~~~~~~~~~~~~~~~ - -____ - - Appends text-field hyperlink into output array (default: reply) - - $1 - action ID - $2 - width parameter (min and max text width - padding with "_") - $3 - start-index parameter - what part of string to show - $4 - text parameter - name of parameter holding text - $5 - data1 - $6 - data2 - $7 - data3 - $8 - handler (function name) - $9 - optional output array name (default: reply) - -____ - -Has 21 line(s). Doesn't call other functions. - -Not called by script or any function (may be e.g. a hook, a Zle widget, etc.). - diff --git a/functions/-zui-list-box-loop b/functions/-zui-list-box-loop index 1f7cf8c..435831d 100644 --- a/functions/-zui-list-box-loop +++ b/functions/-zui-list-box-loop @@ -1,16 +1,13 @@ -# ============================================================================ # -# [ https://github.com/z-shell ] ❮ ZI ❯ [ (c) 2022 Z-SHELL COMMUNITY ] # -# ============================================================================ # -# # -*- mode: zsh; sh-indentation: 2; indent-tabs-mode: nil; sh-basic-offset: 2; -*- # vim: ft=zsh sw=2 ts=2 et -# + # Draws list-box drop-down list local __page_height="$1" __page_width="$2" __ypos="$3" __xpos="$4" __id="$5" __width_var="$6" __idx_var="$7" __opts_var="$8" __data2="$9" __data2="$10" __data3="$11" # Get maximum width local -a options options=( "${(@Ps:;:)__opts_var}" ) + # Remove color marks # [all] [fg] [bg] TEXT options=( "${options[@]//(#b)([$'\03'-$'\07'$'\013'-$'\014'$'\016'-$'\031'])([$'\03'-$'\07'$'\013'-$'\014'$'\016'-$'\017']|)([$'\020'-$'\030']|)([^${ZUI[FMT_END]}]#)${ZUI[FMT_END]}/$match[4]}" ) @@ -19,26 +16,26 @@ options=( "${options[@]//(#b)([$'\03'-$'\07'$'\013'-$'\014'$'\016'-$'\031'])([$' local txt integer width=7 height=10 size="${#options}" for txt in "${options[@]}"; do - (( width = ${(m)#txt} > width ? ${(m)#txt} : width )) + (( width = ${(m)#txt} > width ? ${(m)#txt} : width )) done if (( __ypos + size + 2 > __page_height + 1 )); then - if (( size + 2 > __page_height + 1 )); then - height=__page_height-2 - (( height <= 0 )) && height=__page_height # paranoid - __ypos=3 - else - height=size - (( __ypos = __page_height - size - 1 )) - fi -else - (( __ypos+=1 )) + if (( size + 2 > __page_height + 1 )); then + height=__page_height-2 + (( height <= 0 )) && height=__page_height # paranoid + __ypos=3 + else height=size + (( __ypos = __page_height - size - 1 )) + fi +else + (( __ypos+=1 )) + height=size fi if (( __xpos + width + 4 > __page_width )); then - # Basic protection, can be inaccurate - (( __xpos=__page_width - width - 4 )) + # Basic protection, can be inaccurate + (( __xpos=__page_width - width - 4 )) fi zcurses delwin lbox 2>/dev/null @@ -49,6 +46,7 @@ zcurses bg lbox "${ZUI[colorpair]}" zcurses timeout lbox 0 zcurses input lbox key keypad zcurses timeout lbox -1 + key="" keypad="" @@ -56,89 +54,87 @@ integer hidx __start __end return_val=0 initial_idx=${(P)__idx_var} __start=initial_idx-height/2 if (( __start <= 0 )); then - __start=1 - __end=size - if (( size > height )); then - __end=height - fi + __start=1 + __end=size + if (( size > height )); then + __end=height + fi elif (( __start + height - 1 > size )); then - __start=size-height+1 - __end=size + __start=size-height+1 + __end=size else - __end=initial_idx+(height-height/2)-1 + __end=initial_idx+(height-height/2)-1 fi while (( 1 )); do - # Draw list box - zcurses clear lbox - - integer i count=1 - hidx=${(P)__idx_var} - for (( i = __start; i <= __end; ++ i )); do - txt="${options[i]}" - zcurses move lbox "$count" 2 - - if (( i == hidx )); then - zcurses attr lbox +reverse - zcurses string lbox "$txt" - zcurses attr lbox -reverse - else - zcurses string lbox "$txt" - fi - - (( ++ count )) - done - - zcurses border lbox - zcurses refresh lbox - - # Wait for input - local key keypad final_key - zcurses input "lbox" key keypad - - # Get the special (i.e. "keypad") key or regular key - if [[ -n "$key" ]]; then - final_key="$key" - elif [[ -n "$keypad" ]]; then - final_key="$keypad" - fi - - case "$final_key" in - (UP|k|BTAB) - hidx=${(P)__idx_var} - (( hidx = hidx > 1 ? hidx-1 : hidx )) - if (( hidx < __start )); then - __start=hidx - __end=__start+height-1 - fi - : ${(P)__idx_var::=$hidx} - ;; - (DOWN|j|$'\t') - hidx=${(P)__idx_var} - (( hidx = hidx < ${#options} ? hidx+1 : hidx )) - if (( hidx > __end )); then - __end=hidx - __start=__end-height+1 - fi - : ${(P)__idx_var::=$hidx} - ;; - ($'\E') - : ${(P)__idx_var::=$initial_idx} - return_val=1 - break - ;; - ($'\n') - break - ;; - (??*) - ;; - (*) - ;; - esac + # Draw list box + zcurses clear lbox + + integer i count=1 + hidx=${(P)__idx_var} + for (( i = __start; i <= __end; ++ i )); do + txt="${options[i]}" + zcurses move lbox "$count" 2 + + if (( i == hidx )); then + zcurses attr lbox +reverse + zcurses string lbox "$txt" + zcurses attr lbox -reverse + else + zcurses string lbox "$txt" + fi + + (( ++ count )) + done + + zcurses border lbox + zcurses refresh lbox + + # Wait for input + local key keypad final_key + zcurses input "lbox" key keypad + + # Get the special (i.e. "keypad") key or regular key + if [[ -n "$key" ]]; then + final_key="$key" + elif [[ -n "$keypad" ]]; then + final_key="$keypad" + fi + + case "$final_key" in + (UP|k|BTAB) + hidx=${(P)__idx_var} + (( hidx = hidx > 1 ? hidx-1 : hidx )) + if (( hidx < __start )); then + __start=hidx + __end=__start+height-1 + fi + : ${(P)__idx_var::=$hidx} + ;; + (DOWN|j|$'\t') + hidx=${(P)__idx_var} + (( hidx = hidx < ${#options} ? hidx+1 : hidx )) + if (( hidx > __end )); then + __end=hidx + __start=__end-height+1 + fi + : ${(P)__idx_var::=$hidx} + ;; + ($'\E') + : ${(P)__idx_var::=$initial_idx} + return_val=1 + break + ;; + ($'\n') + break + ;; + (??*) + ;; + (*) + ;; + esac done zcurses delwin lbox 2>/dev/null return $return_val - -# vim:ft=zsh diff --git a/functions/-zui-log b/functions/-zui-log index 8ee86fc..74a75de 100644 --- a/functions/-zui-log +++ b/functions/-zui-log @@ -1,7 +1,3 @@ -# ============================================================================ # -# [ https://github.com/z-shell ] ❮ ZI ❯ [ (c) 2022 Z-SHELL COMMUNITY ] # -# ============================================================================ # -# # -*- mode: zsh; sh-indentation: 2; indent-tabs-mode: nil; sh-basic-offset: 2; -*- # vim: ft=zsh sw=2 ts=2 et # @@ -32,92 +28,94 @@ # $4 - indentation # $5 - actual length of text in current line (output parameter name) -zuilog_counted_msg() { - local color="$1" txt="$2" line_var="$3" indent="$4" actlen_var="$5" - - [[ -z "$txt" ]] && return 0 - - [[ -n "$color" ]] && zcurses attr "$window" "$color/${win_colorpair#*/}" - - while (( ${(P)actlen_var} + ${#txt} > win_width - indent * 2 )); do - integer part_count=$(( (win_width - indent * 2) - ${(P)actlen_var} )) - zcurses string "$window" "${txt[1,part_count]}" - : ${(P)actlen_var::=0} - # Needed next line 0-based > maximum line 0-based -> abort - [[ $(( ${(P)line_var} + 1 )) -gt $(( win_height - win_border - 1 )) ]] && { - [[ -n "$color" ]] && zcurses attr "$window" "$win_colorpair" - return 1 - } - txt="${txt[part_count+1,-1]}" - - # Curses cursor: right after text. Line number: at text. - if [[ -n "$txt" ]]; then - : ${(P)line_var::=${(P)line_var}+1} - zcurses move "$window" "${(P)line_var}" "$indent" - fi - done + local color="$1" txt="$2" line_var="$3" indent="$4" actlen_var="$5" + + [[ -z "$txt" ]] && return 0 + + [[ -n "$color" ]] && zcurses attr "$window" "$color/${win_colorpair#*/}" + + while (( ${(P)actlen_var} + ${#txt} > win_width - indent * 2 )); do + integer part_count=$(( (win_width - indent * 2) - ${(P)actlen_var} )) + zcurses string "$window" "${txt[1,part_count]}" + : ${(P)actlen_var::=0} + # Needed next line 0-based > maximum line 0-based -> abort + [[ $(( ${(P)line_var} + 1 )) -gt $(( win_height - win_border - 1 )) ]] && { + [[ -n "$color" ]] && zcurses attr "$window" "$win_colorpair" + return 1 + } + txt="${txt[part_count+1,-1]}" + + # Curses cursor: right after text. Line number: at text. if [[ -n "$txt" ]]; then - zcurses string "$window" "$txt" - : ${(P)actlen_var::=${(P)actlen_var}+${#txt}} + : ${(P)line_var::=${(P)line_var}+1} + zcurses move "$window" "${(P)line_var}" "$indent" fi + done + + if [[ -n "$txt" ]]; then + zcurses string "$window" "$txt" + : ${(P)actlen_var::=${(P)actlen_var}+${#txt}} + fi - [[ -n "$color" ]] && zcurses attr "$window" "$win_colorpair" + [[ -n "$color" ]] && zcurses attr "$window" "$win_colorpair" - return 0 + return 0 } # Outputs a message in the bottom of the screen # "[UNIQ]", "Text", "[Grep string]", "Generation time", "$reply[@]" from callback -zuilog_output_message() { - local direction="${1:-above}" line_var="$2" entry="$3" number="$4" txt - integer indent=2 msg_len track_len=0 index=0 - - local -a elems - elems=( "${(@Q)${(z@)entry}}" ) - msg_len="${elems[1]}" - shift 3 elems - - (( msg_len == 0 )) && return - - msg_len+=${#elems[1]} - - (( number > 0 )) && msg_len+=3+${#number} - - # - # Scroll - # - - if [[ "$direction" = "below" ]]; then - # (P)line_var is 0-based and it points after previous text - integer __line="${(P)line_var}"+$(( (msg_len-1)/(win_width-2*indent) )) - # Needed line 0-based, minus maximum line 0-based - integer __scroll=__line-$(( win_height - win_border - 1 )) - if (( __scroll > 0 )); then - (( __scroll = __scroll > (${(P)line_var}-win_border) ? ${(P)line_var} - win_border : __scroll )) - zcurses scroll "$window" +$__scroll - : ${(P)line_var::=${(P)line_var}-$__scroll} - fi - elif [[ "$direction" = "above" ]]; then - zcurses scroll "$window" -$(( 1 + (msg_len-1)/(win_width-2*indent) )) + local direction="${1:-above}" line_var="$2" entry="$3" number="$4" txt + integer indent=2 msg_len track_len=0 index=0 + + local -a elems + elems=( "${(@Q)${(z@)entry}}" ) + msg_len="${elems[1]}" + shift 3 elems + + (( msg_len == 0 )) && return + + msg_len+=${#elems[1]} + + (( number > 0 )) && msg_len+=3+${#number} + + # + # Scroll + # + + if [[ "$direction" = "below" ]]; then + # (P)line_var is 0-based and it points after previous text + integer __line="${(P)line_var}"+$(( (msg_len-1)/(win_width-2*indent) )) + + # Needed line 0-based, minus maximum line 0-based + integer __scroll=__line-$(( win_height - win_border - 1 )) + if (( __scroll > 0 )); then + (( __scroll = __scroll > (${(P)line_var}-win_border) ? ${(P)line_var} - win_border : __scroll )) + zcurses scroll "$window" +$__scroll + : ${(P)line_var::=${(P)line_var}-$__scroll} fi + elif [[ "$direction" = "above" ]]; then + zcurses scroll "$window" -$(( 1 + (msg_len-1)/(win_width-2*indent) )) + fi - zcurses move "$window" "${(P)line_var}" $indent + zcurses move "$window" "${(P)line_var}" $indent - # - # Print - # + # + # Print + # - (( number > 0 )) && -zuilog_counted_msg "${zui_log_colors[1]}" "[$number] " "$line_var" $indent track_len + (( number > 0 )) && -zuilog_counted_msg "${zui_log_colors[1]}" "[$number] " "$line_var" $indent track_len - index=2 - for txt in "${elems[@]}"; do - [[ -n "$txt" ]] && { -zuilog_counted_msg "${zui_log_colors[index]}" "$txt" "$line_var" $indent track_len || break; } - (( ++ index )) - done + index=2 + for txt in "${elems[@]}"; do + [[ -n "$txt" ]] && { -zuilog_counted_msg "${zui_log_colors[index]}" "$txt" "$line_var" $indent track_len || break; } + (( ++ index )) + done - # Return number of lines of the message - REPLY=$(( (msg_len-1)/(win_width-2*indent) + 1 )) + # Return number of lines of the message + REPLY=$(( (msg_len-1)/(win_width-2*indent) + 1 )) } local window="$1" @@ -151,34 +149,33 @@ zcurses clear "$window" local entry for entry in "${(@)ZUI_MESSAGES[start,last]}"; do - -zuilog_output_message "${ZUI[log_append]}" "line" "$entry" "$message_num" - (( message_num = message_num ? ++ message_num : 0 )) - - if [[ "${ZUI[log_append]}" = "below" ]]; then - (( ++ line )) - else - (( line = win_border )) - fi + -zuilog_output_message "${ZUI[log_append]}" "line" "$entry" "$message_num" + (( message_num = message_num ? ++ message_num : 0 )) + + if [[ "${ZUI[log_append]}" = "below" ]]; then + (( ++ line )) + else + (( line = win_border )) + fi done if [[ "${ZUI[status_pointer]}" = "1" ]]; then - if [[ "${ZUI[log_append]}" = "above" || $(( win_height - win_border - 1 )) -ge "$line" || "$REPLY" -ge $(( win_height - 2*win_border )) ]]; then - zcurses scroll "$window" -1 - fi + if [[ "${ZUI[log_append]}" = "above" || $(( win_height - win_border - 1 )) -ge "$line" || "$REPLY" -ge $(( win_height - 2*win_border )) ]]; then + zcurses scroll "$window" -1 + fi - zcurses move "$window" "$win_border" 2 - zcurses clear "$window" eol + zcurses move "$window" "$win_border" 2 + zcurses clear "$window" eol - local track_len=0 - line=0 + local track_len=0 + line=0 - if [[ -n "$_gen" ]]; then - -zuilog_counted_msg "yellow" "$_gen " line 2 track_len - else - for txt in $_uniq $_text $_grep; do - -zuilog_counted_msg "" "$txt " line 2 track_len - done - fi + if [[ -n "$_gen" ]]; then + -zuilog_counted_msg "yellow" "$_gen " line 2 track_len + else + for txt in $_uniq $_text $_grep; do + -zuilog_counted_msg "" "$txt " line 2 track_len + done + fi fi -# vim:ft=zsh diff --git a/functions/zui-event-loop b/functions/zui-event-loop index fbbd906..fd7545c 100644 --- a/functions/zui-event-loop +++ b/functions/zui-event-loop @@ -1,21 +1,17 @@ -# ============================================================================ # -# [ https://github.com/z-shell ] ❮ ZI ❯ [ (c) 2022 Z-SHELL COMMUNITY ] # -# ============================================================================ # -# # -*- mode: zsh; sh-indentation: 2; indent-tabs-mode: nil; sh-basic-offset: 2; -*- # vim: ft=zsh sw=2 ts=2 et # # Started from zle or from command line # -[[ "${ZUI[stdlib_sourced]}" != "1" ]] && source "${ZUI_REPO_DIR}/stdlib.lzui" -[[ "${ZUI[syslib_sourced]}" != "1" ]] && source "${ZUI_REPO_DIR}/syslib.lzui" -[[ "${ZUI[utillib_sourced]}" != "1" ]] && source "${ZUI_REPO_DIR}/utillib.lzui" +[[ "${ZUI[stdlib_sourced]}" != "1" ]] && builtin source "${Plugins[ZUI_DIR]}/stdlib.lzui" +[[ "${ZUI[syslib_sourced]}" != "1" ]] && builtin source "${Plugins[ZUI_DIR]}/syslib.lzui" +[[ "${ZUI[utillib_sourced]}" != "1" ]] && builtin source "${Plugins[ZUI_DIR]}/utillib.lzui" -emulate -LR zsh -setopt extendedglob typesetsilent warncreateglobal +builtin emulate -LR zsh +builtin setopt extended_glob typeset_silent warn_create_global -[[ "${ZUI[PROMPT_SUBST]}" = "1" ]] && setopt promptsubst +[[ "${ZUI[PROMPT_SUBST]}" = "1" ]] && setopt prompt_subst # Should provide the top anchors? -zui_std_load_config b:top_anchors 1 2 'ZUI[top_anchors]' diff --git a/functions/zui-list b/functions/zui-list index e6edbf3..7ec9d61 100644 --- a/functions/zui-list +++ b/functions/zui-list @@ -1,7 +1,3 @@ -# ============================================================================ # -# [ https://github.com/z-shell ] ❮ ZI ❯ [ (c) 2022 Z-SHELL COMMUNITY ] # -# ============================================================================ # -# # -*- mode: zsh; sh-indentation: 2; indent-tabs-mode: nil; sh-basic-offset: 2; -*- # vim: ft=zsh sw=2 ts=2 et # @@ -20,10 +16,10 @@ # Besides vertical navigation, it does horizontal navigation over elements of line. # Uses curses library. -emulate -LR zsh +builtin emulate -LR zsh +builtin setopt typeset_silent extended_glob no_short_loops -setopt typesetsilent extendedglob noshortloops -[[ "${ZUI[PROMPT_SUBST]}" = "1" ]] && setopt promptsubst +[[ "${ZUI[PROMPT_SUBST]}" = "1" ]] && setopt prompt_subst zmodload zsh/curses zmodload zsh/terminfo 2>/dev/null diff --git a/functions/zui-list-draw b/functions/zui-list-draw index ee1f42d..3494c4b 100644 --- a/functions/zui-list-draw +++ b/functions/zui-list-draw @@ -1,14 +1,11 @@ -# ============================================================================ # -# [ https://github.com/z-shell ] ❮ ZI ❯ [ (c) 2022 Z-SHELL COMMUNITY ] # -# ============================================================================ # -# # -*- mode: zsh; sh-indentation: 2; indent-tabs-mode: nil; sh-basic-offset: 2; -*- # vim: ft=zsh sw=2 ts=2 et -emulate -L zsh + +builtin emulate -L zsh zmodload zsh/curses -setopt typesetsilent extendedglob +builtin setopt typeset_silent extended_glob -zui_list_print_with_ansi() { local win="$1" text="$2" out col bcol attr chunk Xout diff --git a/functions/zui-list-input b/functions/zui-list-input index 733ee78..cebdefe 100644 --- a/functions/zui-list-input +++ b/functions/zui-list-input @@ -1,14 +1,11 @@ -# ============================================================================ # -# [ https://github.com/z-shell ] ❮ ZI ❯ [ (c) 2022 Z-SHELL COMMUNITY ] # -# ============================================================================ # -# # -*- mode: zsh; sh-indentation: 2; indent-tabs-mode: nil; sh-basic-offset: 2; -*- # vim: ft=zsh sw=2 ts=2 et -emulate -L zsh + +builtin emulate -L zsh zmodload zsh/curses -setopt typesetsilent extendedglob +builtin setopt typeset_silent extended_glob # Compute first to show index - exact page -zui_listin_compute_first_to_show_idx() { diff --git a/functions/zui-list-wrapper b/functions/zui-list-wrapper index ff7a612..46e5983 100644 --- a/functions/zui-list-wrapper +++ b/functions/zui-list-wrapper @@ -1,11 +1,8 @@ -# ============================================================================ # -# [ https://github.com/z-shell ] ❮ ZI ❯ [ (c) 2022 Z-SHELL COMMUNITY ] # -# ============================================================================ # -# # -*- mode: zsh; sh-indentation: 2; indent-tabs-mode: nil; sh-basic-offset: 2; -*- # vim: ft=zsh sw=2 ts=2 et -emulate -LR zsh -setopt extendedglob warncreateglobal + +builtin emulate -LR zsh +builtin setopt extended_glob warn_create_global local _zui_wrapper_has_terminfo=0 @@ -111,9 +108,9 @@ ZUI[term_sread_ts]="$EPOCHSECONDS" } # Standard functions library -[[ "${ZUI[stdlib_sourced]}" != "1" ]] && source "${ZUI_REPO_DIR}/lib/stdlib.lzui" -[[ "${ZUI[syslib_sourced]}" != "1" ]] && source "${ZUI_REPO_DIR}/lib/syslib.lzui" -[[ "${ZUI[utillib_sourced]}" != "1" ]] && source "${ZUI_REPO_DIR}/lib/utillib.lzui" +[[ "${ZUI[stdlib_sourced]}" != "1" ]] && source "${Plugins[ZUI_DIR]}/lib/stdlib.lzui" +[[ "${ZUI[syslib_sourced]}" != "1" ]] && source "${Plugins[ZUI_DIR]}/lib/syslib.lzui" +[[ "${ZUI[utillib_sourced]}" != "1" ]] && source "${Plugins[ZUI_DIR]}/lib/utillib.lzui" # Configuration -zui_std_load_config s:select_mode "no-restart" 2 'ZUI[select_mode]' # quit, restart or callback diff --git a/functions/zui-process-buffer b/functions/zui-process-buffer index 9bb2024..d44c258 100644 --- a/functions/zui-process-buffer +++ b/functions/zui-process-buffer @@ -1,7 +1,3 @@ -# ============================================================================ # -# [ https://github.com/z-shell ] ❮ ZI ❯ [ (c) 2022 Z-SHELL COMMUNITY ] # -# ============================================================================ # -# # -*- mode: zsh; sh-indentation: 2; indent-tabs-mode: nil; sh-basic-offset: 2; -*- # vim: ft=zsh sw=2 ts=2 et # @@ -18,8 +14,8 @@ # ZUI_PB_RIGHT - right part of active word # -emulate -LR zsh -setopt typesetsilent extendedglob noshortloops +builtin emulate -LR zsh +builtin setopt typeset_silent extended_glob no_short_loops local MBEGIN MEND MATCH mbegin mend match diff --git a/functions/zui-process-buffer2 b/functions/zui-process-buffer2 index 588b47c..c7ba018 100644 --- a/functions/zui-process-buffer2 +++ b/functions/zui-process-buffer2 @@ -1,7 +1,3 @@ -# ============================================================================ # -# [ https://github.com/z-shell ] ❮ ZI ❯ [ (c) 2022 Z-SHELL COMMUNITY ] # -# ============================================================================ # -# # -*- mode: zsh; sh-indentation: 2; indent-tabs-mode: nil; sh-basic-offset: 2; -*- # vim: ft=zsh sw=2 ts=2 et # @@ -17,8 +13,8 @@ # ZUI_PB2_QSPACES - the same, but in ZUI_PB2_QWORDS # -emulate -LR zsh -setopt typesetsilent extendedglob noshortloops +builtin emulate -LR zsh +builtin setopt typeset_silent extended_glob no_short_loops local MBEGIN MEND MATCH mbegin mend match diff --git a/functions/zui-usetty-wrapper b/functions/zui-usetty-wrapper index f8262d3..e914a1d 100644 --- a/functions/zui-usetty-wrapper +++ b/functions/zui-usetty-wrapper @@ -1,40 +1,35 @@ -# ============================================================================ # -# [ https://github.com/z-shell ] ❮ ZI ❯ [ (c) 2022 Z-SHELL COMMUNITY ] # -# ============================================================================ # -# # -*- mode: zsh; sh-indentation: 2; indent-tabs-mode: nil; sh-basic-offset: 2; -*- # vim: ft=zsh sw=2 ts=2 et -emulate -L zsh - +builtin emulate -L zsh zmodload zsh/curses test_fd0() { - true <&0 + true <&0 } local restore=0 FD # Reattach to terminal if [ ! -t 0 ]; then - # Check if can reattach to terminal in any way - if [[ ! -c /dev/tty && ! -t 2 ]]; then - echo "No terminal available (no /dev/tty and no terminal at stderr)" - return 1 - fi - - if test_fd0 2>/dev/null; then - exec {FD}<&0 - restore=2 - else - restore=1 - fi - - if [[ ! -c /dev/tty ]]; then - exec <&2 - else - exec /dev/null; then + exec {FD}<&0 + restore=2 + else + restore=1 + fi + + if [[ ! -c /dev/tty ]]; then + exec <&2 + else + exec && "$__data1" != <->[-+]<-> ]] && __data1="1+0+0+0" - - # With no handler do only no-restart jumps - local hpfx="zuiiaction" __pfx="zuianchor" - [[ -n "$__handler" ]] && { - [[ $__handler = *internal* ]] || { hpfx="zuiaction"; __pfx="zuieanchor"; } - ZUI[$hpfx$__id]="$__handler" - unset hpfx - } || { - # Passed a regeneration instruction? - # This will make link external, i.e. - # leading to list restart (so, it's - # "external" to the list; "internal" - # is ran within single list run). - [[ "$__data3" = ,*, ]] && __pfx="zuieanchor" - } - - # Quote only text, not codes - __text="${__text//(#b)([^$'\03'-$'\07'$'\013'-$'\014'$'\016'-$'\031'$'\037']##)/${(q)match[1]}}" - - __var_name="${__var_name}[${(P)#__var_name}+1]" - local __output=$'\01'"$__pfx$__id"$'\01'"$__data1"$'\01'"$__data2"$'\01'"$__data3"$'\01'"$__data4"$'\02'"${__text}"$'\02' - : ${(PA)__var_name::=$__output} - - # Store anchor's target line index - ZUI[$__pfx$__id]="$__data1" +-zui_std_anchor() { + setopt local_options extended_glob + + local __id="${(q)1}" __data1="${(q)2}" __data2="${(q)3}" __data3="${(q)4}" __data4="${(q)5}" __text="$6" __handler="$7" + local __var_name="${8:-reply}" + + # Set to some weird line that probably exists, + # to signal that anchor works, but input line + # number is incorrect + # [[ "$__data1" != <-> && "$__data1" != <->[-+]<-> ]] && __data1="1+0+0+0" + + # With no handler do only no-restart jumps + local hpfx="zuiiaction" __pfx="zuianchor" + [[ -n "$__handler" ]] && { + [[ $__handler = *internal* ]] || { hpfx="zuiaction"; __pfx="zuieanchor"; } + ZUI[$hpfx$__id]="$__handler" + unset hpfx + } || { + # Passed a regeneration instruction? + # This will make link external, i.e. + # leading to list restart (so, it's + # "external" to the list; "internal" + # is ran within single list run). + [[ "$__data3" = ,*, ]] && __pfx="zuieanchor" + } + + # Quote only text, not codes + __text="${__text//(#b)([^$'\03'-$'\07'$'\013'-$'\014'$'\016'-$'\031'$'\037']##)/${(q)match[1]}}" + + __var_name="${__var_name}[${(P)#__var_name}+1]" + local __output=$'\01'"$__pfx$__id"$'\01'"$__data1"$'\01'"$__data2"$'\01'"$__data3"$'\01'"$__data4"$'\02'"${__text}"$'\02' + : ${(PA)__var_name::=$__output} + + # Store anchor's target line index + ZUI[$__pfx$__id]="$__data1" } # }}} # FUNCTION: -zui_std_text_field {{{ @@ -299,29 +291,28 @@ function -zui_std_anchor() { # $7 - data3 # $8 - handler (function name) # $9 - optional output array name (default: reply) -# -function -zui_std_text_field() { - local __id="${(q)1}" __width_var="${(q)2}" __sidx_var="${(q)3}" __text_var="${(q)4}" __data1="${(q)5}" __data2="${(q)6}" __data3="${(q)7}" __handler="$8" - local __var_name="${9:-reply}" +-zui_std_text_field() { + local __id="${(q)1}" __width_var="${(q)2}" __sidx_var="${(q)3}" __text_var="${(q)4}" __data1="${(q)5}" __data2="${(q)6}" __data3="${(q)7}" __handler="$8" + local __var_name="${9:-reply}" - [[ -n "$__handler" ]] && ZUI[zuitfield$__id]="$__handler" + [[ -n "$__handler" ]] && ZUI[zuitfield$__id]="$__handler" - __var_name="${__var_name}[${(P)#__var_name}+1]" + __var_name="${__var_name}[${(P)#__var_name}+1]" - if (( ${(P)+${(Q)__width_var}} + ${(P)+${(Q)__sidx_var}} + ${(P)+${(Q)__text_var}} != 3 )); then - local __key_part=$RANDOM - ZUI[my_err_tfield_width_${__key_part}]=100 - ZUI[my_err_tfield_sidx_${__key_part}]=1 - ZUI[my_err_tfield_data_${__key_part}]="ERROR: Not all variables exist: ${(Q)__width_var}, ${(Q)__sidx_var}, ${(Q)__text_var}" - __width_var="ZUI\[my_err_tfield_width_${__key_part}\]" - __sidx_var="ZUI\[my_err_tfield_sidx_${__key_part}\]" - __text_var="ZUI\[my_err_tfield_data_${__key_part}\]" - fi + if (( ${(P)+${(Q)__width_var}} + ${(P)+${(Q)__sidx_var}} + ${(P)+${(Q)__text_var}} != 3 )); then + local __key_part=$RANDOM + ZUI[my_err_tfield_width_${__key_part}]=100 + ZUI[my_err_tfield_sidx_${__key_part}]=1 + ZUI[my_err_tfield_data_${__key_part}]="ERROR: Not all variables exist: ${(Q)__width_var}, ${(Q)__sidx_var}, ${(Q)__text_var}" + __width_var="ZUI\[my_err_tfield_width_${__key_part}\]" + __sidx_var="ZUI\[my_err_tfield_sidx_${__key_part}\]" + __text_var="ZUI\[my_err_tfield_data_${__key_part}\]" + fi - local __output=$'\032'"zuitfield$__id"$'\032'"$__data1"$'\032'"$__data2"$'\032'"$__data3"$'\032'"$__width_var"$'\032'"$__sidx_var"$'\032'"$__text_var"$'\02' + local __output=$'\032'"zuitfield$__id"$'\032'"$__data1"$'\032'"$__data2"$'\032'"$__data3"$'\032'"$__width_var"$'\032'"$__sidx_var"$'\032'"$__text_var"$'\02' - unset __id __module_idx __width_var __sidx_var __text_var __data1 __data2 __handler - : ${(PA)__var_name::=$__output} + unset __id __module_idx __width_var __sidx_var __text_var __data1 __data2 __handler + : ${(PA)__var_name::=$__output} } # }}} # FUNCTION: -zui_std_list_box {{{ @@ -336,29 +327,28 @@ function -zui_std_text_field() { # $7 - data3 # $8 - handler (function name) # $9 - optional output array name (default: reply) -# -function -zui_std_list_box() { - local __id="${(q)1}" __width_var="${(q)2}" __idx_var="${(q)3}" __opts_var="${(q)4}" __data1="${(q)5}" __data2="${(q)6}" __data3="${(q)7}" __handler="$8" - local __var_name="${9:-reply}" +-zui_std_list_box() { + local __id="${(q)1}" __width_var="${(q)2}" __idx_var="${(q)3}" __opts_var="${(q)4}" __data1="${(q)5}" __data2="${(q)6}" __data3="${(q)7}" __handler="$8" + local __var_name="${9:-reply}" - [[ -n "$__handler" ]] && ZUI[zuilbox$__id]="$__handler" + [[ -n "$__handler" ]] && ZUI[zuilbox$__id]="$__handler" - __var_name="${__var_name}[${(P)#__var_name}+1]" + __var_name="${__var_name}[${(P)#__var_name}+1]" - if (( ${(P)+${(Q)__width_var}} + ${(P)+${(Q)__idx_var}} + ${(P)+${(Q)__opts_var}} != 3 )); then - local __key_part=$RANDOM - ZUI[my_err_tfield_width_${__key_part}]=100 - ZUI[my_err_tfield_idx_${__key_part}]=1 - ZUI[my_err_tfield_data_${__key_part}]="ERROR: Not all variables exist: ${(Q)__width_var}, ${(Q)__idx_var}, ${(Q)__opts_var}" - __width_var="ZUI\[my_err_tfield_width_${__key_part}\]" - __idx_var="ZUI\[my_err_tfield_idx_${__key_part}\]" - __opts_var="ZUI\[my_err_tfield_data_${__key_part}\]" - fi + if (( ${(P)+${(Q)__width_var}} + ${(P)+${(Q)__idx_var}} + ${(P)+${(Q)__opts_var}} != 3 )); then + local __key_part=$RANDOM + ZUI[my_err_tfield_width_${__key_part}]=100 + ZUI[my_err_tfield_idx_${__key_part}]=1 + ZUI[my_err_tfield_data_${__key_part}]="ERROR: Not all variables exist: ${(Q)__width_var}, ${(Q)__idx_var}, ${(Q)__opts_var}" + __width_var="ZUI\[my_err_tfield_width_${__key_part}\]" + __idx_var="ZUI\[my_err_tfield_idx_${__key_part}\]" + __opts_var="ZUI\[my_err_tfield_data_${__key_part}\]" + fi - local __output=$'\034'"zuilbox$__id"$'\034'"$__data1"$'\034'"$__data2"$'\034'"$__data3"$'\034'"$__width_var"$'\034'"$__idx_var"$'\034'"$__opts_var"$'\02' + local __output=$'\034'"zuilbox$__id"$'\034'"$__data1"$'\034'"$__data2"$'\034'"$__data3"$'\034'"$__width_var"$'\034'"$__idx_var"$'\034'"$__opts_var"$'\02' - unset __id __width_var __idx_var __opts_var __data1 __data2 __data3 __handler - : ${(PA)__var_name::=$__output} + unset __id __width_var __idx_var __opts_var __data1 __data2 __data3 __handler + : ${(PA)__var_name::=$__output} } # }}} # FUNCTION: -zui_std_get_ganchor {{{ @@ -371,15 +361,15 @@ function -zui_std_list_box() { # $2 - instance index # $3 - visible text of the anchor # $4 - optional output array name -function -zui_std_get_ganchor() { - local __mod="$1" __ice="$2" __text="$3" __var_name="${4:-reply}" +-zui_std_get_ganchor() { + local __mod="$1" __ice="$2" __text="$3" __var_name="${4:-reply}" - # Quote only text, not codes - __text="${__text//(#b)([^$'\03'-$'\07'$'\013'-$'\014'$'\016'-$'\031'$'\037']##)/${(q)match[1]}}" + # Quote only text, not codes + __text="${__text//(#b)([^$'\03'-$'\07'$'\013'-$'\014'$'\016'-$'\031'$'\037']##)/${(q)match[1]}}" - __var_name="${__var_name}[${(P)#__var_name}+1]" - local __output=$'\01'"zuianchoraglobal_m${__mod}_i${__ice}"$'\01'""$'\01'""$'\01'""$'\01'""$'\02'"${__text}"$'\02' - : ${(PA)__var_name::=$__output} + __var_name="${__var_name}[${(P)#__var_name}+1]" + local __output=$'\01'"zuianchoraglobal_m${__mod}_i${__ice}"$'\01'""$'\01'""$'\01'""$'\01'""$'\02'"${__text}"$'\02' + : ${(PA)__var_name::=$__output} } # }}} # FUNCTION: -zui_std_decode_hyperlink {{{ @@ -395,27 +385,26 @@ function -zui_std_get_ganchor() { # $reply[3] - data2 # $reply[4] - data3 # $reply[5] - data4 -# -function -zui_std_decode_hyperlink() { - local __var_name="${2:-reply}" - : ${(PA)__var_name::=} - - if [[ "$1" = (#b)*$'\01'([^$'\01']#)$'\01'([^$'\01']#)$'\01'([^$'\01']#)$'\01'([^$'\01']#)$'\01'([^$'\02']#)$'\02'* ]]; then - local __id="${match[1]}" __data1="${match[2]}" __data2="${match[3]}" __data3="${match[4]}" __data4="${match[5]}" - local assgn_str="${__var_name}[1]" - : ${(P)assgn_str::=${(Q)__id}} - assgn_str="${__var_name}[2]" - : ${(P)assgn_str::=${(Q)__data1}} - assgn_str="${__var_name}[3]" - : ${(P)assgn_str::=${(Q)__data2}} - assgn_str="${__var_name}[4]" - : ${(P)assgn_str::=${(Q)__data3}} - assgn_str="${__var_name}[5]" - : ${(P)assgn_str::=${(Q)__data4}} - return 0 - fi +-zui_std_decode_hyperlink() { + local __var_name="${2:-reply}" + : ${(PA)__var_name::=} + + if [[ "$1" = (#b)*$'\01'([^$'\01']#)$'\01'([^$'\01']#)$'\01'([^$'\01']#)$'\01'([^$'\01']#)$'\01'([^$'\02']#)$'\02'* ]]; then + local __id="${match[1]}" __data1="${match[2]}" __data2="${match[3]}" __data3="${match[4]}" __data4="${match[5]}" + local assgn_str="${__var_name}[1]" + : ${(P)assgn_str::=${(Q)__id}} + assgn_str="${__var_name}[2]" + : ${(P)assgn_str::=${(Q)__data1}} + assgn_str="${__var_name}[3]" + : ${(P)assgn_str::=${(Q)__data2}} + assgn_str="${__var_name}[4]" + : ${(P)assgn_str::=${(Q)__data3}} + assgn_str="${__var_name}[5]" + : ${(P)assgn_str::=${(Q)__data4}} + return 0 + fi - return 1 + return 1 } # }}} # FUNCTION: -zui_std_decode_text_field {{{ @@ -433,32 +422,31 @@ function -zui_std_decode_hyperlink() { # $reply[5] - data1 # $reply[6] - data2 # $reply[7] - data3 -# -function -zui_std_decode_text_field() { - local __var_name="${2:-reply}" - : ${(PA)__var_name::=} - - # id [1] data1 [2] data2 [3] data3 [4] width_var [5] sidx_var [6] text_var [7] - if [[ "$1" = (#b)*$'\032'([^$'\032']#)$'\032'([^$'\032']#)$'\032'([^$'\032']#)$'\032'([^$'\032']#)$'\032'([^$'\032']#)$'\032'([^$'\032']#)$'\032'([^$'\02']#)$'\02'* ]]; then - local __id="${match[1]}" __data1="${match[2]}" __data2="${match[3]}" __data3="${match[4]}" __width_var="${match[5]}" __sidx_var="${match[6]}" __param="${match[7]}" - local assgn_str="${__var_name}[1]" - : ${(P)assgn_str::=${(Q)__id}} - assgn_str="${__var_name}[2]" - : ${(P)assgn_str::=${(Q)__width_var}} - assgn_str="${__var_name}[3]" - : ${(P)assgn_str::=${(Q)__sidx_var}} - assgn_str="${__var_name}[4]" - : ${(P)assgn_str::=${(Q)__param}} - assgn_str="${__var_name}[5]" - : ${(P)assgn_str::=${(Q)__data1}} - assgn_str="${__var_name}[6]" - : ${(P)assgn_str::=${(Q)__data2}} - assgn_str="${__var_name}[7]" - : ${(P)assgn_str::=${(Q)__data3}} - return 0 - fi +-zui_std_decode_text_field() { + local __var_name="${2:-reply}" + : ${(PA)__var_name::=} + + # id [1] data1 [2] data2 [3] data3 [4] width_var [5] sidx_var [6] text_var [7] + if [[ "$1" = (#b)*$'\032'([^$'\032']#)$'\032'([^$'\032']#)$'\032'([^$'\032']#)$'\032'([^$'\032']#)$'\032'([^$'\032']#)$'\032'([^$'\032']#)$'\032'([^$'\02']#)$'\02'* ]]; then + local __id="${match[1]}" __data1="${match[2]}" __data2="${match[3]}" __data3="${match[4]}" __width_var="${match[5]}" __sidx_var="${match[6]}" __param="${match[7]}" + local assgn_str="${__var_name}[1]" + : ${(P)assgn_str::=${(Q)__id}} + assgn_str="${__var_name}[2]" + : ${(P)assgn_str::=${(Q)__width_var}} + assgn_str="${__var_name}[3]" + : ${(P)assgn_str::=${(Q)__sidx_var}} + assgn_str="${__var_name}[4]" + : ${(P)assgn_str::=${(Q)__param}} + assgn_str="${__var_name}[5]" + : ${(P)assgn_str::=${(Q)__data1}} + assgn_str="${__var_name}[6]" + : ${(P)assgn_str::=${(Q)__data2}} + assgn_str="${__var_name}[7]" + : ${(P)assgn_str::=${(Q)__data3}} + return 0 + fi - return 1 + return 1 } # }}} # FUNCTION: -zui_std_decode_list_box {{{ @@ -476,32 +464,31 @@ function -zui_std_decode_text_field() { # $reply[5] - data1 # $reply[6] - data2 # $reply[7] - data3 -# -function -zui_std_decode_list_box() { - local __var_name="${2:-reply}" - : ${(PA)__var_name::=} - - # id [1] data1 [2] data2 [3] data3 [4] width_var [5] idx_var [6] text_var [7] - if [[ "$1" = (#b)*$'\034'([^$'\034']#)$'\034'([^$'\034']#)$'\034'([^$'\034']#)$'\034'([^$'\034']#)$'\034'([^$'\034']#)$'\034'([^$'\034']#)$'\034'([^$'\02']#)$'\02'* ]]; then - local __id="${match[1]}" __data1="${match[2]}" __data2="${match[3]}" __data3="${match[4]}" __width_var="${match[5]}" __idx_var="${match[6]}" __param="${match[7]}" - local assgn_str="${__var_name}[1]" - : ${(P)assgn_str::=${(Q)__id}} - assgn_str="${__var_name}[2]" - : ${(P)assgn_str::=${(Q)__width_var}} - assgn_str="${__var_name}[3]" - : ${(P)assgn_str::=${(Q)__idx_var}} - assgn_str="${__var_name}[4]" - : ${(P)assgn_str::=${(Q)__param}} - assgn_str="${__var_name}[5]" - : ${(P)assgn_str::=${(Q)__data1}} - assgn_str="${__var_name}[6]" - : ${(P)assgn_str::=${(Q)__data2}} - assgn_str="${__var_name}[7]" - : ${(P)assgn_str::=${(Q)__data3}} - return 0 - fi +-zui_std_decode_list_box() { + local __var_name="${2:-reply}" + : ${(PA)__var_name::=} + + # id [1] data1 [2] data2 [3] data3 [4] width_var [5] idx_var [6] text_var [7] + if [[ "$1" = (#b)*$'\034'([^$'\034']#)$'\034'([^$'\034']#)$'\034'([^$'\034']#)$'\034'([^$'\034']#)$'\034'([^$'\034']#)$'\034'([^$'\034']#)$'\034'([^$'\02']#)$'\02'* ]]; then + local __id="${match[1]}" __data1="${match[2]}" __data2="${match[3]}" __data3="${match[4]}" __width_var="${match[5]}" __idx_var="${match[6]}" __param="${match[7]}" + local assgn_str="${__var_name}[1]" + : ${(P)assgn_str::=${(Q)__id}} + assgn_str="${__var_name}[2]" + : ${(P)assgn_str::=${(Q)__width_var}} + assgn_str="${__var_name}[3]" + : ${(P)assgn_str::=${(Q)__idx_var}} + assgn_str="${__var_name}[4]" + : ${(P)assgn_str::=${(Q)__param}} + assgn_str="${__var_name}[5]" + : ${(P)assgn_str::=${(Q)__data1}} + assgn_str="${__var_name}[6]" + : ${(P)assgn_str::=${(Q)__data2}} + assgn_str="${__var_name}[7]" + : ${(P)assgn_str::=${(Q)__data3}} + return 0 + fi - return 1 + return 1 } # }}} # FUNCTION: -zui_std_decode {{{ @@ -512,14 +499,14 @@ function -zui_std_decode_list_box() { # $1 - hyperlink # $2 - output parameter name, for type (default: REPLY) # $3 - output array name, for hyperlink data (default: reply) -function -zui_std_decode() { - local __out="${2:-REPLY}" __var_name="${3:-reply}" - : ${(PA)__var_name::=} - [[ "$1" = *$'\01'* ]] && { -zui_std_decode_hyperlink "$1" "$__var_name" && { : ${(P)__out::=1}; return 0; }; } - [[ "$1" = *$'\032'* ]] && { -zui_std_decode_text_field "$1" "$__var_name" && { : ${(P)__out::=2}; return 0; }; } - [[ "$1" = *$'\034'* ]] && { -zui_std_decode_list_box "$1" "$__var_name" && { : ${(P)__out::=3}; return 0; }; } - : ${(P)__out::=0} - return 1 +-zui_std_decode() { + local __out="${2:-REPLY}" __var_name="${3:-reply}" + : ${(PA)__var_name::=} + [[ "$1" = *$'\01'* ]] && { -zui_std_decode_hyperlink "$1" "$__var_name" && { : ${(P)__out::=1}; return 0; }; } + [[ "$1" = *$'\032'* ]] && { -zui_std_decode_text_field "$1" "$__var_name" && { : ${(P)__out::=2}; return 0; }; } + [[ "$1" = *$'\034'* ]] && { -zui_std_decode_list_box "$1" "$__var_name" && { : ${(P)__out::=3}; return 0; }; } + : ${(P)__out::=0} + return 1 } # }}} # FUNCTION: -zui_std_get_stext {{{ @@ -529,68 +516,70 @@ function -zui_std_decode() { # # REPLY: decoded text contained in the special string # -function -zui_std_get_stext() { - local __var_name="${2:-REPLY}" +-zui_std_get_stext() { + local __var_name="${2:-REPLY}" - if [[ "$1" = (#b)(*)$'\01'$'\01'[^$'\01']#$'\01'[^$'\01']#$'\01'[^$'\01']#$'\01'[^$'\02']#$'\02'([^$'\02']#)$'\02'(*) ]]; then - # Repeat the wrapping text, too - : ${(P)__var_name::=${match[1]}${(Q)match[2]}${match[3]}} - return 0 - fi + if [[ "$1" = (#b)(*)$'\01'$'\01'[^$'\01']#$'\01'[^$'\01']#$'\01'[^$'\01']#$'\01'[^$'\02']#$'\02'([^$'\02']#)$'\02'(*) ]]; then + # Repeat the wrapping text, too + : ${(P)__var_name::=${match[1]}${(Q)match[2]}${match[3]}} + return 0 + fi - return 1 + return 1 } # }}} # FUNCTION: -zui_std_strip_meta_data {{{ -function -zui_std_strip_meta_data() { - local buf="$1" - # Remove hyperlinks - buf="${buf//(#b)$'\01'[^$'\01']#$'\01'[^$'\01']#$'\01'[^$'\01']#$'\01'[^$'\01']#$'\01'[^$'\02']#$'\02'([^$'\02']#)$'\02'/${(Q)match[1]}}" - # id data1 data2 data3 width sidx text - buf="${buf//(#b)$'\032'[^$'\032']#$'\032'[^$'\032']#$'\032'[^$'\032']#$'\032'[^$'\032']#$'\032'([^$'\032']#)$'\032'([^$'\032']#)$'\032'([^$'\02']#)$'\02'/${(mr:${(P)${(Q)match[1]}}::_:)${(P)${(Q)match[3]}}[${(P)${(Q)match[2]}},-1]}}" - # id data1 data2 data3 width idx options text - buf="${buf//(#b)$'\034'[^$'\034']#$'\034'[^$'\034']#$'\034'[^$'\034']#$'\034'[^$'\034']#$'\034'([^$'\034']#)$'\034'([^$'\034']#)$'\034'([^$'\02']#)$'\02'/${(mr:${(P)${(Q)match[1]}}:: :)${(As:;:)${(P)${(Q)match[3]}}}[${(P)${(Q)match[2]}}]}}" - - # Remove color marks - # [all] [fg] [bg] TEXT - buf="${buf//(#b)([$'\03'-$'\07'$'\013'-$'\014'$'\016'-$'\031'])([$'\03'-$'\07'$'\013'-$'\014'$'\016'-$'\017']|)([$'\020'-$'\030']|)([^${ZUI[FMT_END]}]#)${ZUI[FMT_END]}/$match[4]}" - - # Mark 1 - buf="${buf//(#b)${ZUI[MARK]}([^${ZUI[MARK_E]}]#)${ZUI[MARK_E]}/$match[1]}" - # Mark 2 (alternative for segments with background color) - buf="${buf//(#b)${ZUI[MARK2]}([^${ZUI[MARK_E]}]#)${ZUI[MARK_E]}/$match[1]}" - - REPLY="$buf" +-zui_std_strip_meta_data() { + local buf="$1" + # Remove hyperlinks + buf="${buf//(#b)$'\01'[^$'\01']#$'\01'[^$'\01']#$'\01'[^$'\01']#$'\01'[^$'\01']#$'\01'[^$'\02']#$'\02'([^$'\02']#)$'\02'/${(Q)match[1]}}" + # id data1 data2 data3 width sidx text + buf="${buf//(#b)$'\032'[^$'\032']#$'\032'[^$'\032']#$'\032'[^$'\032']#$'\032'[^$'\032']#$'\032'([^$'\032']#)$'\032'([^$'\032']#)$'\032'([^$'\02']#)$'\02'/${(mr:${(P)${(Q)match[1]}}::_:)${(P)${(Q)match[3]}}[${(P)${(Q)match[2]}},-1]}}" + # id data1 data2 data3 width idx options text + buf="${buf//(#b)$'\034'[^$'\034']#$'\034'[^$'\034']#$'\034'[^$'\034']#$'\034'[^$'\034']#$'\034'([^$'\034']#)$'\034'([^$'\034']#)$'\034'([^$'\02']#)$'\02'/${(mr:${(P)${(Q)match[1]}}:: :)${(As:;:)${(P)${(Q)match[3]}}}[${(P)${(Q)match[2]}}]}}" + + # Remove color marks + # [all] [fg] [bg] TEXT + buf="${buf//(#b)([$'\03'-$'\07'$'\013'-$'\014'$'\016'-$'\031'])([$'\03'-$'\07'$'\013'-$'\014'$'\016'-$'\017']|)([$'\020'-$'\030']|)([^${ZUI[FMT_END]}]#)${ZUI[FMT_END]}/$match[4]}" + + # Mark 1 + buf="${buf//(#b)${ZUI[MARK]}([^${ZUI[MARK_E]}]#)${ZUI[MARK_E]}/$match[1]}" + # Mark 2 (alternative for segments with background color) + buf="${buf//(#b)${ZUI[MARK2]}([^${ZUI[MARK_E]}]#)${ZUI[MARK_E]}/$match[1]}" + + REPLY="$buf" } # }}} + # FUNCTION: -zui_std_strip_color_codes {{{ -function -zui_std_strip_color_codes() { - # [all] [fg] [bg] TEXT - REPLY="${1//[$'\03'-$'\07'$'\013'-$'\014'$'\016'-$'\031'$'\037']/}" +-zui_std_strip_color_codes() { + # [all] [fg] [bg] TEXT + REPLY="${1//[$'\03'-$'\07'$'\013'-$'\014'$'\016'-$'\031'$'\037']/}" } # }}} + # FUNCTION: -zui_std_is_hyperlink {{{ # Checks if given text is a button/anchor/raw hyperlink -function -zui_std_is_hyperlink() { - [[ "$1" = *$'\01'[^$'\01']##$'\01'[^$'\01']#$'\01'[^$'\01']#$'\01'[^$'\01']#$'\01'[^$'\02']#$'\02'[^$'\02']#$'\02'* ]] +-zui_std_is_hyperlink() { + [[ "$1" = *$'\01'[^$'\01']##$'\01'[^$'\01']#$'\01'[^$'\01']#$'\01'[^$'\01']#$'\01'[^$'\02']#$'\02'[^$'\02']#$'\02'* ]] } # }}} # FUNCTION: -zui_std_is_special_text {{{ # Checks if given text is a button/anchor/raw hyperlink -function -zui_std_is_special_text() { - [[ "$1" = *$'\01'$'\01'[^$'\01']#$'\01'[^$'\01']#$'\01'[^$'\01']#$'\01'[^$'\02']#$'\02'[^$'\02']#$'\02'* ]] +-zui_std_is_special_text() { + [[ "$1" = *$'\01'$'\01'[^$'\01']#$'\01'[^$'\01']#$'\01'[^$'\01']#$'\01'[^$'\02']#$'\02'[^$'\02']#$'\02'* ]] } # }}} # FUNCTION: -zui_std_is_text_field {{{ # Checks if given text is a text field hyperlink -function -zui_std_is_text_field() { - # id data1 data2 data3 width_var sidx_var text_var - [[ "$1" = *$'\032'[^$'\032']#$'\032'[^$'\032']#$'\032'[^$'\032']#$'\032'[^$'\032']#$'\032'[^$'\032']#$'\032'[^$'\032']#$'\032'[^$'\02']#$'\02'* ]] +-zui_std_is_text_field() { + # id data1 data2 data3 width_var sidx_var text_var + [[ "$1" = *$'\032'[^$'\032']#$'\032'[^$'\032']#$'\032'[^$'\032']#$'\032'[^$'\032']#$'\032'[^$'\032']#$'\032'[^$'\032']#$'\032'[^$'\02']#$'\02'* ]] } # }}} # FUNCTION: -zui_std_is_list_box {{{ # Checks if given text is a list box hyperlink -function -zui_std_is_list_box() { - # id data1 data2 data3 width_var sidx_var text_var - [[ "$1" = *$'\034'[^$'\034']#$'\034'[^$'\034']#$'\034'[^$'\034']#$'\034'[^$'\034']#$'\034'[^$'\034']#$'\034'[^$'\034']#$'\034'[^$'\02']#$'\02'* ]] +-zui_std_is_list_box() { + # id data1 data2 data3 width_var sidx_var text_var + [[ "$1" = *$'\034'[^$'\034']#$'\034'[^$'\034']#$'\034'[^$'\034']#$'\034'[^$'\034']#$'\034'[^$'\034']#$'\034'[^$'\034']#$'\034'[^$'\02']#$'\02'* ]] } # }}} # FUNCTION: -zui_std_is_any_hyperlink {{{ @@ -600,24 +589,24 @@ function -zui_std_is_list_box() { # # $1 - hyperlink # $2 - output parameter name, for type (default: REPLY) -function -zui_std_is_any_hyperlink() { - local __out="${2:-REPLY}" - [[ "$1" = *$'\01'* ]] && { -zui_std_is_hyperlink "$1" && { : ${(P)__out::=1}; return 0; }; } - [[ "$1" = *$'\032'* ]] && { -zui_std_is_text_field "$1" && { : ${(P)__out::=2}; return 0; }; } - [[ "$1" = *$'\034'* ]] && { -zui_std_is_list_box "$1" && { : ${(P)__out::=3}; return 0; }; } - : ${(P)__out::=0} - return 1 +-zui_std_is_any_hyperlink() { + local __out="${2:-REPLY}" + [[ "$1" = *$'\01'* ]] && { -zui_std_is_hyperlink "$1" && { : ${(P)__out::=1}; return 0; }; } + [[ "$1" = *$'\032'* ]] && { -zui_std_is_text_field "$1" && { : ${(P)__out::=2}; return 0; }; } + [[ "$1" = *$'\034'* ]] && { -zui_std_is_list_box "$1" && { : ${(P)__out::=3}; return 0; }; } + : ${(P)__out::=0} + return 1 } # }}} # FUNCTION: -zui_std_has_any_hyperlinks {{{ # Checks if given text has any hyperlinks (buttons/anchors/raws, # text fields, list boxes) -function -zui_std_has_any_hyperlinks() { - [[ "$1" = *$'\01'[^$'\01']##$'\01'[^$'\01']#$'\01'[^$'\01']#$'\01'[^$'\01']#$'\01'[^$'\02']#$'\02'[^$'\02']#$'\02'* ]] || - # id data1 data2 module index width_var sidx_var text_var - [[ "$1" = *$'\032'[^$'\032']#$'\032'[^$'\032']#$'\032'[^$'\032']#$'\032'[^$'\032']#$'\032'[^$'\032']#$'\032'[^$'\032']#$'\032'[^$'\02']#$'\02'* ]] || - # id data1 data2 data3 width_var sidx_var text_var - [[ "$1" = *$'\034'[^$'\034']#$'\034'[^$'\034']#$'\034'[^$'\034']#$'\034'[^$'\034']#$'\034'[^$'\034']#$'\034'[^$'\034']#$'\034'[^$'\02']#$'\02'* ]] +-zui_std_has_any_hyperlinks() { + [[ "$1" = *$'\01'[^$'\01']##$'\01'[^$'\01']#$'\01'[^$'\01']#$'\01'[^$'\01']#$'\01'[^$'\02']#$'\02'[^$'\02']#$'\02'* ]] || + # id data1 data2 data3 width_var sidx_var text_var + [[ "$1" = *$'\032'[^$'\032']#$'\032'[^$'\032']#$'\032'[^$'\032']#$'\032'[^$'\032']#$'\032'[^$'\032']#$'\032'[^$'\032']#$'\032'[^$'\02']#$'\02'* ]] || + # id data1 data2 data3 width_var sidx_var text_var + [[ "$1" = *$'\034'[^$'\034']#$'\034'[^$'\034']#$'\034'[^$'\034']#$'\034'[^$'\034']#$'\034'[^$'\034']#$'\034'[^$'\034']#$'\034'[^$'\02']#$'\02'* ]] } # }}} # FUNCTION: -zui_std_pack_hyperlinks_into_box {{{ @@ -631,73 +620,72 @@ function -zui_std_has_any_hyperlinks() { # $3 - hyperlink 1 # $4 - hyperlink 2 # $5 - ... -# -function -zui_std_pack_hyperlinks_into_box() { - local width="$1" max_height="$2" - shift 2 - - reply=() - local hyp_link __text new_line="" tmp pad - integer idx max_idx="${#}" text_len diff_len now_width=0 now_height=0 - for (( idx=1; idx <= max_idx; idx ++ )); do - # The box is limited in height - (( now_height >= max_height )) && break - - hyp_link="${@[idx]}" - __text="${hyp_link/(#b)$'\01'*$'\02'([^$'\02']#)$'\02'/${match[1]}}" - text_len="${#__text}" - - # Will hyp_link fit into this line? - if [ "$now_width" != "0" ]; then - if (( now_width + text_len + 1 <= width )); then - now_width+=text_len+1 - new_line+=" $hyp_link" - else - # The line will be too long, pad it and store - # it into the box array without current link - # – leave the link for next loop run - pad="" - (( width-now_width > 0 )) && pad="${(r:width-now_width:: :)pad}" - # Store the line into the box array - reply+=( "${new_line}${pad}" ) - now_height+=1 - # Next line – empty - new_line="" - now_width=0 - # Repeat processing of current hyp_link - idx=idx-1 - fi - else - if (( text_len <= width )); then - now_width+=text_len - new_line+="$hyp_link" - else - # Special case: a hyper-link that does - # not fit even when it's alone in line - diff_len=$(( ${#__text} - (width-2) )) - hyp_link="${hyp_link[1,-diff_len-1]}" - # Store the truncated button into box array - reply+=( "${hyp_link}.." ) - now_height+=1 - # Next line – empty - new_line="" - now_width=0 - fi - fi - done - - # Line that wasn't filled and store wasn't triggered - if [[ -n "$new_line" && "$now_height" -lt "$max_height" ]]; then +-zui_std_pack_hyperlinks_into_box() { + local width="$1" max_height="$2" + shift 2 + + reply=() + local hyp_link __text new_line="" tmp pad + integer idx max_idx="${#}" text_len diff_len now_width=0 now_height=0 + for (( idx=1; idx <= max_idx; idx ++ )); do + # The box is limited in height + (( now_height >= max_height )) && break + + hyp_link="${@[idx]}" + __text="${hyp_link/(#b)$'\01'*$'\02'([^$'\02']#)$'\02'/${match[1]}}" + text_len="${#__text}" + + # Will hyp_link fit into this line? + if [ "$now_width" != "0" ]; then + if (( now_width + text_len + 1 <= width )); then + now_width+=text_len+1 + new_line+=" $hyp_link" + else + # The line will be too long, pad it and store + # it into the box array without current link + # – leave the link for next loop run pad="" (( width-now_width > 0 )) && pad="${(r:width-now_width:: :)pad}" # Store the line into the box array reply+=( "${new_line}${pad}" ) + now_height+=1 + # Next line – empty + new_line="" + now_width=0 + # Repeat processing of current hyp_link + idx=idx-1 + fi + else + if (( text_len <= width )); then + now_width+=text_len + new_line+="$hyp_link" + else + # Special case: a hyper-link that does + # not fit even when it's alone in line + diff_len=$(( ${#__text} - (width-2) )) + hyp_link="${hyp_link[1,-diff_len-1]}" + # Store the truncated button into box array + reply+=( "${hyp_link}.." ) + now_height+=1 + # Next line – empty + new_line="" + now_width=0 + fi fi - - #local tmp - #for tmp in "${reply[@]}"; do - # echo "| $tmp |" >> /tmp/reply - #done + done + + # Line that wasn't filled and store wasn't triggered + if [[ -n "$new_line" && "$now_height" -lt "$max_height" ]]; then + pad="" + (( width-now_width > 0 )) && pad="${(r:width-now_width:: :)pad}" + # Store the line into the box array + reply+=( "${new_line}${pad}" ) + fi + + #local tmp + #for tmp in "${reply[@]}"; do + # echo "| $tmp |" >> /tmp/reply + #done } # }}} # FUNCTION: -zui_std_load_config {{{ @@ -719,47 +707,47 @@ function -zui_std_pack_hyperlinks_into_box() { # $2 - default value, 0 or 1 for bools # $3 - time limit # $4 - output parameter to fill (name) -function -zui_std_load_config() { - local __ts=${EPOCHSECONDS:-0} - - local __bool="${${${1##b:*}:+0}:-1}" __default="$2" __cvar="${${1#b:}#s:}" __time_limit="${3:-2}" __var_name="${4:-REPLY}" - local __key __value - local -a match mbegin mend - - # Check if current ZUI[...] is fresh - if [[ "$__var_name" = (#b)ZUI\[(*)\] ]]; then - __key="${match[1]}_ts_" - # *_ts_ key in ZUI is older than __time_limit? - if [[ $(( __ts - __time_limit )) -gt "${ZUI[$__key]:-0}" || "$__ts" -eq 0 ]]; then - ZUI[$__key]=$__ts - else - return 0 - fi +-zui_std_load_config() { + local __ts=${EPOCHSECONDS:-0} + + local __bool="${${${1##b:*}:+0}:-1}" __default="$2" __cvar="${${1#b:}#s:}" __time_limit="${3:-2}" __var_name="${4:-REPLY}" + local __key __value + local -a match mbegin mend + + # Check if current ZUI[...] is fresh + if [[ "$__var_name" = (#b)ZUI\[(*)\] ]]; then + __key="${match[1]}_ts_" + # *_ts_ key in ZUI is older than __time_limit? + if [[ $(( __ts - __time_limit )) -gt "${ZUI[$__key]:-0}" || "$__ts" -eq 0 ]]; then + ZUI[$__key]=$__ts + else + return 0 fi + fi - # Global ZUI settings + # Global ZUI settings + if (( __bool )); then + if (( __default )); then + zstyle -T ":plugin:zui" "$__cvar" && : ${(P)__var_name::=1} || : ${(P)__var_name::=0} + else + zstyle -t ":plugin:zui" "$__cvar" && : ${(P)__var_name::=1} || : ${(P)__var_name::=0} + fi + else + zstyle -s ":plugin:zui" "$__cvar" __value || __value="$__default" + : ${(P)__var_name::=$__value} + fi + + # Application - specific settings + [[ -n "${ZUI[app]}" ]] && { + local __zstyle_path=":plugin:zui:app:${ZUI[app]}" if (( __bool )); then - if (( __default )); then - zstyle -T ":plugin:zui" "$__cvar" && : ${(P)__var_name::=1} || : ${(P)__var_name::=0} - else - zstyle -t ":plugin:zui" "$__cvar" && : ${(P)__var_name::=1} || : ${(P)__var_name::=0} - fi + zstyle -t $__zstyle_path "$__cvar" && : ${(P)__var_name::=1} || zstyle -T $__zstyle_path "$__cvar" || : ${(P)__var_name::=0} else - zstyle -s ":plugin:zui" "$__cvar" __value || __value="$__default" - : ${(P)__var_name::=$__value} + zstyle -s $__zstyle_path "$__cvar" __value && : ${(P)__var_name::=$__value} fi + } - # Application - specific settings - [[ -n "${ZUI[app]}" ]] && { - local __zstyle_path=":plugin:zui:app:${ZUI[app]}" - if (( __bool )); then - zstyle -t $__zstyle_path "$__cvar" && : ${(P)__var_name::=1} || zstyle -T $__zstyle_path "$__cvar" || : ${(P)__var_name::=0} - else - zstyle -s $__zstyle_path "$__cvar" __value && : ${(P)__var_name::=$__value} - fi - } - - return 0 + return 0 } # }}} # FUNCTION: -zui_std_refresh_configs {{{ @@ -771,13 +759,13 @@ function -zui_std_load_config() { # # $1, $2 ... – keys in ZUI to update, config # variables' names -function -zui_std_refresh_configs() { - local ts=${EPOCHSECONDS:-0} config - (( ts == 0 )) && ts=$( date +%s ) +-zui_std_refresh_configs() { + local ts=${EPOCHSECONDS:-0} config + (( ts == 0 )) && ts=$( date +%s ) - for config in "$@"; do - (( ${+ZUI[$config]} )) && ZUI[${config}_ts_]=$ts - done + for config in "$@"; do + (( ${+ZUI[$config]} )) && ZUI[${config}_ts_]=$ts + done } # }}} # FUNCTION: -zui_std_store_default_app_config {{{ @@ -792,125 +780,125 @@ function -zui_std_refresh_configs() { # $2 - value to write, 0 or 1 for bools # # Returns 0 if written, 1 if Zstyle was already set -function -zui_std_store_default_app_config() { - local cvar="${${1#b:}#s:}" value="$2" bool="${${${1##b:*}:+0}:-1}" - local zstyle_path=":plugin:zui:app:${ZUI[app]}" tmp - integer isset - - # Establish if already set - if (( bool )); then - # Lets keep this as a fine piece of logic - if zstyle -t "$zstyle_path" "$cvar"; then - isset=1 - else - zstyle -T "$zstyle_path" "$cvar" && isset=0 || isset=1 - fi +-zui_std_store_default_app_config() { + local cvar="${${1#b:}#s:}" value="$2" bool="${${${1##b:*}:+0}:-1}" + local zstyle_path=":plugin:zui:app:${ZUI[app]}" tmp + integer isset + + # Establish if already set + if (( bool )); then + # Lets keep this as a fine piece of logic + if zstyle -t "$zstyle_path" "$cvar"; then + isset=1 else - zstyle -s "$zstyle_path" "$cvar" tmp && isset=1 || isset=0 + zstyle -T "$zstyle_path" "$cvar" && isset=0 || isset=1 fi + else + zstyle -s "$zstyle_path" "$cvar" tmp && isset=1 || isset=0 + fi - # Store if not set - if (( isset == 0 )); then - zstyle "$zstyle_path" "$cvar" "$value" - return 0 - else - return 1 - fi + # Store if not set + if (( isset == 0 )); then + zstyle "$zstyle_path" "$cvar" "$value" + return 0 + else + return 1 + fi } # }}} # FUNCTION: -zui_std_cleanup {{{ # This function clears application data # from $ZUI global hash. To be called at # exit and at start of zui application -function -zui_std_cleanup() { - # Optimization to not recreate windows on list - # restart - but yes here, on app restart - (( ${+builtins[zcurses]} )) && { - if [[ -n "${zcurses_windows[(r)main]}" || -n "${zcurses_windows[(r)status]}" ]]; then - zcurses delwin main 2>/dev/null - zcurses delwin status 2>/dev/null - zcurses end - fi - } - - local -a keys - # Anchors, checkboxes, actions, internal actions - keys=( ${ZUI[(I)zuianchor*]} ${ZUI[(I)zuieanchor*]} ${ZUI[(I)zuitfield*]} ${ZUI[(I)zuilbox*]} - ${ZUI[(I)zuiaction*]} ${ZUI[(I)zuiiaction*]} ${ZUI[(I)fly_*]} - app app_name PROMPT_SUBST INTERACTIVE_COMMENTS GENERATION_TIME - - # zui-list state fields - CURRENT_IDX FROM_WHAT_IDX_LIST_IS_SHOWN CURRENT_SEGMENT SEARCH_MODE SEARCH_BUFFER UNIQ_MODE TEXT_OFFSET PREV_SBUFFER PREV_SIDX - # zui-list working & configuration fields - REGENERATE_LIST IGNORE_MSG COLORING_PATTERN COLORING_COLOR COLORING_MATCH_MULTIPLE - - # Configuration keys - text_mode text_mode_ts_ - colorpair colorpair_ts_ - border border_ts_ - border_cp border_cp_ts_ - bold bold_ts_ - status_colorpair status_colorpair_ts_ - status_border status_border_ts_ - status_border_cp status_border_cp_ts_ - status_bold status_bold_ts_ - status_size status_size_ts_ - mark mark_ts_ - altmark altmark_ts_ - mark2 mark2_ts_ - altmark2 altmark2_ts_ - select_mode select_mode_ts_ - text_mode text_mode_ts_ - text_select text_select_ts_ - status_pointer status_pointer_ts_ - log_append log_append_ts_ - log_index log_index_ts_ - log_size log_size_ts_ - log_time_format log_time_format_ts_ - log_colors log_colors_ts_ - ) - - [[ -n "${ZUI[app]}" ]] && ZUI[previous_app]="${ZUI[app]}" - - # Serialize? - if [[ "$1" = serialize* ]]; then - local dst="${${1#serialize}#:}" - -zui_std_serialize "${dst:-${ZUI[app]}}" - fi - - local k - for k in "${keys[@]}" ${ZUI[(I)my_*]}; do - unset "ZUI[$k]" - done - - (( ${+functions[-zui-standard-global-anchors-callback]} )) && unfunction -- -zui-standard-global-anchors-callback - (( ${+functions[-zui-standard-status-callback]} )) && unfunction -- -zui-standard-status-callback - (( ${+functions[-zui-standard-text-select-callback]} )) && unfunction -- -zui-standard-text-select-callback - (( ${+functions[-zui-standard-timeout-callback]} )) && unfunction -- -zui-standard-timeout-callback - - # Deserialize? - if [[ "$1" = deserialize* ]]; then - local src="${${1#deserialize}#:}" - -zui_std_deserialize "${src:-${ZUI[app]}}" +-zui_std_cleanup() { + # Optimization to not recreate windows on list + # restart - but yes here, on app restart + (( ${+builtins[zcurses]} )) && { + if [[ -n "${zcurses_windows[(r)main]}" || -n "${zcurses_windows[(r)status]}" ]]; then + zcurses delwin main 2>/dev/null + zcurses delwin status 2>/dev/null + zcurses end fi + } + + local -a keys + # Anchors, checkboxes, actions, internal actions + keys=( ${ZUI[(I)zuianchor*]} ${ZUI[(I)zuieanchor*]} ${ZUI[(I)zuitfield*]} ${ZUI[(I)zuilbox*]} + ${ZUI[(I)zuiaction*]} ${ZUI[(I)zuiiaction*]} ${ZUI[(I)fly_*]} + app app_name PROMPT_SUBST INTERACTIVE_COMMENTS GENERATION_TIME + + # zui-list state fields + CURRENT_IDX FROM_WHAT_IDX_LIST_IS_SHOWN CURRENT_SEGMENT SEARCH_MODE SEARCH_BUFFER UNIQ_MODE TEXT_OFFSET PREV_SBUFFER PREV_SIDX + # zui-list working & configuration fields + REGENERATE_LIST IGNORE_MSG COLORING_PATTERN COLORING_COLOR COLORING_MATCH_MULTIPLE + + # Configuration keys + text_mode text_mode_ts_ + colorpair colorpair_ts_ + border border_ts_ + border_cp border_cp_ts_ + bold bold_ts_ + status_colorpair status_colorpair_ts_ + status_border status_border_ts_ + status_border_cp status_border_cp_ts_ + status_bold status_bold_ts_ + status_size status_size_ts_ + mark mark_ts_ + altmark altmark_ts_ + mark2 mark2_ts_ + altmark2 altmark2_ts_ + select_mode select_mode_ts_ + text_mode text_mode_ts_ + text_select text_select_ts_ + status_pointer status_pointer_ts_ + log_append log_append_ts_ + log_index log_index_ts_ + log_size log_size_ts_ + log_time_format log_time_format_ts_ + log_colors log_colors_ts_ + ) + + [[ -n "${ZUI[app]}" ]] && ZUI[previous_app]="${ZUI[app]}" + + # Serialize? + if [[ "$1" = serialize* ]]; then + local dst="${${1#serialize}#:}" + -zui_std_serialize "${dst:-${ZUI[app]}}" + fi + + local k + for k in "${keys[@]}" ${ZUI[(I)my_*]}; do + unset "ZUI[$k]" + done + + (( ${+functions[-zui-standard-global-anchors-callback]} )) && unfunction -- -zui-standard-global-anchors-callback + (( ${+functions[-zui-standard-status-callback]} )) && unfunction -- -zui-standard-status-callback + (( ${+functions[-zui-standard-text-select-callback]} )) && unfunction -- -zui-standard-text-select-callback + (( ${+functions[-zui-standard-timeout-callback]} )) && unfunction -- -zui-standard-timeout-callback + + # Deserialize? + if [[ "$1" = deserialize* ]]; then + local src="${${1#deserialize}#:}" + -zui_std_deserialize "${src:-${ZUI[app]}}" + fi } # }}} # FUNCTION: -zui_std_serialize {{{ # Stores my_* keys of ZUI hash into # "serialized_${ZUI[app]}" key, which # can be read with *deserialize() call -function -zui_std_serialize() { - local dst="${1:-${ZUI[app]}}" +-zui_std_serialize() { + local dst="${1:-${ZUI[app]}}" - local -a skeys - skeys=( ${ZUI[(I)my_*]} CURRENT_IDX FROM_WHAT_IDX_LIST_IS_SHOWN CURRENT_SEGMENT SEARCH_MODE SEARCH_BUFFER UNIQ_MODE TEXT_OFFSET PREV_SBUFFER PREV_SIDX ) + local -a skeys + skeys=( ${ZUI[(I)my_*]} CURRENT_IDX FROM_WHAT_IDX_LIST_IS_SHOWN CURRENT_SEGMENT SEARCH_MODE SEARCH_BUFFER UNIQ_MODE TEXT_OFFSET PREV_SBUFFER PREV_SIDX ) - local k out - for k in "${skeys[@]}"; do - (( ${+ZUI[$k]} )) && out+="${(q)k} ${(q)ZUI[$k]} " - done + local k out + for k in "${skeys[@]}"; do + (( ${+ZUI[$k]} )) && out+="${(q)k} ${(q)ZUI[$k]} " + done - ZUI[serialized_$dst]="${out% }" + ZUI[serialized_$dst]="${out% }" } # }}} # FUNCTION: -zui_std_deserialize {{{ @@ -918,16 +906,16 @@ function -zui_std_serialize() { # the content onto ZUI keys, normally my_* # keys. Use this to restore application state # after exit and consecutive start. -function -zui_std_deserialize() { - local src="${1:-${ZUI[app]}}" +-zui_std_deserialize() { + local src="${1:-${ZUI[app]}}" - local -a data - data=( "${(Q@)${(z@)ZUI[serialized_$src]}}" ) + local -a data + data=( "${(Q@)${(z@)ZUI[serialized_$src]}}" ) - if (( ${#data} % 2 == 0 && ${#data} > 0 )); then - ZUI+=( "${data[@]}" ) - unset "ZUI[serialized_$src]" - fi + if (( ${#data} % 2 == 0 && ${#data} > 0 )); then + ZUI+=( "${data[@]}" ) + unset "ZUI[serialized_$src]" + fi } # }}} # FUNCTION: -zui_std_set_mod_factor {{{ @@ -937,9 +925,9 @@ function -zui_std_deserialize() { # # $1 - module index # $2 - new factor -function -zui_std_set_mod_factor() { - local key="${zuiel_module_hash[(i)${1}_*]}" - zuiel_module_hash[$key]="$2" +-zui_std_set_mod_factor() { + local key="${zuiel_module_hash[(i)${1}_*]}" + zuiel_module_hash[$key]="$2" } # }}} # FUNCTION: -zui_std_get_mod_factor {{{ @@ -948,9 +936,9 @@ function -zui_std_set_mod_factor() { # # $1 - module index # $2 - output parameter name (default: REPLY) -function -zui_std_get_mod_factor() { - local __var_name="${2:-REPLY}" __key="${zuiel_module_hash[(i)${1}_*]}" - : ${(P)__var_name::=${zuiel_module_hash[$__key]}} +-zui_std_get_mod_factor() { + local __var_name="${2:-REPLY}" __key="${zuiel_module_hash[(i)${1}_*]}" + : ${(P)__var_name::=${zuiel_module_hash[$__key]}} } # }}} # FUNCTION: -zui_std_set_mod_spacing {{{ @@ -967,10 +955,9 @@ function -zui_std_get_mod_factor() { # $1 - module index # $2 - instance index # $3 - the spacing to set (i.e. number of blank lines) -function -zui_std_set_mod_spacing() { - ZUI[SPACING_${1}_${2}]="$3" -} -# }}} +-zui_std_set_mod_spacing() { + ZUI[SPACING_${1}_${2}]="$3" +} # }}} # FUNCTION: -zui_std_get_mod_spacing {{{ # Gets module's spacing, either from the transport place @@ -984,21 +971,20 @@ function -zui_std_set_mod_spacing() { # $1 - module index # $2 - instance index # $3 - "tra" or "dst" - transport or destination -function -zui_std_get_mod_spacing() { - REPLY=1 +-zui_std_get_mod_spacing() { + REPLY=1 - if [[ "$3" = "tra" ]]; then - [[ "${+ZUI[SPACING_${1}_${2}]}" = "0" ]] && return 1 - REPLY="${ZUI[SPACING_${1}_${2}]}" - return 0 - fi - - local __var_name="mod${1}_ice${2}_spacing" - [[ "${(P)+__var_name}" = "0" ]] && return 1 - REPLY="${(P)var_name}" + if [[ "$3" = "tra" ]]; then + [[ "${+ZUI[SPACING_${1}_${2}]}" = "0" ]] && return 1 + REPLY="${ZUI[SPACING_${1}_${2}]}" return 0 -} -# }}} + fi + + local __var_name="mod${1}_ice${2}_spacing" + [[ "${(P)+__var_name}" = "0" ]] && return 1 + REPLY="${(P)var_name}" + return 0 +} # }}} # FUNCTION: -zui_std_load_global_index_and_size {{{ # Use this to quickly load variables: @@ -1017,31 +1003,31 @@ function -zui_std_get_mod_spacing() { # $2 - instance index # $3 - output parameter name for global index # $4 - output parameter name for size -function -zui_std_load_global_index_and_size() { - local tmp var_name - 3=${2:-REPLY} - 4=${3:-REPLY2} +-zui_std_load_global_index_and_size() { + local tmp var_name + 3=${2:-REPLY} + 4=${3:-REPLY2} - var_name="mod${1}_ice${2}_global_index" - [[ "${(P)+var_name}" = "0" ]] && return 1 + var_name="mod${1}_ice${2}_global_index" + [[ "${(P)+var_name}" = "0" ]] && return 1 - # Global index - tmp="${(P)var_name}" - : ${(P)3::=$tmp} + # Global index + tmp="${(P)var_name}" + : ${(P)3::=$tmp} - # Size - var_name="mod${1}_ice${2}_size" - tmp="${(P)var_name}" - : ${(P)4::=$tmp} + # Size + var_name="mod${1}_ice${2}_size" + tmp="${(P)var_name}" + : ${(P)4::=$tmp} - return 0 + return 0 } # }}} # FUNCTION: -zui_std_reset_replies {{{ # Resets parameters reply{,2..5}, i.e. sets them # to empty arrays or strings -function -zui_std_reset_replies() { - reply=() reply2=() reply3=() reply4=() reply5="" +-zui_std_reset_replies() { + reply=() reply2=() reply3=() reply4=() reply5="" } # }}} # FUNCTION: -zui_std_map_replies {{{ @@ -1053,20 +1039,20 @@ function -zui_std_reset_replies() { # # $1 - module index # $2 - instance index -function -zui_std_map_replies() { - local var_name - var_name="mod${1}_ice${2}_output" - : ${(PA)var_name::="${reply[@]}"} - var_name="mod${1}_ice${2}_size" - : ${(P)var_name::=${#reply}} - var_name="mod${1}_ice${2}_nonselectables" - : ${(PA)var_name::="${reply2[@]}"} - var_name="mod${1}_ice${2}_hops" - : ${(PA)var_name::="${reply3[@]}"} - var_name="mod${1}_ice${2}_lanchors" - : ${(PA)var_name::="${reply4[@]}"} - var_name="mod${1}_ice${2}_spacing" - : ${(PA)var_name::=$reply5} +-zui_std_map_replies() { + local var_name + var_name="mod${1}_ice${2}_output" + : ${(PA)var_name::="${reply[@]}"} + var_name="mod${1}_ice${2}_size" + : ${(P)var_name::=${#reply}} + var_name="mod${1}_ice${2}_nonselectables" + : ${(PA)var_name::="${reply2[@]}"} + var_name="mod${1}_ice${2}_hops" + : ${(PA)var_name::="${reply3[@]}"} + var_name="mod${1}_ice${2}_lanchors" + : ${(PA)var_name::="${reply4[@]}"} + var_name="mod${1}_ice${2}_spacing" + : ${(PA)var_name::=$reply5} } # }}} # FUNCTION: -zui_std_fly_mod_regen_ext {{{ @@ -1076,38 +1062,37 @@ function -zui_std_map_replies() { # $1 - name of generator function # $2 - module's index # $3 - instance index -# $4, $5, ... - additional arguments for -# the generator +# $4, $5, ... - additional arguments for the generator -zui_std_fly_mod_regen_ext() { - local generator="$1" mod="$2" ice="$3" + local generator="$1" mod="$2" ice="$3" - shift 3 + shift 3 - -zui_std_reset_replies + -zui_std_reset_replies - "$generator" "$mod" "$ice" "$@" + "$generator" "$mod" "$ice" "$@" - # Setting the following will also pass the new - # content to regeneration-path. I.e. you can - # do restart-update (not on-the-fly update) and - # module "$module" will still have data from - # this *_regenerate call. Note that the data - # will be overwritten if restart-update will - # regenerate "$module". - -zui_std_map_replies "$mod" "$ice" + # Setting the following will also pass the new + # content to regeneration-path. I.e. you can + # do restart-update (not on-the-fly update) and + # module "$module" will still have data from + # this *_regenerate call. Note that the data + # will be overwritten if restart-update will + # regenerate "$module". + -zui_std_map_replies "$mod" "$ice" - # No typical saving of any newly created local - # anchors. There is no regeneration loop (i.e. - # it is on-the-fly update) and placing anchors - # is handled in zui-list. - # -zui_std_gather_lanchors regen_lanchors + # No typical saving of any newly created local + # anchors. There is no regeneration loop (i.e. + # it is on-the-fly update) and placing anchors + # is handled in zui-list. + # -zui_std_gather_lanchors regen_lanchors - # Submit on-the-fly list update. The same data - # as in -zui_std_map_replies. - -zui_std_submit_fly_from_gen_replies "$mod" "$ice" + # Submit on-the-fly list update. The same data + # as in -zui_std_map_replies. + -zui_std_submit_fly_from_gen_replies "$mod" "$ice" - # No output from this function - -zui_std_reset_replies + # No output from this function + -zui_std_reset_replies } # }}} # FUNCTION: -zui_std_fly_mod_regen {{{ @@ -1116,21 +1101,20 @@ function -zui_std_map_replies() { # # $1 - module's index # $2 - instance index -# $3, $4, ... - additional arguments for -# the generator +# $3, $4, ... - additional arguments for the generator -zui_std_fly_mod_regen() { - local mod="$1" ice="$2" key="${zuiel_module_hash[(i)${1}_*]}" - local generator="${key#[[:digit:]]#_}" + local mod="$1" ice="$2" key="${zuiel_module_hash[(i)${1}_*]}" + local generator="${key#[[:digit:]]#_}" - shift 2 + shift 2 - [[ -z "$generator" ]] && return + [[ -z "$generator" ]] && return - -zui_std_reset_replies - "$generator" "$mod" "$ice" "$@" - -zui_std_map_replies "$mod" "$ice" - -zui_std_submit_fly_from_gen_replies "$mod" "$ice" - -zui_std_reset_replies + -zui_std_reset_replies + "$generator" "$mod" "$ice" "$@" + -zui_std_map_replies "$mod" "$ice" + -zui_std_submit_fly_from_gen_replies "$mod" "$ice" + -zui_std_reset_replies } # }}} # FUNCTION: -zui_std_fly_array_refresh {{{ @@ -1144,22 +1128,22 @@ function -zui_std_map_replies() { # # $1 - module's index -zui_std_fly_array_refresh() { - local __mod="$1" __ice="1" __key="${zuiel_module_hash[(i)${1}_*]}" - - local __arr="${zuiel_module_hash[$__key]}" - if [[ "$__arr" = u-* ]]; then - __arr="${__arr#u-}" - reply=( "${(PA@u)__arr}" ) - else - reply=( "${(PA@)__arr}" ) - fi - - reply2=( ) reply3=( 1 ) reply4=( ) - -zui_std_map_replies "$__mod" "$__ice" - -zui_std_submit_fly_from_gen_replies "$__mod" "$__ice" - - # No output from this function - -zui_std_reset_replies + local __mod="$1" __ice="1" __key="${zuiel_module_hash[(i)${1}_*]}" + + local __arr="${zuiel_module_hash[$__key]}" + if [[ "$__arr" = u-* ]]; then + __arr="${__arr#u-}" + reply=( "${(PA@u)__arr}" ) + else + reply=( "${(PA@)__arr}" ) + fi + + reply2=( ) reply3=( 1 ) reply4=( ) + -zui_std_map_replies "$__mod" "$__ice" + -zui_std_submit_fly_from_gen_replies "$__mod" "$__ice" + + # No output from this function + -zui_std_reset_replies } # }}} # FUNCTION: -zui_std_submit_fly_from_gen_replies {{{ @@ -1178,24 +1162,24 @@ function -zui_std_map_replies() { # # $1 - module index # $2 - instance index -function -zui_std_submit_fly_from_gen_replies() { - local mod="$1" ice="$2" global_index previous_size var_name - - # Get global index and previous size. We reach for - # prev_mod${mod}_ice${ice}_size parameter because here - # we submit what means outside code that ran generator - # also probably mapped new replies to non-prev parameters - var_name="mod${mod}_ice${ice}_global_index" - global_index="${(P)var_name}" - var_name="prev_mod${mod}_ice${ice}_size" - previous_size="${(P)var_name}" - - # Not submitting module output, it is assumed - # that -zui_std_map_replies was called - -zui_std_submit_list_update "$mod" "$ice" "$global_index" "$(( global_index + previous_size - 1 ))" # "${reply[@]}" - -zui_std_submit_nonselectables "${reply2[@]}" - -zui_std_submit_hops "${reply3[@]}" - -zui_std_submit_lanchors "${reply4[@]}" +-zui_std_submit_fly_from_gen_replies() { + local mod="$1" ice="$2" global_index previous_size var_name + + # Get global index and previous size. We reach for + # prev_mod${mod}_ice${ice}_size parameter because here + # we submit what means outside code that ran generator + # also probably mapped new replies to non-prev parameters + var_name="mod${mod}_ice${ice}_global_index" + global_index="${(P)var_name}" + var_name="prev_mod${mod}_ice${ice}_size" + previous_size="${(P)var_name}" + + # Not submitting module output, it is assumed + # that -zui_std_map_replies was called + -zui_std_submit_list_update "$mod" "$ice" "$global_index" "$(( global_index + previous_size - 1 ))" # "${reply[@]}" + -zui_std_submit_nonselectables "${reply2[@]}" + -zui_std_submit_hops "${reply3[@]}" + -zui_std_submit_lanchors "${reply4[@]}" } # }}} # FUNCTION: -zui_std_submit_list_update {{{ @@ -1207,10 +1191,10 @@ function -zui_std_submit_fly_from_gen_replies() { # $3 - beginning line number of area to replace # $4 - end line number of area to replace # $5, $6, ... - new elements to replace lines $1..$2 -function -zui_std_submit_list_update() { - integer size=$(( $4 - $3 + 1 )) - 4=$size - ZUI[fly_update]="${(j: :)${(q)@}}" +-zui_std_submit_list_update() { + integer size=$(( $4 - $3 + 1 )) + 4=$size + ZUI[fly_update]="${(j: :)${(q)@}}" } # }}} # FUNCTION: -zui_std_submit_hops {{{ @@ -1221,8 +1205,8 @@ function -zui_std_submit_list_update() { # # $1, $2, ... - local indices of hops in the # substituted fragment -function -zui_std_submit_hops() { - ZUI[fly_hops]="${(j: :)${(q)@}}" +-zui_std_submit_hops() { + ZUI[fly_hops]="${(j: :)${(q)@}}" } # }}} # FUNCTION: -zui_std_submit_nonselectables {{{ @@ -1233,8 +1217,8 @@ function -zui_std_submit_hops() { # # $1, $2, ... - local indices of nonselectables # in the substituted fragment -function -zui_std_submit_nonselectables() { - ZUI[fly_nonselectables]="${(j: :)${(q)@}}" +-zui_std_submit_nonselectables() { + ZUI[fly_nonselectables]="${(j: :)${(q)@}}" } # }}} # FUNCTION: -zui_std_submit_lanchors {{{ @@ -1244,11 +1228,11 @@ function -zui_std_submit_nonselectables() { # in $ZUI) will be globalized. # # $1, $2, ... - IDs of anchors to be globalized -function -zui_std_submit_lanchors() { - ZUI[fly_lanchors]="${(j: :)${(q)@}}" +-zui_std_submit_lanchors() { + ZUI[fly_lanchors]="${(j: :)${(q)@}}" } # }}} # FUNCTION: -zui_std_stalog {{{ -function -zui_std_stalog() { - -zui_sys_add_message 1 ${EPOCHSECONDS:-0} "$@" +-zui_std_stalog() { + -zui_sys_add_message 1 ${EPOCHSECONDS:-0} "$@" } # }}} diff --git a/lib/syslib.lzui b/lib/syslib.lzui index 5734b73..d0e5847 100644 --- a/lib/syslib.lzui +++ b/lib/syslib.lzui @@ -1,7 +1,3 @@ -# ============================================================================ # -# [ https://github.com/z-shell ] ❮ ZI ❯ [ (c) 2022 Z-SHELL COMMUNITY ] # -# ============================================================================ # -# # -*- mode: zsh; sh-indentation: 2; indent-tabs-mode: nil; sh-basic-offset: 2; -*- # vim: ft=zsh sw=2 ts=2 et # @@ -26,84 +22,84 @@ ZUI[syslib_sourced]="1" # $2 - output parameter name - cursor end index # $3 - current $list (zui-list working variable) element # $4, ..., $11 - decoded __text field -function -zui_sys_get_tfield_cursor_boundaries() { - local __out1="$1" __out2="$2" __elem="$3" __id="$4" - local -a __output - - zui-process-buffer "$__elem" - - integer __i __size="${#ZUI_PB_WORDS}" __idx=0 - local __seg __text REPLY - - for (( __i=1; __i <= __size; __i ++ )); do - __idx+="${#ZUI_PB_SPACES[__i]}" - __seg="${ZUI_PB_WORDS[__i]}" - if -zui_std_is_hyperlink "$__seg"; then - __text="${__seg//(#b)$'\01'[^$'\01']#$'\01'[^$'\01']#$'\01'[^$'\01']#$'\01'[^$'\01']#$'\01'[^$'\02']#$'\02'([^$'\02']#)$'\02'/${(Q)match[1]}}" - -zui_util_strip_codes "$__text" - __idx+="${(m)#REPLY}" - elif -zui_std_decode_text_field "$__seg" __output; then - if [[ "$__id" = "${__output[1]}" ]]; then - # Add characters that precede - if [[ "$__seg" = (#b)(*)$'\032'[^$'\032']#$'\032'[^$'\032']#$'\032'[^$'\032']#$'\032'[^$'\032']#$'\032'[^$'\032']#$'\032'[^$'\032']#$'\032'[^$'\02']#$'\02'* ]]; then - __idx+=${(m)#match[1]} - fi - # Minimum x position - : ${(P)__out1::=$__idx} - - __text="${(P)__output[4]}" - __text="${__text[${(P)__output[3]},-1]}" - __text="${__text[1,${(P)__output[2]}]}" - __idx+="${(m)#__text}" - # Maximum x position - : ${(P)__out2::=$__idx} - return 0 - else - # Add characters that precede and follow - if [[ "$__seg" = (#b)(*)$'\032'[^$'\032']#$'\032'[^$'\032']#$'\032'[^$'\032']#$'\032'[^$'\032']#$'\032'[^$'\032']#$'\032'[^$'\032']#$'\032'[^$'\02']#$'\02'(*) ]]; then - __idx+=${(m)#match[1]}+${(m)#match[2]} - fi - __idx+="${(P)__output[2]}" - fi - elif -zui_std_decode_list_box "$__seg" __output; then - if [[ "$__id" = "${__output[1]}" ]]; then - # Add characters that precede - if [[ "$__seg" = (#b)(*)$'\034'[^$'\034']#$'\034'[^$'\034']#$'\034'[^$'\034']#$'\034'[^$'\034']#$'\034'[^$'\034']#$'\034'[^$'\034']#$'\034'[^$'\02']#$'\02'* ]]; then - __idx+=${(m)#match[1]} - fi - - # Minimum x position - : ${(P)__out1::=$__idx} - - # Just take width - __idx+="${__output[2]}" - - # Maximum x position - : ${(P)__out2::=$__idx} - return 0 - else - # Add characters that precede and follow - if [[ "$__seg" = (#b)(*)$'\034'[^$'\034']#$'\034'[^$'\034']#$'\034'[^$'\034']#$'\034'[^$'\034']#$'\034'[^$'\034']#$'\034'[^$'\034']#$'\034'[^$'\02']#$'\02'(*) ]]; then - __idx+=${(m)#match[1]}+${(m)#match[2]} - fi - __idx+="${(P)__output[2]}" - fi - elif -zui_std_get_stext "$__seg" __text; then - -zui_util_strip_codes "$__text" - __idx+="${(m)#REPLY}" - else - -zui_util_strip_codes "$__seg" - __idx+="${(m)#REPLY}" - fi - done +-zui_sys_get_tfield_cursor_boundaries() { + local __out1="$1" __out2="$2" __elem="$3" __id="$4" + local -a __output + + zui-process-buffer "$__elem" + + integer __i __size="${#ZUI_PB_WORDS}" __idx=0 + local __seg __text REPLY + for (( __i=1; __i <= __size; __i ++ )); do __idx+="${#ZUI_PB_SPACES[__i]}" + __seg="${ZUI_PB_WORDS[__i]}" + if -zui_std_is_hyperlink "$__seg"; then + __text="${__seg//(#b)$'\01'[^$'\01']#$'\01'[^$'\01']#$'\01'[^$'\01']#$'\01'[^$'\01']#$'\01'[^$'\02']#$'\02'([^$'\02']#)$'\02'/${(Q)match[1]}}" + -zui_util_strip_codes "$__text" + __idx+="${(m)#REPLY}" + elif -zui_std_decode_text_field "$__seg" __output; then + if [[ "$__id" = "${__output[1]}" ]]; then + # Add characters that precede + if [[ "$__seg" = (#b)(*)$'\032'[^$'\032']#$'\032'[^$'\032']#$'\032'[^$'\032']#$'\032'[^$'\032']#$'\032'[^$'\032']#$'\032'[^$'\032']#$'\032'[^$'\02']#$'\02'* ]]; then + __idx+=${(m)#match[1]} + fi + # Minimum x position + : ${(P)__out1::=$__idx} + + __text="${(P)__output[4]}" + __text="${__text[${(P)__output[3]},-1]}" + __text="${__text[1,${(P)__output[2]}]}" + __idx+="${(m)#__text}" + # Maximum x position + : ${(P)__out2::=$__idx} + return 0 + else + # Add characters that precede and follow + if [[ "$__seg" = (#b)(*)$'\032'[^$'\032']#$'\032'[^$'\032']#$'\032'[^$'\032']#$'\032'[^$'\032']#$'\032'[^$'\032']#$'\032'[^$'\032']#$'\032'[^$'\02']#$'\02'(*) ]]; then + __idx+=${(m)#match[1]}+${(m)#match[2]} + fi + __idx+="${(P)__output[2]}" + fi + elif -zui_std_decode_list_box "$__seg" __output; then + if [[ "$__id" = "${__output[1]}" ]]; then + # Add characters that precede + if [[ "$__seg" = (#b)(*)$'\034'[^$'\034']#$'\034'[^$'\034']#$'\034'[^$'\034']#$'\034'[^$'\034']#$'\034'[^$'\034']#$'\034'[^$'\034']#$'\034'[^$'\02']#$'\02'* ]]; then + __idx+=${(m)#match[1]} + fi - # Store incorrect data - : ${(P)__out1::=$__idx} - : ${(P)__out2::=$__idx} + # Minimum x position + : ${(P)__out1::=$__idx} - return 1 + # Just take width + __idx+="${__output[2]}" + + # Maximum x position + : ${(P)__out2::=$__idx} + return 0 + else + # Add characters that precede and follow + if [[ "$__seg" = (#b)(*)$'\034'[^$'\034']#$'\034'[^$'\034']#$'\034'[^$'\034']#$'\034'[^$'\034']#$'\034'[^$'\034']#$'\034'[^$'\034']#$'\034'[^$'\02']#$'\02'(*) ]]; then + __idx+=${(m)#match[1]}+${(m)#match[2]} + fi + __idx+="${(P)__output[2]}" + fi + elif -zui_std_get_stext "$__seg" __text; then + -zui_util_strip_codes "$__text" + __idx+="${(m)#REPLY}" + else + -zui_util_strip_codes "$__seg" + __idx+="${(m)#REPLY}" + fi + done + + __idx+="${#ZUI_PB_SPACES[__i]}" + + # Store incorrect data + : ${(P)__out1::=$__idx} + : ${(P)__out2::=$__idx} + + return 1 } # }}} # FUNCTION: -zui_sys_map_cursor_on_string {{{ @@ -115,22 +111,22 @@ function -zui_sys_get_tfield_cursor_boundaries() { # $2 - string # $3 - cursor position # $4 - output parameter name -function -zui_sys_map_cursor_on_string() { - local __idx="$1" __str="$2" __curx="$3" __var_name="$4" - integer __i __count=${#__str} __width_sum=0 - - for (( __i = 1; __i <= __count; __i ++ )); do - if (( __width_sum - 1 >= __curx )); then - (( __idx += __i - 1 - 1 )) - : ${(P)__var_name::=$__idx} - return 0 - fi - __width_sum+=${(m)#__str[__idx+__i-1]} - done +-zui_sys_map_cursor_on_string() { + local __idx="$1" __str="$2" __curx="$3" __var_name="$4" + integer __i __count=${#__str} __width_sum=0 + + for (( __i = 1; __i <= __count; __i ++ )); do + if (( __width_sum - 1 >= __curx )); then + (( __idx += __i - 1 - 1 )) + : ${(P)__var_name::=$__idx} + return 0 + fi + __width_sum+=${(m)#__str[__idx+__i-1]} + done - (( __idx += __i - 1 - 1 )) - : ${(P)__var_name::=$__idx} - return 1 + (( __idx += __i - 1 - 1 )) + : ${(P)__var_name::=$__idx} + return 1 } # }}} # FUNCTION: -zui_sys_index_tail_width {{{ @@ -141,20 +137,20 @@ function -zui_sys_map_cursor_on_string() { # $1 - string # $2 - expected width # $3 - output parameter name for the index -function -zui_sys_index_tail_width() { - local __str="$1" __width="$2" __var_name="$3" - integer __i __count=${#__str} __width_sum=0 - - for (( __i = __count; __i >= 1; __i -- )); do - __width_sum+=${(m)#__str[__i]} - if (( __width_sum >= __width )); then - : ${(P)__var_name::=$__i} - return 0 - fi - done +-zui_sys_index_tail_width() { + local __str="$1" __width="$2" __var_name="$3" + integer __i __count=${#__str} __width_sum=0 + + for (( __i = __count; __i >= 1; __i -- )); do + __width_sum+=${(m)#__str[__i]} + if (( __width_sum >= __width )); then + : ${(P)__var_name::=$__i} + return 0 + fi + done - : ${(P)__var_name::=1} - return 1 + : ${(P)__var_name::=1} + return 1 } # }}} # FUNCTION: -zui_sys_gather_lanchors {{{ @@ -163,18 +159,18 @@ function -zui_sys_index_tail_width() { # $1 - module index # $2 - instance index # $3 - target array name -function -zui_sys_gather_lanchors() { - local __var_name1="mod${1}_ice${2}_lanchors" __var_name2="${3-reply}" - if [[ -z "$1" || -z "$2" ]]; then - echo "-zui_std_gather_lanchors must obtain module and instance indices" - return 1 - fi +-zui_sys_gather_lanchors() { + local __var_name1="mod${1}_ice${2}_lanchors" __var_name2="${3-reply}" + if [[ -z "$1" || -z "$2" ]]; then + echo "-zui_std_gather_lanchors must obtain module and instance indices" + return 1 + fi - # Append and store - local -a __output - __output=( "${(P@)__var_name2}" "${(P@)__var_name1}" ) + # Append and store + local -a __output + __output=( "${(P@)__var_name2}" "${(P@)__var_name1}" ) - : ${(PA)__var_name2::=${__output[@]}} + : ${(PA)__var_name2::=${__output[@]}} } # }}} # FUNCTION: -zui_sys_decode_list_update {{{ @@ -183,12 +179,12 @@ function -zui_sys_gather_lanchors() { # # $1 - the package # $2 - optional target parameter name -function -zui_sys_decode_list_update() { - local -a __segments - [[ -n "$1" ]] && __segments=( "${(z@)1}" ) || __segments=( "" "" 0 0 ) - local __var_name="${2-reply}" +-zui_sys_decode_list_update() { + local -a __segments + [[ -n "$1" ]] && __segments=( "${(z@)1}" ) || __segments=( "" "" 0 0 ) + local __var_name="${2-reply}" - : ${(PA)__var_name::="${(Q)__segments[@]}"} + : ${(PA)__var_name::="${(Q)__segments[@]}"} } # }}} # FUNCTION: -zui_sys_decode_hops {{{ @@ -197,11 +193,11 @@ function -zui_sys_decode_list_update() { # # $1 - the hops' package # $2 - optional target parameter name -function -zui_sys_decode_hops() { - local -a __hops - [[ -n "$1" ]] && __hops=( "${(z@)1}" ) || __hops=( ) - local __var_name="${2-reply}" - : ${(PA)__var_name::=${(Q)__hops[@]}} +-zui_sys_decode_hops() { + local -a __hops + [[ -n "$1" ]] && __hops=( "${(z@)1}" ) || __hops=( ) + local __var_name="${2-reply}" + : ${(PA)__var_name::=${(Q)__hops[@]}} } # }}} # FUNCTION: -zui_sys_decode_nonselectables {{{ @@ -210,11 +206,11 @@ function -zui_sys_decode_hops() { # # $1 - the nonselectables' package # $2 - optional target parameter name -function -zui_sys_decode_nonselectables() { - local -a __nonselectables - [[ -n "$1" ]] && __nonselectables=( "${(z@)1}" ) || __nonselectables=( ) - local __var_name="${2-reply}" - : ${(PA)__var_name::="${(Q)__nonselectables[@]}"} +-zui_sys_decode_nonselectables() { + local -a __nonselectables + [[ -n "$1" ]] && __nonselectables=( "${(z@)1}" ) || __nonselectables=( ) + local __var_name="${2-reply}" + : ${(PA)__var_name::="${(Q)__nonselectables[@]}"} } # }}} # FUNCTION: -zui_sys_decode_lanchors {{{ @@ -223,11 +219,11 @@ function -zui_sys_decode_nonselectables() { # # $1 - the anchors' package # $2 - optional target parameter name -function -zui_sys_decode_lanchors() { - local -a __lanchors - [[ -n "$1" ]] && __lanchors=( "${(z@)1}" ) || __lanchors=( ) - local __var_name="${2-reply}" - : ${(PA)__var_name::="${(Q)__lanchors[@]}"} +-zui_sys_decode_lanchors() { + local -a __lanchors + [[ -n "$1" ]] && __lanchors=( "${(z@)1}" ) || __lanchors=( ) + local __var_name="${2-reply}" + : ${(PA)__var_name::="${(Q)__lanchors[@]}"} } # }}} # FUNCTION: -zui_sys_add_message {{{ @@ -236,32 +232,32 @@ function -zui_sys_decode_lanchors() { # $1 - message type # $2 - timestamp # $3, $4, ... - message bits / lines -function -zui_sys_add_message() { - local tpe="$1" ts="${2:-$(date +%s)}" timestr="" - - if [[ -n "${ZUI[log_time_format]}" ]]; then - if (( ${+builtins[strftime]} )); then - strftime -s timestr "${ZUI[log_time_format]}" "$ts" - else - # Slow and not respecting $ts fallback - # but will rescue users with weird zsh - timestr=$(date "+${ZUI[log_time_format]}") - fi +-zui_sys_add_message() { + local tpe="$1" ts="${2:-$(date +%s)}" timestr="" + + if [[ -n "${ZUI[log_time_format]}" ]]; then + if (( ${+builtins[strftime]} )); then + strftime -s timestr "${ZUI[log_time_format]}" "$ts" + else + # Slow and not respecting $ts fallback + # but will rescue users with weird zsh + timestr=$(date "+${ZUI[log_time_format]}") fi + fi - # Clean space-only elements - set -- "${@[3,-1]/(#s)[[:space:]]##(#e)/}" + # Clean space-only elements + set -- "${@[3,-1]/(#s)[[:space:]]##(#e)/}" - integer index msg_len=0 - for (( index = 1; index <= ${#}; index ++ )); do - msg_len+=${#@[index]} - done + integer index msg_len=0 + for (( index = 1; index <= ${#}; index ++ )); do + msg_len+=${#@[index]} + done - ZUI_MESSAGES+=( "${(q)msg_len} ${(q)tpe} ${(q)ts} ${(q)timestr} ${(j: :)${(q)@}}" ) - (( ++ ZUI[message_count] )) + ZUI_MESSAGES+=( "${(q)msg_len} ${(q)tpe} ${(q)ts} ${(q)timestr} ${(j: :)${(q)@}}" ) + (( ++ ZUI[message_count] )) - # House-keeping - (( ${#ZUI_MESSAGES} >= ZUI[log_size] + 10 )) && { ZUI_MESSAGES=( "${(@)ZUI_MESSAGES[1+10,-1]}" ); } + # House-keeping + (( ${#ZUI_MESSAGES} >= ZUI[log_size] + 10 )) && { ZUI_MESSAGES=( "${(@)ZUI_MESSAGES[1+10,-1]}" ); } } # }}} # FUNCTION: -zui_sys_get_match_line {{{ @@ -272,51 +268,51 @@ function -zui_sys_add_message() { # # $__slist - input variable with copy of $__list # $1 - output variable to hold the established target line number -function -zui_sys_get_match_line() { - local __var_name="${1:-REPLY}" __i - [[ "${#ZUILIST_NONSELECTABLE_ELEMENTS}" -gt 0 ]] && for __i in "${(nO)ZUILIST_NONSELECTABLE_ELEMENTS[@]}"; do - __slist[$__i]=() +-zui_sys_get_match_line() { + local __var_name="${1:-REPLY}" __i + [[ "${#ZUILIST_NONSELECTABLE_ELEMENTS}" -gt 0 ]] && for __i in "${(nO)ZUILIST_NONSELECTABLE_ELEMENTS[@]}"; do + __slist[$__i]=() + done + [[ "${ZUI[UNIQ_MODE]}" -eq 1 ]] && typeset -gU __slist + + local search_buffer="${ZUI[SEARCH_BUFFER]%% ##}" + search_buffer="${search_buffer## ##}" + search_buffer="${search_buffer//(#m)[][*?|#~^()><\\]/\\$MATCH}" + if [[ -n "$search_buffer" ]]; then + # Base bit of this pattern is ((#s)[^$'\01']#THEWORD*|*$'\02'[^$'\01']#THEWORD*) - the word occurring not inside hyper link + # Pattern will be: BIT1~^BIT2... + local search_pattern=${search_buffer//(#b)([^ ]##)/(#B)((#s)[^$'\01'$'\032'$'\034']#${match[1]}*|*[$'\02'][^$'\01'$'\032'$'\034']#${match[1]}*)~^} + search_pattern="${search_pattern// ##/}" + search_pattern="${search_pattern%\~\^}" + + search_pattern="(#b)(($search_pattern)|(*))" + integer __line=0 __correct=0 + local -a __slist2 + repeat 1; do + __slist=( "${(@)__slist//(#i)$~search_pattern/$(( ++ __line, ${#match[2]} > 0 ? __line : 0 ))}" ) + __slist=( "${(@)__slist:#0}" ) + __slist2=( "${(@)__slist:#}" ) done - [[ "${ZUI[UNIQ_MODE]}" -eq 1 ]] && typeset -gU __slist - - local search_buffer="${ZUI[SEARCH_BUFFER]%% ##}" - search_buffer="${search_buffer## ##}" - search_buffer="${search_buffer//(#m)[][*?|#~^()><\\]/\\$MATCH}" - if [[ -n "$search_buffer" ]]; then - # Base bit of this pattern is ((#s)[^$'\01']#THEWORD*|*$'\02'[^$'\01']#THEWORD*) - the word occuring not inside hyper link - # Pattern will be: BIT1~^BIT2... - local search_pattern=${search_buffer//(#b)([^ ]##)/(#B)((#s)[^$'\01'$'\032'$'\034']#${match[1]}*|*[$'\02'][^$'\01'$'\032'$'\034']#${match[1]}*)~^} - search_pattern="${search_pattern// ##/}" - search_pattern="${search_pattern%\~\^}" - - search_pattern="(#b)(($search_pattern)|(*))" - integer __line=0 __correct=0 - local -a __slist2 - repeat 1; do - __slist=( "${(@)__slist//(#i)$~search_pattern/$(( ++ __line, ${#match[2]} > 0 ? __line : 0 ))}" ) - __slist=( "${(@)__slist:#0}" ) - __slist2=( "${(@)__slist:#}" ) - done - - # Use the same element but from line-number-only array - __line=${__slist2[${ZUI[CURRENT_IDX]}]} - - # Correct for possible empty entries that weren't counted - # because // substitution ignores empty elements, always - integer __index=${__slist[(i)$__line]} - local -a __empty - __empty=( "${(@M)__slist[1,__index]:#}" ) - __line+=${#__empty} - - [[ "${ZUI[UNIQ_MODE]}" -ne 1 ]] && [[ "${#ZUILIST_NONSELECTABLE_ELEMENTS}" -gt 0 ]] && for __i in "${(no)ZUILIST_NONSELECTABLE_ELEMENTS[@]}"; do - (( __i <= __line + __correct )) && __correct+=1 - done - - __line+=__correct - - : ${(P)__var_name::=$__line} - return 0 - fi - return 1 + # Use the same element but from line-number-only array + __line=${__slist2[${ZUI[CURRENT_IDX]}]} + + # Correct for possible empty entries that weren't counted + # because // substitution ignores empty elements, always + integer __index=${__slist[(i)$__line]} + local -a __empty + __empty=( "${(@M)__slist[1,__index]:#}" ) + __line+=${#__empty} + + [[ "${ZUI[UNIQ_MODE]}" -ne 1 ]] && [[ "${#ZUILIST_NONSELECTABLE_ELEMENTS}" -gt 0 ]] && for __i in "${(no)ZUILIST_NONSELECTABLE_ELEMENTS[@]}"; do + (( __i <= __line + __correct )) && __correct+=1 + done + + __line+=__correct + + : ${(P)__var_name::=$__line} + return 0 + fi + + return 1 } # }}} diff --git a/lib/utillib.lzui b/lib/utillib.lzui index 7243fc0..37302f0 100644 --- a/lib/utillib.lzui +++ b/lib/utillib.lzui @@ -1,7 +1,3 @@ -# ============================================================================ # -# [ https://github.com/z-shell ] ❮ ZI ❯ [ (c) 2022 Z-SHELL COMMUNITY ] # -# ============================================================================ # -# # -*- mode: zsh; sh-indentation: 2; indent-tabs-mode: nil; sh-basic-offset: 2; -*- # vim: ft=zsh sw=2 ts=2 et # @@ -29,26 +25,26 @@ ZUI[utillib_sourced]="1" # -zui_util_map_bools "1;[[ a = b ]];ZUI[text_select]" \ # "color1;color2;color3" $red $white # -function -zui_util_map_bools() { - local __exp="$1" __pm="$2" __tre="$3" __fse="$4" - - local -a __exps __pms - __exps=( "${(@s:;:)__exp}" ) - __pms=( "${(@s:;:)__pm}" ) - - integer __index __size=${#__pms} - for (( __index=1; __index <= __size; ++ __index )); do - __exp="${__exps[__index]}" - __pm="${__pms[__index]}" - [[ -z "${__exp##[[:space:]]##}" || -z "${__pm##[[:space:]]##}" ]] && continue - if [[ "$__exp" = <-> ]] then - (( $__exp )) && : ${(P)__pm::=$__tre} || : ${(P)__pm::=$__fse} - elif [[ "$__exp" != *\[\[* && "$__exp" != *\(\(* ]]; then - [[ "${(P)__exp}" != <-> || "${(P)__exp}" = 0## ]] && : ${(P)__pm::=$__fse} || : ${(P)__pm::=$__tre} - else - eval "$__exp" && : ${(P)__pm::=$__tre} || : ${(P)__pm::=$__fse} - fi - done +-zui_util_map_bools() { + local __exp="$1" __pm="$2" __tre="$3" __fse="$4" + + local -a __exps __pms + __exps=( "${(@s:;:)__exp}" ) + __pms=( "${(@s:;:)__pm}" ) + + integer __index __size=${#__pms} + for (( __index=1; __index <= __size; ++ __index )); do + __exp="${__exps[__index]}" + __pm="${__pms[__index]}" + [[ -z "${__exp##[[:space:]]##}" || -z "${__pm##[[:space:]]##}" ]] && continue + if [[ "$__exp" = <-> ]] then + (( $__exp )) && : ${(P)__pm::=$__tre} || : ${(P)__pm::=$__fse} + elif [[ "$__exp" != *\[\[* && "$__exp" != *\(\(* ]]; then + [[ "${(P)__exp}" != <-> || "${(P)__exp}" = 0## ]] && : ${(P)__pm::=$__fse} || : ${(P)__pm::=$__tre} + else + eval "$__exp" && : ${(P)__pm::=$__tre} || : ${(P)__pm::=$__fse} + fi + done } # }}} # FUNCTION: -zui_util_strip_codes {{{ @@ -56,8 +52,8 @@ function -zui_util_map_bools() { # $1, saves result into parameter REPLY # # $1 - text to strip codes from -function -zui_util_strip_codes() { - REPLY="${1//[$'\03'-$'\07'$'\013'-$'\014'$'\016'-$'\031'$'\037']/}" +-zui_util_strip_codes() { + REPLY="${1//[$'\03'-$'\07'$'\013'-$'\014'$'\016'-$'\031'$'\037']/}" } # }}} # FUNCTION: -zui_util_get_segment {{{ @@ -67,22 +63,22 @@ function -zui_util_strip_codes() { # $3 - destination variable name (default is "REPLY") # # Can use e.g. 'reply[1]' for $3 -function -zui_util_get_segment() { - local -a segs - segs=( "${(z@)1}" ) - local varname="${3:-REPLY}" - local index="${2:-1}" - : ${(P)varname::=${segs[index]}} +-zui_util_get_segment() { + local -a segs + segs=( "${(z@)1}" ) + local varname="${3:-REPLY}" + local index="${2:-1}" + : ${(P)varname::=${segs[index]}} } # }}} # FUNCTION: -zui_util_get_time {{{ # # Returns time %H:%M, via datetime or `date` as fallback # -function -zui_util_get_time() { - local ts - ts="$EPOCHSECONDS" - [[ -z "$ts" || "$ts" = "0" ]] && REPLY="$(date '+%H:%M')" || strftime -s REPLY '%H:%M' "$ts" +-zui_util_get_time() { + local ts + ts="$EPOCHSECONDS" + [[ -z "$ts" || "$ts" = "0" ]] && REPLY="$(date '+%H:%M')" || strftime -s REPLY '%H:%M' "$ts" } # }}} # FUNCTION: -zui_util_get_datetime {{{ @@ -91,29 +87,29 @@ function -zui_util_get_time() { # # $REPLY - date and time string "Ymd_H.M.S" # -function -zui_util_get_datetime() { - local ts - ts="$EPOCHSECONDS" - [[ -z "$ts" || "$ts" = "0" ]] && REPLY="$(date '+%Y%m%d_%H.%M.%S')" || strftime -s REPLY '%Y%m%d_%H.%M.%S' "$ts" +-zui_util_get_datetime() { + local ts + ts="$EPOCHSECONDS" + [[ -z "$ts" || "$ts" = "0" ]] && REPLY="$(date '+%Y%m%d_%H.%M.%S')" || strftime -s REPLY '%Y%m%d_%H.%M.%S' "$ts" } # }}} # FUNCTION: -zui_util_get_timestamp {{{ # Returns timestamp, via datetime or `date` as fallback # -function -zui_util_get_timestamp() { - REPLY="$EPOCHSECONDS" - [[ -z "$REPLY" ]] && REPLY="$(date +%s)" +-zui_util_get_timestamp() { + REPLY="$EPOCHSECONDS" + [[ -z "$REPLY" ]] && REPLY="$(date +%s)" } # }}} # FUNCTION: -zui_util_has_default_color {{{ # Returns true if the "default" color # can be used with current Zsh/zcurses -function -zui_util_has_default_color() { - (( ${+zcurses_colors} )) || return 2 - [[ -z "${zcurses_colors[(r)default]}" ]] && return 1 - autoload is-at-least - is-at-least 2>/dev/null 5.3 && return 0 - return 1 +-zui_util_has_default_color() { + (( ${+zcurses_colors} )) || return 2 + [[ -z "${zcurses_colors[(r)default]}" ]] && return 1 + autoload is-at-least + is-at-least 2>/dev/null 5.3 && return 0 + return 1 } # }}} # FUNCTION: -zui_util_resolve_path {{{ @@ -127,25 +123,25 @@ function -zui_util_has_default_color() { # # $reply[2] - basename # -function -zui_util_resolve_path() { - local dirpath="$1" filepath="$2" - - local dirpath2="${dirpath/#\~/$HOME}" - # :a behaves weird, prepends paths, which are not CWD - [ "${dirpath2[1]}" = "/" ] && dirpath2="${dirpath2:a}" - local filepath2="${filepath/#\~/$HOME}" - [ "${filepath2[1]}" = "/" ] && filepath2="${filepath2:a}" - - reply=() - if [ "${filepath2[1]}" = "/" ]; then - reply[1]="${filepath2:h}" - reply[2]="${filepath2:t}" - else - local p="$dirpath2/$filepath2" - [ "${p[1]}" = "/" ] && p="${p:a}" - reply[1]="${p:h}" - reply[2]="${p:t}" - fi +-zui_util_resolve_path() { + local dirpath="$1" filepath="$2" + + local dirpath2="${dirpath/#\~/$HOME}" + # :a behaves weird, prepends paths, which are not CWD + [ "${dirpath2[1]}" = "/" ] && dirpath2="${dirpath2:a}" + local filepath2="${filepath/#\~/$HOME}" + [ "${filepath2[1]}" = "/" ] && filepath2="${filepath2:a}" + + reply=() + if [ "${filepath2[1]}" = "/" ]; then + reply[1]="${filepath2:h}" + reply[2]="${filepath2:t}" + else + local p="$dirpath2/$filepath2" + [ "${p[1]}" = "/" ] && p="${p:a}" + reply[1]="${p:h}" + reply[2]="${p:t}" + fi } # }}} # FUNCTION: -zui_util_to_cmd_line {{{ @@ -154,15 +150,15 @@ function -zui_util_resolve_path() { # # $1 - text to put on command line # -function -zui_util_to_cmd_line() { - if zle; then - zle .kill-buffer - BUFFER="$1" - zle .redisplay - zle .beginning-of-line - else - print -zr "$1" - fi +-zui_util_to_cmd_line() { + if zle; then + zle .kill-buffer + BUFFER="$1" + zle .redisplay + zle .beginning-of-line + else + print -zr "$1" + fi } # }}} # FUNCTION: -zui_util_circular_next {{{ @@ -174,27 +170,27 @@ function -zui_util_to_cmd_line() { # $1 - base of file names in circular buffer # $2 - maximum number of files in circular buffer # -function -zui_util_circular_next() { - setopt localoptions extendedglob +-zui_util_circular_next() { + setopt local_options extended_glob - # Input data - local base="$1" count="$2" + # Input data + local base="$1" count="$2" - # Circular buffers' directory - local circpath="$ZUI_CONFIG_DIR/var/circular_buffers" - [[ ! -d "$circpath" ]] && command mkdir -p "$circpath" + # Circular buffers' directory + local circpath="${Plugins[ZUI_CONFIG_DIR]}/var/circular_buffers" + [[ ! -d "$circpath" ]] && command mkdir -p "$circpath" - local -a circular_buffer - circular_buffer=( "$circpath"/"$base".[[:digit:]]##(OmN) ) + local -a circular_buffer + circular_buffer=( "${circpath}"/"${base}".[[:digit:]]##(OmN) ) - if [[ "$count" -gt "${#circular_buffer}" ]]; then - integer next_index=$(( ${#circular_buffer} + 1 )) - REPLY="$circpath/${base}.${next_index}" - else - REPLY="${circular_buffer[1]}" - fi + if [[ "$count" -gt "${#circular_buffer}" ]]; then + integer next_index=$(( ${#circular_buffer} + 1 )) + REPLY="${circpath}/${base}.${next_index}" + else + REPLY="${circular_buffer[1]}" + fi - return 0 + return 0 } # }}} # FUNCTION: -zui_util_circular_paths {{{ @@ -207,20 +203,20 @@ function -zui_util_circular_next() { # # $1 - name of the circular buffer # -function -zui_util_circular_paths() { - setopt localoptions extendedglob +-zui_util_circular_paths() { + setopt local_options extended_glob - # Input data - local base="$1" + # Input data + local base="$1" - # Output array - reply=( ) + # Output array + reply=( ) - # Circular buffers' directory - local circpath="$ZUI_CONFIG_DIR/var/circular_buffers" - [[ ! -d "$circpath" ]] && return 1 + # Circular buffers' directory + local circpath="${Plugins[ZUI_CONFIG_DIR]}/var/circular_buffers" + [[ ! -d "$circpath" ]] && return 1 - reply=( "$circpath"/"$base".[[:digit:]]##(omN) ) + reply=( "$circpath"/"$base".[[:digit:]]##(omN) ) } # }}} # FUNCTION: -zui_util_to_cmd_line {{{ @@ -228,13 +224,13 @@ function -zui_util_circular_paths() { # # $1 - text to put on command line # -function -zui_util_to_cmd_line() { - if zle; then - zle .kill-buffer - BUFFER="$1" - zle .redisplay - zle .beginning-of-line - else - print -zr "$1" - fi +-zui_util_to_cmd_line() { + if zle; then + zle .kill-buffer + BUFFER="$1" + zle .redisplay + zle .beginning-of-line + else + print -zr "$1" + fi } # }}} diff --git a/zui.plugin.zsh b/zui.plugin.zsh index 021f727..a75399f 100644 --- a/zui.plugin.zsh +++ b/zui.plugin.zsh @@ -1,33 +1,25 @@ -# ============================================================================ # -# [ https://github.com/z-shell ] ❮ ZI ❯ [ (c) 2022 Z-SHELL COMMUNITY ] # -# ============================================================================ # -# # -*- mode: zsh; sh-indentation: 2; indent-tabs-mode: nil; sh-basic-offset: 2; -*- # vim: ft=zsh sw=2 ts=2 et # -# No plugin manager is needed to use this file. All that is needed is adding: -# source {wherezui-is}/zui.plugin.zsh +# No plugin manager is needed to use this file. +# All that is needed is adding: +# +# source {where-zui-is}/zui.plugin.zsh # # to ~/.zshrc. # - -0="${(%):-%N}" # this gives immunity to functionargzero being unset -ZUI_REPO_DIR="${0%/*}" - -# Check if ZI config directory exist. -if [[ -d $ZCDR ]]; then - # Use ZI default config directory. - ZUI_CONFIG_DIR="${ZCDR}/zui" -else - # Use common values to set default working directory. - ZUI_CONFIG_DIR="${XDG_CONFIG_HOME:-$HOME/.config}/zi/zui" -fi - -# Update FPATH if: -# 1. Not loading with ZI -# 2. Not having fpath already updated (that would equal: using other plugin manager) -if [[ -z "$ZI_CUR_PLUGIN" && "${fpath[(r)$ZUI_REPO_DIR]}" != $ZUI_REPO_DIR ]]; then - fpath+=( "$ZUI_REPO_DIR/functions" ) +# https://wiki.zshell.dev/community/zsh_plugin_standard#zero-handling +0="${ZERO:-${${0:#$ZSH_ARGZERO}:-${(%):-%N}}}" +0="${${(M)0:#/*}:-$PWD/$0}" + +# https://wiki.zshell.dev/community/zsh_plugin_standard#standard-plugins-hash +typeset -gA Plugins +Plugins[ZUI_DIR]="${0:h}" +Plugins[ZUI_CONFIG_DIR]="${ZI[CONFIG_DIR]}/zui:-${XDG_CONFIG_HOME:-$HOME/.config}/zi/zui" + +# https://wiki.zshell.dev/community/zsh_plugin_standard#functions-directory +if [[ $PMSPEC != *f* ]]; then + fpath+=( "${0:h}/functions" ) fi # Load colors @@ -38,19 +30,17 @@ fi # # Support reloading -(( ${+functions[zui-list]} )) && { unfunction -- zui-list zui-list-draw zui-list-input zui-list-wrapper -zui-log zui-event-loop -zui-list-box-loop zui-process-buffer zui-process-buffer2 zui-usetty-wrapper zui-demo-various zui-demo-hello-world zui-demo-text-fields zui-demo-fly zui-demo-append zui-demo-buttons zui-demo-anchors zui-demo-list-boxes zui-demo-history -zui_std_cleanup -zui_std_init 2>/dev/null; unset ZUI; } +(( ${+functions[zui-list]} )) && { + unfunction -- zui-list zui-list-draw zui-list-input zui-list-wrapper -zui-log \ + zui-event-loop -zui-list-box-loop zui-process-buffer zui-process-buffer2 zui-usetty-wrapper \ + zui-demo-various zui-demo-hello-world zui-demo-text-fields zui-demo-fly zui-demo-append zui-demo-buttons \ + zui-demo-anchors zui-demo-list-boxes zui-demo-history -zui_std_cleanup -zui_std_init 2>/dev/null + unset ZUI +} autoload -- zui-list zui-list-draw zui-list-input zui-list-wrapper -zui-log zui-event-loop -zui-list-box-loop autoload -- zui-process-buffer zui-process-buffer2 zui-usetty-wrapper -fpath+=( "${ZUI_REPO_DIR}/demos" ) -autoload -- zui-demo-hello-world zui-demo-fly zui-demo-append zui-demo-text-fields zui-demo-list-boxes zui-demo-anchors -autoload -- zui-demo-ganchors zui-demo-buttons zui-demo-special-text zui-demo-history zui-demo-various zui-demo-timeout -autoload -- zui-demo-configure zui-demo-edit zui-demo-toggles zui-demo-nmap - -zle -N zui-demo-various -bindkey "^O^Z" zui-demo-various - # # Global parameters # @@ -58,6 +48,18 @@ bindkey "^O^Z" zui-demo-various typeset -gAH ZUI typeset -ga ZUI_MESSAGES +# Enable demos if ZUI[DEMOS] is set, i.e.: typeset -A ZUI; ZUI[DEMOS]=1 +if (( ZUI[DEMOS] )); then + fpath+=( "${0:h}/demos" ) + + autoload -- zui-demo-hello-world zui-demo-fly zui-demo-append zui-demo-text-fields zui-demo-list-boxes zui-demo-anchors + autoload -- zui-demo-ganchors zui-demo-buttons zui-demo-special-text zui-demo-history zui-demo-various zui-demo-timeout + autoload -- zui-demo-configure zui-demo-edit zui-demo-toggles zui-demo-nmap + + zle -N zui-demo-various + bindkey "^O^Z" zui-demo-various +fi + # # Load modules # @@ -73,21 +75,25 @@ zmodload zsh/datetime && ZUI[datetime_available]="1" || ZUI[datetime_available]= # functions called, sourcing the libraries (( 0 == ${+functions[-zui_std_cleanup]} )) && { - function -zui_std_cleanup() { - unfunction -- -zui_std_cleanup - [[ "${ZUI[stdlib_sourced]}" != "1" ]] && source "${ZUI_REPO_DIR}/lib/stdlib.lzui" - [[ "${ZUI[syslib_sourced]}" != "1" ]] && source "${ZUI_REPO_DIR}/lib/syslib.lzui" - [[ "${ZUI[utillib_sourced]}" != "1" ]] && source "${ZUI_REPO_DIR}/lib/utillib.lzui" - -zui_std_cleanup "$@" - } + -zui_std_cleanup() { + unfunction -- -zui_std_cleanup + + [[ "${ZUI[stdlib_sourced]}" != "1" ]] && builtin source "${Plugins[ZUI_DIR]}/lib/stdlib.lzui" + [[ "${ZUI[syslib_sourced]}" != "1" ]] && builtin source "${Plugins[ZUI_DIR]}/lib/syslib.lzui" + [[ "${ZUI[utillib_sourced]}" != "1" ]] && builtin source "${Plugins[ZUI_DIR]}/lib/utillib.lzui" + + -zui_std_cleanup "$@" + } } (( 0 == ${+functions[-zui_std_init]} )) && { - function -zui_std_init() { - unfunction -- -zui_std_init - [[ "${ZUI[stdlib_sourced]}" != "1" ]] && source "${ZUI_REPO_DIR}/lib/stdlib.lzui" - [[ "${ZUI[syslib_sourced]}" != "1" ]] && source "${ZUI_REPO_DIR}/lib/syslib.lzui" - [[ "${ZUI[utillib_sourced]}" != "1" ]] && source "${ZUI_REPO_DIR}/lib/utillib.lzui" - -zui_std_init "$@" - } + -zui_std_init() { + unfunction -- -zui_std_init + + [[ "${ZUI[stdlib_sourced]}" != "1" ]] && builtin source "${Plugins[ZUI_DIR]}/lib/stdlib.lzui" + [[ "${ZUI[syslib_sourced]}" != "1" ]] && builtin source "${Plugins[ZUI_DIR]}/lib/syslib.lzui" + [[ "${ZUI[utillib_sourced]}" != "1" ]] && builtin source "${Plugins[ZUI_DIR]}/lib/utillib.lzui" + + -zui_std_init "$@" + } }