On Tue, Jul 07, 2020 at 01:50:04PM +0200, Roman Perepelitsa wrote: > The documentation for promptinit states that themes can install > cleanup hooks via prompt_cleanup. > > > If your function makes any other changes that should > > be undone when the theme is disabled, your setup function > > may call > > > > prompt_cleanup command > > > > where command should be suitably quoted. If your theme > > is ever disabled or replaced by another, command is > > executed with eval. > > The documentation also states that: > > > The precmd and preexec hooks are automatically > > adjusted if the prompt theme changes or is disabled. I understood that in terms of workers/30087: the theme "foo" may define prompt_foo_precmd and prompt_foo_preexec, which are removed from the respective arrays if the prompt theme is deactivated. It would probably make sense to do something like (( $+functions[prompt_$name_precmd] )) && [[ -n ${precmd_functions[(r)prompt_$name_precmd]} ]] && precmd_functions+=(prompt_$name_precmd) automatically on theme activation, though — to match the above. > > If I understand it correctly, this implies that the following script > should print "cleanup" and shouldn't print "hook". > > autoload -Uz promptinit > promptinit > prompt_foo_setup() { > prompt_cleanup 'print cleanup' > precmd_functions+=(hook) > } > prompt_themes+=(foo) > prompt foo Consider the following right here: precmd_functions+=(func1 func2) > prompt off > print -r -- $precmd_functions > > It doesn't print "cleanup" and does print "hook". As per what you suggest, user-supplied precmd functions, which were set after prompt theme activation — in that example func1 and func2 — will be unhooked as well. I doubt this is what users want. > > I'm attaching a patch that does what I believe the documentation > describes. I'm not very confident that I understood the documentation > or that my patch is correct. > > Roman. > diff --git a/Functions/Prompts/promptinit b/Functions/Prompts/promptinit > index e27b8779a..a9850d35c 100644 > --- a/Functions/Prompts/promptinit > +++ b/Functions/Prompts/promptinit > @@ -200,33 +200,37 @@ prompt_cleanup () { > prompt () { > local -a prompt_opts theme_active > > - zstyle -g theme_active :prompt-theme cleanup || { > - # This is done here rather than in set_prompt so that it > - # is safe and sane for set_prompt to setopt localoptions, > - # which will be cleared before we arrive back here again. > - # This is also why we pass around the prompt_opts array. > - [[ -o promptbang ]] && prompt_opts+=(bang) > - [[ -o promptcr ]] && prompt_opts+=(cr) > - [[ -o promptpercent ]] && prompt_opts+=(percent) > - [[ -o promptsp ]] && prompt_opts+=(sp) > - [[ -o promptsubst ]] && prompt_opts+=(subst) > - zstyle -e :prompt-theme cleanup \ > - 'zstyle -d :prompt-theme cleanup;' \ > - 'prompt_default_setup;' \ > - ${PS1+PS1="${(q)PS1}"} \ > - ${PS2+PS2="${(q)PS2}"} \ > - ${PS3+PS3="${(q)PS3}"} \ > - ${PS4+PS4="${(q)PS4}"} \ > - ${RPS1+RPS1="${(q)RPS1}"} \ > - ${RPS2+RPS2="${(q)RPS2}"} \ > - ${RPROMPT+RPROMPT="${(q)RPROMPT}"} \ > - ${RPROMPT2+RPROMPT2="${(q)RPROMPT2}"} \ > - ${PSVAR+PSVAR="${(q)PSVAR}"} \ > - "precmd_functions=(${(q)precmd_functions[@]})" \ > - "preexec_functions=(${(q)preexec_functions[@]})" \ > - "prompt_opts=( ${prompt_opts[*]} )" \ > - 'reply=(yes)' > + zstyle -g theme_active :prompt-theme cleanup && { > + local -a reply > + eval "$theme_active" Nit: `prompt restore' opts to call `zstyle -t :prompt-theme cleanup' to do this. > } > + > + # This is done here rather than in set_prompt so that it > + # is safe and sane for set_prompt to setopt localoptions, > + # which will be cleared before we arrive back here again. > + # This is also why we pass around the prompt_opts array. > + [[ -o promptbang ]] && prompt_opts+=(bang) > + [[ -o promptcr ]] && prompt_opts+=(cr) > + [[ -o promptpercent ]] && prompt_opts+=(percent) > + [[ -o promptsp ]] && prompt_opts+=(sp) > + [[ -o promptsubst ]] && prompt_opts+=(subst) > + zstyle -e :prompt-theme cleanup \ > + 'zstyle -d :prompt-theme cleanup;' \ > + 'prompt_default_setup;' \ > + ${PS1+PS1="${(q)PS1}"} \ > + ${PS2+PS2="${(q)PS2}"} \ > + ${PS3+PS3="${(q)PS3}"} \ > + ${PS4+PS4="${(q)PS4}"} \ > + ${RPS1+RPS1="${(q)RPS1}"} \ > + ${RPS2+RPS2="${(q)RPS2}"} \ > + ${RPROMPT+RPROMPT="${(q)RPROMPT}"} \ > + ${RPROMPT2+RPROMPT2="${(q)RPROMPT2}"} \ > + ${PSVAR+PSVAR="${(q)PSVAR}"} \ > + "precmd_functions=(${(q)precmd_functions[@]})" \ > + "preexec_functions=(${(q)preexec_functions[@]})" \ > + "prompt_opts=( ${prompt_opts[*]} )" \ > + 'reply=(yes)' > + > set_prompt "$@" > > (( ${#prompt_opts} )) &&