From: Mark Wooding Date: Tue, 21 Apr 2020 11:54:55 +0000 (+0100) Subject: dot/shell-rc, dot/bashrc, dot/zshrc: Introduce a formal notion of hooks. X-Git-Url: http://www.chiark.greenend.org.uk/ucgi/~mdw/git/profile/commitdiff_plain/4877b8d8f0fd312be08bf10a8ec4f2ac7b7c952b dot/shell-rc, dot/bashrc, dot/zshrc: Introduce a formal notion of hooks. Replace the `__mdw_precmd' and `__mdw_preexec' functions with hooks. Each shell implementation is responsible for calling the hooks at the right time, but the common core is responsible for maintaining the hooks and doing the job of invoking the hook functions. Use this machinery for the prompt setting and `screen' status things. --- diff --git a/dot/bashrc b/dot/bashrc index 9e872f5..18a2d7d 100644 --- a/dot/bashrc +++ b/dot/bashrc @@ -10,6 +10,30 @@ case ${__mdw_bashrc+t} in t) ;; *) __mdw_bashrc=t +###-------------------------------------------------------------------------- +### Hook implementation. + +__mdw_precmd_hook= __mdw_preexec_hook= +__mdw_running=t + +__mdw_run_precmd_hook () { + __mdw_running=nil + __mdw_runhook __mdw_precmd_hook "$@" +} +__mdw_run_preexec_hook () { + case $__mdw_running in + t) ;; + nil) + __mdw_running=t; + set -- $(history 1); shift + __mdw_runhook __mdw_preexec_hook "$*" + ;; + esac +} + +PROMPT_COMMAND=__mdw_run_precmd_hook +trap __mdw_run_preexec_hook DEBUG + ###-------------------------------------------------------------------------- ### Common shell configuration. @@ -46,18 +70,11 @@ __mdw_set_prompt_hacks () { host='\h' dir=' \w' } -__mdw_before_cmd_hack () { - set -- $(history 1); shift - __mdw_preexec "$*" -} - ## Only bother if the shell is interactive. if [ -t 0 ]; then PROMPT_DIRTRIM=5 __mdw_source_if_exists /usr/lib/git-core/git-sh-prompt __mdw_set_prompt_pieces - PROMPT_COMMAND=__mdw_precmd - PS0="\$(__mdw_before_cmd_hack)" fi ###-------------------------------------------------------------------------- diff --git a/dot/shell-rc b/dot/shell-rc index 940f91b..582b94d 100644 --- a/dot/shell-rc +++ b/dot/shell-rc @@ -14,6 +14,50 @@ __mdw_source_if_exists () { done } +###-------------------------------------------------------------------------- +### Hooks. + +__mdw_addhook () { + local hk=$1 fn=$2 t + + eval t=\${$hk+t} + case $t in t) ;; *) echo >&2 "unknown hook \`$hk'"; return 2; esac + + eval t=\$$hk + case " $t " in + *" $fn "*) ;; + *) eval "$hk=\${$hk:+\$$hk }\$fn" ;; + esac +} + +__mdw_delhook () { + local hk=$1 fn=$2 t l r + + eval t=\${$hk+t} + case $t in t) ;; *) echo >&2 "unknown hook \`$hk'"; return 2; esac + + eval t=\" \$$hk \" + case $t in + *" $fn "*) + l=${t%% $fn*} r=${t##*$fn } + l=${l# } r=${r% } + eval "$hk=\$l\${l:+ }\$r" + ;; + esac +} + +__mdw_setrc () { return $1; } + +__mdw_runhook () { + local hk=$1 saverc=$? t i; shift + + eval t=\${$hk+t} + case $t in t) ;; *) echo >&2 "unknown hook \`$hk'"; return 2; esac + + eval t=\$$hk + for i in $t; do __mdw_setrc $saverc; "$i" "$@"; done +} + ###-------------------------------------------------------------------------- ### Prompt machinery. @@ -101,18 +145,20 @@ __mdw_set_prompt () { esac } -__mdw_precmd () { - __mdw_set_prompt - case ${STY+t} in - t) printf "k%s\\" "$__mdw_shell" ;; - esac -} +__mdw_screen_precmd () { printf "k%s\\" "$__mdw_shell"; } +__mdw_screen_preexec () { printf "k%s\\" "$1"; } -__mdw_preexec () { - case ${STY+t} in - t) printf "k%s\\" "$1" ;; +if [ -t 0 ]; then + case ${STY+t},${__mdw_precmd_hook+t},${__mdw_preexec_hook+t} in + t,t,t) + __mdw_addhook __mdw_precmd_hook __mdw_screen_precmd + __mdw_addhook __mdw_preexec_hook __mdw_screen_preexec + ;; esac -} + case ${__mdw_precmd_hook+t} in + t) __mdw_addhook __mdw_precmd_hook __mdw_set_prompt ;; + esac +fi ###-------------------------------------------------------------------------- ### Some handy aliases. diff --git a/dot/zshrc b/dot/zshrc index c6cfa99..62766c0 100644 --- a/dot/zshrc +++ b/dot/zshrc @@ -14,11 +14,33 @@ HISTFILE=~/.zsh-history HISTSIZE=1000 SAVEHIST=1000 +###-------------------------------------------------------------------------- +### Hook implementation. + +__mdw_precmd_hook= __mdw_preexec_hook= + +__mdw_run_precmd_hook () { __mdw_runhook __mdw_precmd_hook "$@"; } +__mdw_run_preexec_hook () { __mdw_runhook __mdw_preexec_hook "$@"; } + +precmd_functions+=(__mdw_run_precmd_hook) +preexec_functions+=(__mdw_run_preexec_hook) + ###-------------------------------------------------------------------------- ### Common shell configuration. . "$HOME/.shell-rc" +## Fixup: `zsh' has sane quoting rules. +__mdw_runhook () { + local hk=$1 saverc=$? t i; shift + + eval t=\${$hk+t} + case $t in t) ;; *) echo >&2 "unknown hook \`$hk'"; return 2; esac + + eval t=\$$hk + for i in ${=t}; do __mdw_setrc $saverc; "$i" "$@"; done +} + ###-------------------------------------------------------------------------- ### Prompt hacking. @@ -36,8 +58,6 @@ __mdw_set_prompt_hacks () { if [ -t 0 ]; then __mdw_source_if_exists /usr/lib/git-core/git-sh-prompt __mdw_set_prompt_pieces - precmd_functions+=(__mdw_precmd) - preexec_functions+=(__mdw_preexec) fi ###--------------------------------------------------------------------------