From 00648901a93a8b4eafa824da55c591909b4bd05a Mon Sep 17 00:00:00 2001 From: Konstantin Demin Date: Wed, 23 Jul 2025 10:59:44 +0300 Subject: [PATCH] zsh: update --- .config/dotfiles/gitignore | 4 +- .config/zsh/_.zsh | 6 +- .config/zsh/lib/cmdtime.zsh | 7 +- .config/zsh/lib/prompt.zsh | 4 +- .config/zsh/lib/term.zsh | 134 ++++++++++++++++++ .config/zsh/lib/title.zsh | 58 -------- .config/zsh/opt.zsh | 11 +- .config/zsh/opt/completion.zsh | 8 +- .config/zsh/opt/directories.zsh | 6 +- .config/zsh/opt/history.zsh | 10 +- .config/zsh/rc.zsh | 52 +++++-- .../rc/{keyboard.zsh => keyboard-base.zsh} | 13 +- .config/zsh/rc/keyboard-extras.zsh | 7 + .config/zsh/rc/prompt.zsh | 30 ++-- 14 files changed, 219 insertions(+), 131 deletions(-) delete mode 100644 .config/zsh/lib/title.zsh rename .config/zsh/rc/{keyboard.zsh => keyboard-base.zsh} (90%) create mode 100644 .config/zsh/rc/keyboard-extras.zsh diff --git a/.config/dotfiles/gitignore b/.config/dotfiles/gitignore index 874ca5e..7ec9f09 100644 --- a/.config/dotfiles/gitignore +++ b/.config/dotfiles/gitignore @@ -64,7 +64,6 @@ !/.config/zsh/lib/systemd.zsh !/.config/zsh/lib/term.zsh !/.config/zsh/lib/time.zsh -!/.config/zsh/lib/title.zsh !/.config/zsh/local.zsh.example !/.config/zsh/local/.keep !/.config/zsh/local/completion/.keep @@ -78,7 +77,8 @@ !/.config/zsh/rc.zsh !/.config/zsh/rc/completion.zsh !/.config/zsh/rc/gpg-agent.zsh -!/.config/zsh/rc/keyboard.zsh +!/.config/zsh/rc/keyboard-base.zsh +!/.config/zsh/rc/keyboard-extras.zsh !/.config/zsh/rc/pager.zsh !/.config/zsh/rc/prompt.zsh !/.config/zsh/rc/ssh-agent.zsh diff --git a/.config/zsh/_.zsh b/.config/zsh/_.zsh index e0199cc..a0e2725 100644 --- a/.config/zsh/_.zsh +++ b/.config/zsh/_.zsh @@ -1,10 +1,12 @@ #!/bin/zsh -## early module load -zmodload -s zsh/zprof +## early load modules +zmodload zsh/mathfunc zsh/datetime zsh/zprof typeset -gA ZSHU +__z_unsupported() { echo "not supported" >&2 ; } + ZSHU[t_begin]=${(%):-%D{%s.%6.}} ZSHU[d_zdot]="${ZDOTDIR}" diff --git a/.config/zsh/lib/cmdtime.zsh b/.config/zsh/lib/cmdtime.zsh index 669a5dd..ebc65a6 100644 --- a/.config/zsh/lib/cmdtime.zsh +++ b/.config/zsh/lib/cmdtime.zsh @@ -7,8 +7,7 @@ z-time() { "$@" ; r=$? a=$[ EPOCHREALTIME - a ] a=$(z-ts-to-human "$a" 6) - echo >&2 - echo "time took: $a" >&2 + printf '\n# time took: %s\n' "$a" >&2 return $r } @@ -49,5 +48,7 @@ add-zsh-hook precmd __z_cmdtime_measure add-zsh-hook preexec __z_cmdtime_set else - echo "cmd time measurement is disabled due to missing hook support" >&2 + +echo "cmd time measurement is disabled due to missing hook support" >&2 + fi diff --git a/.config/zsh/lib/prompt.zsh b/.config/zsh/lib/prompt.zsh index 84a646d..a60cf10 100644 --- a/.config/zsh/lib/prompt.zsh +++ b/.config/zsh/lib/prompt.zsh @@ -47,5 +47,7 @@ __z_pwd_hook() { add-zsh-hook precmd __z_pwd_hook else - echo "shiny pwd's are disabled due to missing hook support" >&2 + +echo "shiny pwd's are disabled due to missing hook support" >&2 + fi diff --git a/.config/zsh/lib/term.zsh b/.config/zsh/lib/term.zsh index 047d2fb..4b33f44 100644 --- a/.config/zsh/lib/term.zsh +++ b/.config/zsh/lib/term.zsh @@ -1,5 +1,6 @@ #!/bin/zsh +typeset -gA ZSHU_TERM typeset -Uga ZSHU_TERM_MISSING z-ti-test() { @@ -16,3 +17,136 @@ z-ti-test() { return $r } + +case "${TERM}" in +xterm* | putty* | rxvt* | konsole* | mlterm* | alacritty* | foot* | contour* ) + ZSHU_TERM[has_title_tab]=1 + ZSHU_TERM[has_title_wnd]=1 + ZSHU_TERM[want_cwd]=1 + + ZSHU_TERM[title_tab]=term + ZSHU_TERM[title_wnd]=term +;; +st* | wezterm* ) + ZSHU_TERM[has_title_tab]=1 + ZSHU_TERM[has_title_wnd]=1 + + ZSHU_TERM[title_tab]=term + ZSHU_TERM[title_wnd]=term +;; +cygwin | ansi ) + ZSHU_TERM[has_title_tab]=1 + ZSHU_TERM[has_title_wnd]=1 + + ZSHU_TERM[title_tab]=term + ZSHU_TERM[title_wnd]=term +;; +screen* | tmux* ) + ZSHU_TERM[has_title_tab]=1 + ZSHU_TERM[want_cwd]=1 + + ZSHU_TERM[title_tab]=mux +;; +* ) + if z-ti-test fsl tsl ; then + ZSHU_TERM[has_title_tab]=1 + ZSHU_TERM[want_cwd]=1 + + ZSHU_TERM[title_tab]=terminfo + fi +;; +esac + +z-term-title-tab() { + # [ "${ZSHU_TERM[has_title_tab]}" = 1 ] || return 1 + + case "${ZSHU_TERM[title_tab]:-}" in + term ) + print -Pn "\e]1;${1:q}\a" + ;; + mux ) + ## screen/tmux: hardstatus + print -Pn "\ek${1:q}\e\\" + ;; + terminfo ) + echoti tsl + print -Pn "$1" + echoti fsl + ;; + esac +} + +z-term-title-window() { + # [ "${ZSHU_TERM[has_title_wnd]}" = 1 ] || return 1 + + case "${ZSHU_TERM[title_wnd]:-}" in + term ) + print -Pn "\e]2;${1:q}\a" + ;; + esac +} + +z-term-title() { + ## if $2 is unset use $1 as default + ## if it is set and empty, leave it as is + : ${2=$1} + + z-term-title-tab "$1" + z-term-title-window "$2" +} + +z-term-cwd() { + [ "${ZSHU_TERM[want_cwd]}" = 1 ] || return 1 + + local host path + host=${HOST:-localhost} + path=${PWD} + + ## Konsole doesn't want ${host} + while : ; do + [ -n "${KONSOLE_DBUS_SERVICE}" ] || break + [ -n "${KONSOLE_DBUS_SESSION}" ] || break + [ -n "${KONSOLE_DBUS_WINDOW}" ] || break + [ -n "${KONSOLE_PROFILE_NAME}" ] || break + host= + break ; done + + printf "\e]7;file://%s%s\e\\" "${host}" "${path}" +} + +if autoload -Uz add-zsh-hook ; then + +ZSHU[term_title]=1 +z-term-title-enable() { ZSHU[term_title]=1 ; } +z-term-title-disable() { ZSHU[term_title]=0 ; } + +ZSHU[title_tab]='%15<..<%~%<<' +ZSHU[title_wnd]='%n@%m:%~' +__z_term_title_precmd() { + [ "${ZSHU[term_title]}" = 1 ] || return + z-term-title "${ZSHU[title_tab]}" "${ZSHU[title_wnd]}" +} +add-zsh-hook precmd __z_term_title_precmd + +ZSHU[term_cwd]=1 +z-term-cwd-enable() { ZSHU[term_cwd]=1 ; } +z-term-cwd-disable() { ZSHU[term_cwd]=0 ; } + +__z_term_cwd_precmd() { + [ "${ZSHU[term_cwd]}" = 1 ] || return + z-term-cwd +} +## "chpwd" doesn't always hook pwd changes +add-zsh-hook precmd __z_term_cwd_precmd + +else + +echo "current working directory and tab/window title handling is disabled due to missing hook support" >&2 + +z-term-title-enable() { __z_unsupported ; } +z-term-title-disable() { __z_unsupported ; } + +z-term-cwd-enable() { __z_unsupported ; } +z-term-cwd-disable() { __z_unsupported ; } + +fi diff --git a/.config/zsh/lib/title.zsh b/.config/zsh/lib/title.zsh deleted file mode 100644 index 69f6ade..0000000 --- a/.config/zsh/lib/title.zsh +++ /dev/null @@ -1,58 +0,0 @@ -#!/bin/zsh - -ZSHU[title_tab]='%15<..<%~%<<' -ZSHU[title_window]='%n@%m:%~' - -z-title-tab() { - emulate -L zsh - - case "${TERM}" in - cygwin | xterm* | putty* | rxvt* | konsole* | ansi | mlterm* | alacritty | st* ) - print -Pn "\e]1;${1:q}\a" - ;; - screen* | tmux* ) - ## hardstatus - print -Pn "\ek${1:q}\e\\" - ;; - * ) - z-ti-test fsl tsl || return - - echoti tsl - print -Pn "$1" - echoti fsl - ;; - esac -} - -z-title-window() { - emulate -L zsh - - case "${TERM}" in - cygwin | xterm* | putty* | rxvt* | konsole* | ansi | mlterm* | alacritty | st* ) - print -Pn "\e]2;${1:q}\a" - ;; - esac -} - -z-title() { - emulate -L zsh - - ## if $2 is unset use $1 as default - ## if it is set and empty, leave it as is - : ${2=$1} - - z-title-tab "$1" - z-title-window "$2" -} - -if autoload -Uz add-zsh-hook ; then - -__z_title_precmd() { - z-title "${ZSHU[title_tab]}" "${ZSHU[title_window]}" -} - -add-zsh-hook precmd __z_title_precmd - -else - echo "tab/window title handling is disabled due to missing hook support" >&2 -fi diff --git a/.config/zsh/opt.zsh b/.config/zsh/opt.zsh index 8b41feb..2351c9f 100644 --- a/.config/zsh/opt.zsh +++ b/.config/zsh/opt.zsh @@ -1,13 +1,6 @@ #!/bin/zsh -unsetopt err_exit -unsetopt err_return -unsetopt multios +unsetopt err_exit err_return multios -setopt bsd_echo -setopt interactive_comments -setopt long_list_jobs -setopt monitor -setopt prompt_subst -setopt zle +setopt bsd_echo interactive_comments long_list_jobs monitor prompt_subst zle # setopt magic_equal_subst diff --git a/.config/zsh/opt/completion.zsh b/.config/zsh/opt/completion.zsh index 60168da..04f8748 100644 --- a/.config/zsh/opt/completion.zsh +++ b/.config/zsh/opt/completion.zsh @@ -1,9 +1,5 @@ #!/bin/zsh -unsetopt flow_control -unsetopt menu_complete +unsetopt flow_control menu_complete -setopt always_to_end -setopt auto_menu -setopt complete_aliases -setopt complete_in_word +setopt always_to_end auto_menu complete_aliases complete_in_word diff --git a/.config/zsh/opt/directories.zsh b/.config/zsh/opt/directories.zsh index 0a9c3d7..89d9e86 100644 --- a/.config/zsh/opt/directories.zsh +++ b/.config/zsh/opt/directories.zsh @@ -1,7 +1,3 @@ #!/bin/zsh -setopt auto_cd -setopt auto_pushd -setopt cdable_vars -setopt pushd_ignore_dups -setopt pushd_minus +setopt auto_cd auto_pushd cdable_vars pushd_ignore_dups pushd_minus diff --git a/.config/zsh/opt/history.zsh b/.config/zsh/opt/history.zsh index df86c6d..d9a923c 100644 --- a/.config/zsh/opt/history.zsh +++ b/.config/zsh/opt/history.zsh @@ -1,11 +1,3 @@ #!/bin/zsh -setopt append_history -setopt extended_history -setopt hist_expire_dups_first -setopt hist_ignore_all_dups -setopt hist_ignore_dups -setopt hist_ignore_space -setopt hist_verify -setopt inc_append_history -setopt share_history +setopt append_history extended_history hist_expire_dups_first hist_ignore_all_dups hist_ignore_dups hist_ignore_space hist_verify inc_append_history share_history diff --git a/.config/zsh/rc.zsh b/.config/zsh/rc.zsh index b8ad564..fb3cfb8 100644 --- a/.config/zsh/rc.zsh +++ b/.config/zsh/rc.zsh @@ -1,28 +1,50 @@ #!/bin/zsh -typeset -Ua zshu_modules -zshu_modules+=( +typeset -a zshu_modules +## DEBUG module load order +# typeset -a zshu_m0 zshu_m1 +zshu_modules=( + clone + langinfo + parameter + sched + termcap + terminfo + watch + zpty + + zle + zleparameter + deltochar complete complist computil - datetime - langinfo - main - mathfunc - parameter - stat - system - terminfo - zle zutil + compctl ) for i ( ${zshu_modules} ) ; do - case "$i" in - */* ) ;; - * ) i="zsh/$i" ;; - esac + i="zsh/$i" + ## DEBUG module load order + # zshu_m0=( $(zmodload) ) + # if ((${zshu_m0[(Ie)${i}]})); then + # echo "# already loaded: $i" >&2 + # continue + # fi + zmodload "$i" + + ## DEBUG module load order + # zshu_m1=( $(zmodload) ) + # for k ( ${zshu_m1} ) ; do + # if [ "$k" = "$i" ] ; then continue ; fi + # if ((${zshu_m0[(Ie)${k}]})); then + # continue + # fi + # echo "# new module loaded (with $i): $k" >&2 + # done done unset i zshu_modules +## DEBUG module load order +# unset zshu_m0 zshu_m1 autoload -Uz +X colors && colors diff --git a/.config/zsh/rc/keyboard.zsh b/.config/zsh/rc/keyboard-base.zsh similarity index 90% rename from .config/zsh/rc/keyboard.zsh rename to .config/zsh/rc/keyboard-base.zsh index d5cf706..75cf9ff 100644 --- a/.config/zsh/rc/keyboard.zsh +++ b/.config/zsh/rc/keyboard-base.zsh @@ -4,10 +4,8 @@ typeset -A ZSHU_TI_KEYS typeset -A ZSHU_FB_KEYS if z-ti-test smkx rmkx ; then - zle-line-init() { emulate -L zsh ; echoti smkx ; } - zle-line-finish() { emulate -L zsh ; echoti rmkx ; } -# zle-line-init() { echoti smkx ; } -# zle-line-finish() { echoti rmkx ; } + zle-line-init() { echoti smkx ; } + zle-line-finish() { echoti rmkx ; } zle -N zle-line-init zle -N zle-line-finish fi @@ -87,7 +85,7 @@ z-bind () { case "${widget}" in /* ) widget=${widget:1} - emulate zsh -c "autoload -RUz ${widget}" + autoload -RUz "${widget}" zle -N "${widget}" ;; esac @@ -131,8 +129,3 @@ z-bind emacs viins vicmd -- Esc-w kill-region ## use emacs key bindings bindkey -e - -for i ( /usr/share/doc/fzf/examples/key-bindings.zsh ) ; do - [ -s "$i" ] || continue - source $i -done ; unset i diff --git a/.config/zsh/rc/keyboard-extras.zsh b/.config/zsh/rc/keyboard-extras.zsh new file mode 100644 index 0000000..5acb140 --- /dev/null +++ b/.config/zsh/rc/keyboard-extras.zsh @@ -0,0 +1,7 @@ +#!/bin/zsh + +## TODO: more fzf locations +for i ( /usr/share/doc/fzf/examples/key-bindings.zsh ) ; do + [ -s "$i" ] || continue + source $i +done ; unset i diff --git a/.config/zsh/rc/prompt.zsh b/.config/zsh/rc/prompt.zsh index a474cc9..58fc4e3 100644 --- a/.config/zsh/rc/prompt.zsh +++ b/.config/zsh/rc/prompt.zsh @@ -84,17 +84,25 @@ z-ps1() { return } - local k - for k ( "$1" "${1}L" ) ; do - (( ${+ZSHU_PS1[$k]} )) || continue + local k ; k=$1 + case "$k" in + [1-9] ) + (( ${+ZSHU_PS1[$k]} )) || k="${k}L" + ;; + [1-9][Ll] ) + (( ${+ZSHU_PS1[$k]} )) || k="${k%?}L" + ;; + esac + (( ${+ZSHU_PS1[$k]} )) || return 1 - ZSHU_PS[ps1]=$k - PS1=${ZSHU_PS1[$k]} - return - done - return 1 + ZSHU_PS[ps1]=$k + PS1=${ZSHU_PS1[$k]} } -z-ps1 3 -[ "${ZSHU_RUN[nested]}" = 1 ] && z-ps1 2 -[ "${ZSHU_RUN[nested1L]}" = 1 ] && z-ps1 1 +if [ "${ZSHU_RUN[nested1L]}" = 1 ] ; then + z-ps1 1 +elif [ "${ZSHU_RUN[nested]}" = 1 ] ; then + z-ps1 2 +else + z-ps1 3 +fi