diff --git a/.config/zsh/_.zsh b/.config/zsh/_.zsh index 8931740..574c653 100644 --- a/.config/zsh/_.zsh +++ b/.config/zsh/_.zsh @@ -20,7 +20,7 @@ for i ( d_zdot d_cache d_conf d_bin d_var ) ; do done ; unset i d ## early escape -unsetopt GLOBAL_RCS +unsetopt global_rcs ## safety measure: ## redirect all following activity within ZDOTDIR to cache @@ -56,4 +56,4 @@ ZSHU[t_end]=${(%):-%D{%s.%6.}} ZSHU[t_load]=$(( ZSHU[t_end] - ZSHU[t_begin] )) ZSHU[t_load]=${ZSHU[t_load]:0:6} -unset "ZSHU[t_begin]" "ZSHU[t_end]" +unset 'ZSHU[t_begin]' 'ZSHU[t_end]' diff --git a/.config/zsh/lib/cmdtime.zsh b/.config/zsh/lib/cmdtime.zsh index 0b9f335..db52fcc 100644 --- a/.config/zsh/lib/cmdtime.zsh +++ b/.config/zsh/lib/cmdtime.zsh @@ -1,54 +1,53 @@ #!/bin/zsh z-time() { - local a b elapsed result + local a r a=${EPOCHREALTIME} - "$@" - result=$? - b=$(( EPOCHREALTIME - a )) - elapsed=$(z-ts-to-human "$b" 6) - echo 1>&2 - echo "time took: ${elapsed}" 1>&2 + "$@" ; r=$? + a=$(( EPOCHREALTIME - a )) + a=$(z-ts-to-human "$a" 6) + echo >&2 + echo "time took: $a" >&2 - return ${result} + return $r } if autoload -Uz add-zsh-hook ; then typeset -gA ZSHU_PS -ZSHU_PS[cmd_threshold]=3 +ZSHU_PS[cmd_threshold]=1 -__z_cmdtime_precmd() { - local t x elapsed +__z_cmdtime_measure() { + local t x - t=${EPOCHREALTIME} -# t=${(%):-%D{%s.%9.}} + x=${EPOCHREALTIME} - ZSHU_PS[elapsed]='' - (( ${+ZSHU_PS[cmd_ts]} )) || return + unset 'ZSHU[cmd_dt]' 'ZSHU_PS[elapsed]' + (( ${+ZSHU[cmd_ts]} )) || return - t=$(( t - ${ZSHU_PS[cmd_ts]} )) - unset "ZSHU_PS[cmd_ts]" + t=$(( x - ${ZSHU[cmd_ts]} )) + ZSHU[cmd_ts]=$x - x=$(( ${ZSHU_PS[cmd_threshold]} + 0 )) - [ "$x" = '0' ] && return + x=${ZSHU_PS[cmd_threshold]} + x=$(( x + 0 )) || x=0 + [ "$x" = 0 ] && return x=$(( t - x )) [ "${x:0:1}" = '-' ] && return - elapsed=$(z-ts-to-human "$t") - ZSHU_PS[elapsed]=" %f[%B%F{yellow}+${elapsed}%b%f] " + t=$(z-ts-to-human "$t") + ZSHU[cmd_dt]=$t + ZSHU_PS[elapsed]=" %f[%B%F{yellow}+$t%b%f]" } -__z_cmdtime_preexec() { - ZSHU_PS[cmd_ts]=${EPOCHREALTIME} -# ZSHU_PS[cmd_ts]=${(%):-%D{%s.%9.}} +__z_cmdtime_set() { + ZSHU[cmd_ts]=${EPOCHREALTIME} } -add-zsh-hook precmd __z_cmdtime_precmd -add-zsh-hook preexec __z_cmdtime_preexec +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" 1>&2 + echo "cmd time measurement is disabled due to missing hook support" >&2 fi diff --git a/.config/zsh/lib/completion.zsh b/.config/zsh/lib/completion.zsh index 22870b3..1e35bf8 100644 --- a/.config/zsh/lib/completion.zsh +++ b/.config/zsh/lib/completion.zsh @@ -17,7 +17,7 @@ __z_compdump_invalidate() { __z_compdump_verify() { local i s - unset "ZSHU[compdump_refresh]" + unset 'ZSHU[compdump_refresh]' ZSHU[compdump_meta]='ZSH_VERSION ZSH_PATCHLEVEL FPATH PATH' for i ( ${(s: :)ZSHU[compdump_meta]} ) ; do s=$(__z_compdump_print "$i") @@ -37,9 +37,9 @@ __z_compdump_finalize() { __z_compdump_print "$i" done } | tee -a "${ZSHU[f_compdump]}" &>/dev/null - unset "ZSHU[compdump_refresh]" + unset 'ZSHU[compdump_refresh]' fi - unset "ZSHU[compdump_meta]" + unset 'ZSHU[compdump_meta]' } __z_comp_bash() { diff --git a/.config/zsh/lib/git.zsh b/.config/zsh/lib/git.zsh index eed6c81..cc34a40 100644 --- a/.config/zsh/lib/git.zsh +++ b/.config/zsh/lib/git.zsh @@ -1,8 +1,12 @@ #!/bin/zsh ## fancy and manageable PS1 for git -typeset -gA ZSHU_PS +typeset -gA ZSHU_GIT ZSHU_PM ZSHU_PS ZSHU_PS[git]=0 +ZSHU_PM[git_branch]='🞷' +ZSHU_PM[git_detach]='☈' +ZSHU_PM[git_tag]='🗹' +ZSHU_PM[git_commit]='⌽' __z_git_avail() { (( $+commands[git] )) ; } @@ -10,6 +14,8 @@ __z_git() { GIT_OPTIONAL_LOCKS=0 command git "$@"; } __z_git_is_repo() { __z_git rev-parse --git-dir &>/dev/null ; } +__z_git_desc_tag() { __z_git describe --tags "$@" ; } + z-git-test() { [ "${ZSHU_PS[git]}" = '1' ] || return 1 @@ -21,24 +27,93 @@ z-git-test() { } __z_git_pwd() { - local p s last pfx + local x + + unset 'ZSHU_PS[git_ref]' 'ZSHU_PS[git_tag]' + unset 'ZSHU_GIT[path_root]' 'ZSHU_GIT[path_mid]' 'ZSHU_GIT[path_last]' + unset 'ZSHU_GIT[commit]' 'ZSHU_GIT[detached]' 'ZSHU_GIT[ref]' 'ZSHU_GIT[tag]' z-git-test || return - p=${(%):-%~} - [[ "$p" =~ '/.+' ]] || return - s=$(__z_git rev-parse --show-prefix) - s="${s%%/}" - if [ -n "$s" ] ; then - p=${p%%/$s} - last="${s:t}" - pfx="${s%${last}}" + x=$(__z_git rev-parse --short HEAD 2>/dev/null) + [ -n "$x" ] || return + ZSHU_GIT[commit]=$x + + ## git ref + while : ; do + ZSHU_GIT[detached]=1 + x=$(__z_git symbolic-ref --short HEAD 2>/dev/null) + if [ -n "$x" ] ; then + ZSHU_GIT[detached]=0 + ZSHU_GIT[ref]=$x + ZSHU_PS[git_ref]="%F{green}%B${ZSHU_PM[git_branch]}%b ${ZSHU_GIT[ref]}%f" + break + fi + + x=$(__z_git for-each-ref --format='%(refname)' --count=1 --points-at=${ZSHU_GIT[commit]} refs/heads/ refs/remotes/) + if [ -n "$x" ] ; then + ZSHU_GIT[detached]=0 + ZSHU_GIT[ref]=${x#refs/*/} + ZSHU_PS[git_ref]="%F{yellow}%B${ZSHU_PM[git_branch]}%b ${ZSHU_GIT[ref]}%f" + break + fi + + ZSHU_GIT[ref]=${ZSHU_GIT[commit]} + ZSHU_PS[git_ref]="%F{red}%B${ZSHU_PM[git_detach]}%b ${ZSHU_GIT[ref]}%f" + + break + done + + ## git tag + while [ ${ZSHU_GIT[detached]} = 1 ] ; do + x=$(__z_git_desc_tag --exact-match HEAD 2>/dev/null) + if [ -n "$x" ] ; then + ZSHU_GIT[tag]=$x + ZSHU_PS[git_tag]="%F{green}%B${ZSHU_PM[git_tag]}%b ${ZSHU_GIT[tag]}%f" + break + fi + + x=$(__z_git_desc_tag HEAD 2>/dev/null) + if [ -n "$x" ] ; then + ZSHU_GIT[tag]=${x%-*} + ZSHU_PS[git_tag]="%F{yellow}%B${ZSHU_PM[git_commit]}%b ${ZSHU_GIT[tag]}%f" + break + fi + + break + done + + ## try to fancy split current path + while : ; do + x=${(%):-%~} + [[ "$x" =~ '/.+' ]] || break + + local pfx last mid + pfx=$(__z_git rev-parse --show-prefix) pfx="${pfx%/}" - pfx="/${pfx}${pfx:+/}" - else - last="/" - fi - ZSHU_PS[pwd]="%F{magenta}$p%F{cyan}${pfx}%B${last}%f%b" + if [ -n "${pfx}" ] ; then + x=${x%/${pfx}} + last="${pfx:t}" + mid="${pfx%${last}}" + mid="${mid%/}" + mid="/${mid}${mid:+/}" + + ZSHU_GIT[path_mid]=${mid} + ZSHU_GIT[path_last]=${last} + else + ZSHU_GIT[path_last]='/' + fi + break + done + ZSHU_GIT[path_root]=$x + + x="%F{magenta}${ZSHU_GIT[path_root]:gs/%/%%}" + x="$x%F{cyan}${ZSHU_GIT[path_mid]:gs/%/%%}" + x="$x%B${ZSHU_GIT[path_last]:gs/%/%%}%f%b" + ZSHU_PS[pwd]=$x + + x="${ZSHU_PS[git_tag]}" + ZSHU_PS[pwd_extra]=" ${ZSHU_PS[git_ref]}${x:+ }$x" } z-git-enable() { ZSHU_PS[git]=1 ; } diff --git a/.config/zsh/lib/prompt.zsh b/.config/zsh/lib/prompt.zsh index 6273230..84a646d 100644 --- a/.config/zsh/lib/prompt.zsh +++ b/.config/zsh/lib/prompt.zsh @@ -5,6 +5,8 @@ typeset -gA ZSHU_PM ZSHU_PS ZSHU_PM[rst]='%b%k%u%s%f' ZSHU_PM[crlf]=$'\n' +ZSHU_PS[shlvl]='%(2L.%B%F{white}|%F{cyan}%L%b%f.)' + ZSHU_PM[status]='▪' ZSHU_PS[lastcmd]="%B%(?.%F{green}.%F{red})${ZSHU_PM[status]}%f%b" @@ -34,8 +36,9 @@ __z_pwd() { __z_pwd_hook() { local i - unset "ZSHU_PS[pwd]" + unset 'ZSHU_PS[pwd]' for i ( ${(s: :)ZSHU[pwd_hook]} __z_pwd ) ; do + unset 'ZSHU_PS[pwd_extra]' "$i" (( ${+ZSHU_PS[pwd]} )) && return done @@ -44,5 +47,5 @@ __z_pwd_hook() { add-zsh-hook precmd __z_pwd_hook else - echo "shiny pwd's are disabled due to missing hook support" 1>&2 + echo "shiny pwd's are disabled due to missing hook support" >&2 fi diff --git a/.config/zsh/lib/pswalk.zsh b/.config/zsh/lib/pswalk.zsh index 65a3774..0aa8a00 100644 --- a/.config/zsh/lib/pswalk.zsh +++ b/.config/zsh/lib/pswalk.zsh @@ -4,10 +4,10 @@ typeset -Uga ZSHU_PARENTS_PID typeset -ga ZSHU_PARENTS_NAME function { - local i cmd + local i c i=$$ ; while : ; do - i=$(ps -o ppid= -p $i 2>/dev/null || : ) + i=$(ps -o ppid= -p $i 2>/dev/null) || : i=${i//[^0-9]} [[ "$i" =~ '^[1-9][0-9]*$' ]] || break ## don't deal with PID1 @@ -16,8 +16,9 @@ function { done for i ( ${ZSHU_PARENTS_PID} ) ; do - cmd=$(ps -o comm= -p $i 2>/dev/null || : ) - [ -n "${cmd}" ] && ZSHU_PARENTS_NAME+=( "${cmd##*/}" ) + c=$(ps -o comm= -p $i 2>/dev/null) || : + [ -n "$c" ] || continue + ZSHU_PARENTS_NAME+=( "${c##*/}" ) done typeset -r ZSHU_PARENTS_PID @@ -27,20 +28,19 @@ function { typeset -gA ZSHU_RUN z-run-test() { - local key v i + local k i - key=$1 ; shift - v=0 + k=$1 ; shift for i ( ${ZSHU_PARENTS_NAME} ) ; do - if (( ${+argv[(r)$i]} )) ; then - ZSHU_RUN[${key}]=1 - return - fi + (( ${+argv[(r)$i]} )) || continue + + ZSHU_RUN[$k]=1 + return done - ZSHU_RUN[${key}]=0 + ZSHU_RUN[$k]=0 } z-run-test gui konsole xterm x-terminal-emulator z-run-test nested screen tmux mc -z-run-test nested1 mc +z-run-test nested1L mc z-run-test elevated sudo su diff --git a/.config/zsh/lib/time.zsh b/.config/zsh/lib/time.zsh index b0636cb..9e1627e 100644 --- a/.config/zsh/lib/time.zsh +++ b/.config/zsh/lib/time.zsh @@ -1,11 +1,12 @@ #!/bin/zsh z-ts-to-human() { - local t s ns d h m f x + local t s n d h m f x t=$1 + t=$(( float(t) )) s=$(( int(t) )) - ns=$(( int((t - s) * (10**9)) )) + n=$(( int((t - s) * (10**9)) )) t=$s d=0 h=0 m=0 @@ -22,15 +23,13 @@ z-ts-to-human() { t=$(( t % 60 )) fi - f='%s.%6.' - f=$(strftime "$f" $t $ns) - - x=3 + ## strftime does desired rounding for $n/(10**9) internally + f=$(strftime '%s.%6.' $t $n) ## keep math in sync with format above + x=3 case "$2" in 0) x=7 ;; - [1-5]) x=$(( 6 - $2 )) ;; - 6) x=0 ;; + [1-6]) x=$(( 6 - $2 )) ;; esac [ $x -gt 0 ] && f="${f:0:-$x}s" diff --git a/.config/zsh/lib/title.zsh b/.config/zsh/lib/title.zsh index ab286ef..aac17ab 100644 --- a/.config/zsh/lib/title.zsh +++ b/.config/zsh/lib/title.zsh @@ -1,6 +1,5 @@ #!/bin/zsh -typeset -gA ZSHU ZSHU[title_tab]='%15<..<%~%<<' ZSHU[title_window]='%n@%m:%~' diff --git a/.config/zsh/rc/prompt.zsh b/.config/zsh/rc/prompt.zsh index ad8313b..4baf12f 100644 --- a/.config/zsh/rc/prompt.zsh +++ b/.config/zsh/rc/prompt.zsh @@ -1,6 +1,6 @@ #!/bin/zsh -# z-starship-init +typeset -gA ZSHU_PS1 ## three-line prompt function { @@ -13,7 +13,6 @@ function { line+='${ZSHU_PM[id]:+"%B%F{white}${ZSHU_PM[id]}${ZSHU_PM[rst]}%B%F{black}|%b%f"}' line+="${ZSHU_PM[user]}%F{white}@${ZSHU_PM[host]}" line+='${ZSHU_PS[elapsed]}' - line+='${ZSHU_PS[status_extra]}' line+="${ZSHU_PM[rst]}" line+="${ZSHU_PM[crlf]}" @@ -27,10 +26,11 @@ function { line+="%B%F{black}└[%f%b" line+="${ZSHU_PS[lastcmd]}" + line+='${ZSHU_PS[shlvl]}' line+="%B%F{black}|%b%f" line+="${ZSHU_PS[cmd]}" - ZSHU_PS[ps1_3L]="${(j::)line}" + ZSHU_PS1[3L]="${(j::)line}" } ## two-line prompt @@ -51,11 +51,11 @@ function { line+="%B%F{black}└[%f%b" line+="${ZSHU_PS[lastcmd]}" + line+='${ZSHU_PS[shlvl]}' line+="%B%F{black}|%b%f" - line+='${ZSHU_PS[status_extra]}' line+="${ZSHU_PS[cmd]}" - ZSHU_PS[ps1_2L]="${(j::)line}" + ZSHU_PS1[2L]="${(j::)line}" } ## one-line prompt @@ -64,6 +64,7 @@ function { line+="${ZSHU_PM[rst]}" line+="${ZSHU_PS[lastcmd]}" + line+='${ZSHU_PS[shlvl]}' line+="%B%F{black}|%b" line+="${ZSHU_PM[user]}" line+="%B%F{black}|%b" @@ -74,9 +75,26 @@ function { line+="%B%F{black}|%b" line+="${ZSHU_PS[cmd]}" - ZSHU_PS[ps1_1L]="${(j::)line}" + ZSHU_PS1[1L]="${(j::)line}" } -PS1=${ZSHU_PS[ps1_3L]} -[ "${ZSHU_RUN[nested]}" = 1 ] && PS1=${ZSHU_PS[ps1_2L]} -[ "${ZSHU_RUN[nested1]}" = 1 ] && PS1=${ZSHU_PS[ps1_1L]} +z-ps() { + [ -n "$1" ] || { + echo "${ZSHU_PS[ps1]}" + return + } + + local k + for k ( "$1" "${1}L" ) ; do + (( ${+ZSHU_PS1[$k]} )) || continue + + ZSHU_PS[ps1]=$k + PS1=${ZSHU_PS1[$k]} + return + done + return 1 +} + +z-ps 3 +[ "${ZSHU_RUN[nested]}" = 1 ] && z-ps 2 +[ "${ZSHU_RUN[nested1L]}" = 1 ] && z-ps 1