From 4877b8d8f0fd312be08bf10a8ec4f2ac7b7c952b Mon Sep 17 00:00:00 2001 From: Mark Wooding Date: Tue, 21 Apr 2020 12:54:55 +0100 Subject: [PATCH] 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. --- dot/bashrc | 31 +++++++++++++++++++++------- dot/shell-rc | 66 +++++++++++++++++++++++++++++++++++++++++++++++++++--------- dot/zshrc | 24 ++++++++++++++++++++-- 3 files changed, 102 insertions(+), 19 deletions(-) diff --git a/dot/bashrc b/dot/bashrc index 9e872f5..18a2d7d 100644 --- a/dot/bashrc +++ b/dot/bashrc @@ -11,6 +11,30 @@ case ${__mdw_bashrc+t} in *) __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. . "$HOME/.shell-rc" @@ -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 @@ -15,6 +15,50 @@ __mdw_source_if_exists () { } ###-------------------------------------------------------------------------- +### 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. __mdw_set_prompt_hacks () { host=$(hostname); dir=""; } @@ -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 @@ -15,10 +15,32 @@ 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 ###-------------------------------------------------------------------------- -- 2.11.0