mirror of
git://git.code.sf.net/p/zsh/code
synced 2025-09-04 10:41:11 +02:00
41472: introduce cleanup hooks default and restore special themes, and update documentation
This commit is contained in:
parent
32ca9222af
commit
43e55a9bcd
6 changed files with 186 additions and 38 deletions
|
@ -1920,8 +1920,9 @@ subsect(Installation)
|
|||
You should make sure all the functions from the tt(Functions/Prompts)
|
||||
directory of the source distribution are available; they all begin with
|
||||
the string `tt(prompt_)' except for the special function`tt(promptinit)'.
|
||||
You also need the `tt(colors)' function from tt(Functions/Misc). All of
|
||||
these functions may already have been installed on your system; if not,
|
||||
You also need the `tt(colors)' and `tt(add-zsh-hook)' functions from
|
||||
tt(Functions/Misc).
|
||||
All these functions may already be installed on your system; if not,
|
||||
you will need to find them and copy them. The directory should appear as
|
||||
one of the elements of the tt(fpath) array (this should already be the
|
||||
case if they were installed), and at least the function tt(promptinit)
|
||||
|
@ -1975,6 +1976,75 @@ normally call a theme's setup function directly.
|
|||
)
|
||||
enditem()
|
||||
|
||||
subsect(Utility Themes)
|
||||
|
||||
startitem()
|
||||
item(tt(prompt off))(
|
||||
The theme `tt(off)' sets all the prompt variables to minimal values with
|
||||
no special effects.
|
||||
)
|
||||
item(tt(prompt default))(
|
||||
The theme `tt(default)' sets all prompt variables to the same state as
|
||||
if an interactive zsh was started with no initialization files.
|
||||
)
|
||||
item(tt(prompt restore))(
|
||||
The special theme `tt(restore)' erases all theme settings and sets prompt
|
||||
variables to their state before the first time the `tt(prompt)' function
|
||||
was run, provided each theme has properly defined its cleanup (see below).
|
||||
|
||||
Note that you can undo `tt(prompt off)' and `tt(prompt default)' with
|
||||
`tt(prompt restore)', but a second restore does not undo the first.
|
||||
)
|
||||
enditem()
|
||||
|
||||
subsect(Writing Themes)
|
||||
|
||||
The first step for adding your own theme is to choose a name for it,
|
||||
and create a file `tt(prompt_var(name)_setup)' in a directory in your
|
||||
tt(fpath), such as tt(~/myfns) in the example above. The file should
|
||||
at minimum contain assignments for the prompt variables that your
|
||||
theme wishes to modify. By convention, themes use tt(PS1), tt(PS2),
|
||||
tt(RPS1), etc., rather than the longer tt(PROMPT) and tt(RPROMPT).
|
||||
|
||||
The file is autoloaded as a function in the current shell context, so
|
||||
it may contain any necessary commands to customize your theme, including
|
||||
defining additional functions. To make some complex tasks easier, your
|
||||
setup function may also do any of the following:
|
||||
|
||||
startitem()
|
||||
item(Assign tt(prompt_opts))(
|
||||
The array tt(prompt_opts) may be assigned any of tt("bang"), tt("cr"),
|
||||
tt("percent"), tt("sp"), and/or tt("subst") as values. The corresponding
|
||||
setopts (tt(promptbang), etc.) are turned on, all other prompt-related
|
||||
options are turned off. The tt(prompt_opts) array preserves setopts even
|
||||
beyond the scope of tt(localoptions), should your function need that.
|
||||
)
|
||||
item(Modify precmd and preexec)(
|
||||
Use of tt(add-zsh-hook) is recommended. The tt(precmd) and tt(preexec)
|
||||
hooks are automatically adjusted if the prompt theme changes or is
|
||||
disabled.
|
||||
)
|
||||
item(Declare cleanup)(
|
||||
If your function makes any other changes that should be undone when the
|
||||
theme is disabled, your setup function may call
|
||||
example(prompt_cleanup var(command))
|
||||
where var(command) should be suitably quoted. If your theme is ever
|
||||
disabled or replaced by another, var(command) is executed with tt(eval).
|
||||
You may declare more than one such cleanup hook.
|
||||
)
|
||||
item(Define preview)(
|
||||
Define or autoload a function tt(prompt_var(name)_preview) to display
|
||||
a simulated version of your prompt. A simple default previewer is
|
||||
defined by tt(promptinit) for themes that do not define their own.
|
||||
This preview function is called by `tt(prompt -p)'.
|
||||
)
|
||||
item(Provide help)(
|
||||
Define or autoload a function tt(prompt_var(name)_help) to display
|
||||
documentation or help text for your theme.
|
||||
This help function is called by `tt(prompt -h)'.
|
||||
)
|
||||
enditem()
|
||||
|
||||
texinode(ZLE Functions)(Exception Handling)(Prompt Themes)(User Contributions)
|
||||
sect(ZLE Functions)
|
||||
|
||||
|
|
|
@ -16,9 +16,13 @@ prompt_bart_help () {
|
|||
blue, and the default foreground) are used if no arguments are
|
||||
given. The defaults look best on a light background.
|
||||
|
||||
The "off" token temporarily disables the theme; "on" restores it.
|
||||
No background colors or hardwired cursor motion escapes are used,
|
||||
and it is not necessary to setopt promptsubst.
|
||||
|
||||
The "off" token temporarily disables the theme; "on" restores it.
|
||||
Note, this does NOT fully reset to the original prompt state, it
|
||||
only hides/reveals the extra lines above the command line and
|
||||
removes the supporting hooks.
|
||||
EOF
|
||||
[[ $(read -sek 1 "?${(%):-%S[press return]%s}") == [Qq] ]] &&
|
||||
print -nP '\r%E' && return
|
||||
|
@ -183,7 +187,7 @@ prompt_bart_setup () {
|
|||
add-zsh-hook -D preexec "prompt_*_preexec"
|
||||
functions[TRAPWINCH]="${functions[TRAPWINCH]//prompt_bart_winch}"
|
||||
[[ $prompt_theme[1] = bart ]] && PS1=${${(f)PS1}[-1]}
|
||||
return 1
|
||||
return 1 # Prevent change of $prompt_theme
|
||||
;;
|
||||
(on|enable)
|
||||
shift
|
||||
|
@ -224,6 +228,8 @@ prompt_bart_setup () {
|
|||
|
||||
add-zsh-hook precmd prompt_bart_precmd
|
||||
add-zsh-hook preexec prompt_bart_preexec
|
||||
prompt_cleanup \
|
||||
'functions[TRAPWINCH]="${functions[TRAPWINCH]//prompt_bart_winch}"'
|
||||
functions[TRAPWINCH]="${functions[TRAPWINCH]//prompt_bart_winch}
|
||||
prompt_bart_winch"
|
||||
|
||||
|
|
7
Functions/Prompts/prompt_default_setup
Normal file
7
Functions/Prompts/prompt_default_setup
Normal file
|
@ -0,0 +1,7 @@
|
|||
PS1='%m%# '
|
||||
PS2='%_> '
|
||||
PS3='?# '
|
||||
PS4='+%N:%i> '
|
||||
unset RPS1 RPS2 RPROMPT RPROMPT2
|
||||
|
||||
prompt_opts=( cr percent sp )
|
|
@ -1,9 +1,10 @@
|
|||
# Very simple prompt
|
||||
prompt_off_setup () {
|
||||
PS1="%# "
|
||||
PS2="> "
|
||||
|
||||
prompt_opts=( cr percent )
|
||||
}
|
||||
prompt_default_setup 2>/dev/null
|
||||
|
||||
prompt_off_setup "$@"
|
||||
PS1="%# "
|
||||
PS2="> "
|
||||
PS3='?# '
|
||||
PS4='+> '
|
||||
|
||||
prompt_opts=( cr percent sp )
|
||||
|
|
2
Functions/Prompts/prompt_restore_setup
Normal file
2
Functions/Prompts/prompt_restore_setup
Normal file
|
@ -0,0 +1,2 @@
|
|||
# Damn that was easy
|
||||
zstyle -t :prompt-theme cleanup
|
|
@ -47,20 +47,36 @@ prompt_preview_safely() {
|
|||
return
|
||||
fi
|
||||
|
||||
local -a psv; psv=($psvar); local -a +h psvar; psvar=($psv) # Ick
|
||||
local +h PS1=$PS1 PS2=$PS2 PS3=$PS3 PS4=$PS4 RPS1=$RPS1
|
||||
local -a precmd_functions preexec_functions
|
||||
# This handles all the stuff from the default :prompt-theme cleanup
|
||||
local +h PS1=$PS1 PS2=$PS2 PS3=$PS3 PS4=$PS4 RPS1=$RPS1 RPS2=$RPS2
|
||||
local +h PROMPT=$PROMPT RPROMPT=$RPOMPT RPROMPT2=$RPROMPT2 PSVAR=$PSVAR
|
||||
local -a precmd_functions preexec_functions prompt_preview_cleanup
|
||||
local -aLl +h zle_highlight
|
||||
|
||||
# The next line is a bit ugly. It (perhaps unnecessarily)
|
||||
# runs the prompt theme setup function to ensure that if
|
||||
# the theme has a _preview function that it's been autoloaded.
|
||||
prompt_${1}_setup
|
||||
{
|
||||
# Save and clear current restore-point if any
|
||||
zstyle -g prompt_preview_cleanup :prompt-theme cleanup
|
||||
{
|
||||
zstyle -d :prompt-theme cleanup
|
||||
|
||||
if typeset +f prompt_${1}_preview >&/dev/null; then
|
||||
prompt_${1}_preview "$@[2,-1]"
|
||||
else
|
||||
prompt_preview_theme "$@"
|
||||
fi
|
||||
# The next line is a bit ugly. It (perhaps unnecessarily)
|
||||
# runs the prompt theme setup function to ensure that if
|
||||
# the theme has a _preview function that it's been autoloaded.
|
||||
prompt_${1}_setup
|
||||
|
||||
if typeset +f prompt_${1}_preview >&/dev/null; then
|
||||
prompt_${1}_preview "$@[2,-1]"
|
||||
else
|
||||
prompt_preview_theme "$@"
|
||||
fi
|
||||
} always {
|
||||
# Run any theme-specific cleanup, then reset restore point
|
||||
zstyle -t :prompt-theme cleanup
|
||||
}
|
||||
} always {
|
||||
(( $#prompt_preview_cleanup )) &&
|
||||
zstyle -e :prompt-theme cleanup "${prompt_preview_cleanup[@]}"
|
||||
}
|
||||
}
|
||||
|
||||
set_prompt() {
|
||||
|
@ -84,9 +100,9 @@ Use prompt -h <theme> for help on specific themes.'
|
|||
setopt localtraps
|
||||
if [[ -z "$prompt_theme[1]" ]]; then
|
||||
# Not using a prompt theme; save settings
|
||||
local -a psv; psv=($psvar); local -a +h psvar; psvar=($psv) # Ick
|
||||
local +h PS1=$PS1 PS2=$PS2 PS3=$PS3 PS4=$PS4 RPS1=$RPS1
|
||||
local precmd_functions preexec_functions
|
||||
local +h PS1=$PS1 PS2=$PS2 PS3=$PS3 PS4=$PS4 RPS1=$RPS1 RPS2=$RPS2
|
||||
local +h PROMPT=$PROMPT RPROMPT=$RPOMPT RPROMPT2=$RPROMPT2 PSVAR=$PSVAR
|
||||
local -a precmd_functions preexec_functions
|
||||
else
|
||||
trap 'prompt_${prompt_theme[1]}_setup "${(@)prompt_theme[2,-1]}"' 0
|
||||
fi
|
||||
|
@ -104,11 +120,11 @@ Use prompt -h <theme> for help on specific themes.'
|
|||
;;
|
||||
h) if [[ -n "$2" && -n $prompt_themes[(r)$2] ]]; then
|
||||
if functions prompt_$2_setup >/dev/null; then
|
||||
# The next line is a bit ugly. It (perhaps unnecessarily)
|
||||
# runs the prompt theme setup function to ensure that if
|
||||
# the theme has a _help function that it's been autoloaded.
|
||||
prompt_$2_setup
|
||||
fi
|
||||
# The next line is a bit ugly. It (perhaps unnecessarily)
|
||||
# runs the prompt theme setup function to ensure that if
|
||||
# the theme has a _help function that it's been autoloaded.
|
||||
prompt_$2_setup
|
||||
fi
|
||||
if functions prompt_$2_help >/dev/null; then
|
||||
print "Help for $2 theme:\n"
|
||||
prompt_$2_help
|
||||
|
@ -168,28 +184,74 @@ Use prompt -h <theme> for help on specific themes.'
|
|||
esac
|
||||
}
|
||||
|
||||
prompt () {
|
||||
local prompt_opts
|
||||
prompt_cleanup () {
|
||||
local -a cleanup_hooks
|
||||
if zstyle -g cleanup_hooks :prompt-theme cleanup
|
||||
then
|
||||
cleanup_hooks+=(';' "$@")
|
||||
zstyle -e :prompt-theme cleanup "${cleanup_hooks[@]}"
|
||||
elif (( $+prompt_preview_cleanup == 0 ))
|
||||
then
|
||||
print -u2 "prompt_cleanup: no prompt theme active"
|
||||
return 1
|
||||
fi
|
||||
}
|
||||
|
||||
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)'
|
||||
}
|
||||
set_prompt "$@"
|
||||
|
||||
(( $#prompt_opts )) &&
|
||||
setopt noprompt{bang,cr,percent,subst} "prompt${^prompt_opts[@]}"
|
||||
(( ${#prompt_opts} )) &&
|
||||
setopt noprompt{bang,cr,percent,sp,subst} "prompt${^prompt_opts[@]}"
|
||||
|
||||
true
|
||||
}
|
||||
|
||||
prompt_preview_theme () {
|
||||
emulate -L zsh
|
||||
local -a psv; psv=($psvar); local -a +h psvar; psvar=($psv) # Ick
|
||||
local +h PS1=$PS1 PS2=$PS2 PS3=$PS3 PS4=$PS4 RPS1=$RPS1
|
||||
local precmd_functions preexec_functions prompt_opts
|
||||
local -aLl +h zle_highlight
|
||||
|
||||
# Check for proper state handling
|
||||
(( $+prompt_preview_cleanup )) || {
|
||||
prompt_preview_safely "$@"
|
||||
return
|
||||
}
|
||||
|
||||
# Minimal preview for prompts that don't supply one
|
||||
local -a prompt_opts
|
||||
print -n "$1 theme"
|
||||
(( $#* > 1 )) && print -n " with parameters \`$*[2,-1]'"
|
||||
print ":"
|
||||
prompt_${1}_setup "$@[2,-1]"
|
||||
(( ${#prompt_opts} )) &&
|
||||
setopt noprompt{bang,cr,percent,sp,subst} "prompt${^prompt_opts[@]}"
|
||||
[[ -n ${precmd_functions[(r)prompt_${1}_precmd]} ]] &&
|
||||
prompt_${1}_precmd
|
||||
[[ -o promptcr ]] && print -n $'\r'; :
|
||||
|
|
Loading…
Reference in a new issue