diff --git a/pure.zsh b/pure.zsh index beb71eb..e7cf07d 100644 --- a/pure.zsh +++ b/pure.zsh @@ -197,6 +197,14 @@ prompt_pure_preprompt_render() { psvar[21]="${node_symbol}${prompt_pure_node_version}" fi + # psvar[22]: Custom prefix, psvar[23]: Custom suffix. + # Set by the user-defined prompt_pure_precustom function. + psvar[22]= + psvar[23]= + if (( $+functions[prompt_pure_precustom] )); then + prompt_pure_precustom + fi + # Expand the prompt for future comparison. local expanded_prompt expanded_prompt="${(S%%)PROMPT}" @@ -941,7 +949,7 @@ prompt_pure_preview() { fi # Sample preprompt with all components visible. - print -P "%F{$c[suspended_jobs]}${PURE_SUSPENDED_JOBS_SYMBOL-✦}%f %F{$c[user]}zaphod%f${host_sample} ${path_sample} %F{$c[git:branch]}main%f%F{$c[git:dirty]}*+%f %F{$c[git:action]}rebase-i%f %F{$c[git:arrow]}${PURE_GIT_DOWN_ARROW:-⇣}${PURE_GIT_UP_ARROW:-⇡}%f %F{$c[git:stash]}${PURE_GIT_STASH_SYMBOL-≡}%f %F{$c[node_version]}${node_symbol}22%f %F{$c[execution_time]}42s%f" + print -P "%F{$c[custom:prefix]}prefix%f %F{$c[suspended_jobs]}${PURE_SUSPENDED_JOBS_SYMBOL-✦}%f %F{$c[user]}zaphod%f${host_sample} ${path_sample} %F{$c[git:branch]}main%f%F{$c[git:dirty]}*+%f %F{$c[git:action]}rebase-i%f %F{$c[git:arrow]}${PURE_GIT_DOWN_ARROW:-⇣}${PURE_GIT_UP_ARROW:-⇡}%f %F{$c[git:stash]}${PURE_GIT_STASH_SYMBOL-≡}%f %F{$c[node_version]}${node_symbol}22%f %F{$c[execution_time]}42s%f %F{$c[custom:suffix]}suffix%f" print -P "%F{$c[virtualenv]}venv%f %F{$c[prompt:success]}${PURE_PROMPT_SYMBOL:-❯}%f" print print -P "%F{$c[prompt:error]}${PURE_PROMPT_SYMBOL:-❯}%f prompt after error" @@ -984,6 +992,8 @@ prompt_pure_setup() { # Set the colors. typeset -gA prompt_pure_colors_default prompt_pure_colors prompt_pure_colors_default=( + custom:prefix 242 + custom:suffix 242 execution_time yellow git:arrow cyan git:stash cyan @@ -1038,13 +1048,16 @@ prompt_pure_setup() { # psvar[19] = exec time (e.g. 1d 3h 2m 5s) # psvar[20] = virtualenv/conda/nix-shell name # psvar[21] = Node.js version (e.g. ⬢22) + # psvar[22] = custom prefix (set by prompt_pure_precustom) + # psvar[23] = custom suffix (set by prompt_pure_precustom) # # Example output: - # ✦ user@host ~/Code/pure main*+ rebase ⇣⇡ ≡ ⬢22 3s + # prefix ✦ user@host ~/Code/pure main*+ rebase ⇣⇡ ≡ ⬢22 3s suffix # myenv ❯ # # Preprompt line: each %(NV..) section only renders when its psvar is non-empty. - PROMPT='%(12V.%F{$prompt_pure_colors[suspended_jobs]}%12v%f .)' + PROMPT='%(22V.%F{$prompt_pure_colors[custom:prefix]}%22v%f .)' + PROMPT+='%(12V.%F{$prompt_pure_colors[suspended_jobs]}%12v%f .)' local hostname_part='' if (( prompt_pure_state[show_host] )); then hostname_part='%F{$prompt_pure_colors[host]}@%m%f' @@ -1058,6 +1071,7 @@ prompt_pure_setup() { PROMPT+='%(18V. %F{$prompt_pure_colors[git:stash]}%18v%f.)' PROMPT+='%(21V. %F{$prompt_pure_colors[node_version]}%21v%f.)' PROMPT+='%(19V. %F{$prompt_pure_colors[execution_time]}%19v%f.)' + PROMPT+='%(23V. %F{$prompt_pure_colors[custom:suffix]}%23v%f.)' # Newline separating preprompt from prompt. PROMPT+='${prompt_newline}' diff --git a/readme.md b/readme.md index fbac6cb..2dce6ce 100644 --- a/readme.md +++ b/readme.md @@ -133,6 +133,38 @@ Automatic terminal title management can be disabled if you want to set your own `zstyle :prompt:pure:title show no` +## Customization + +Pure supports a hook function for adding custom content to the prompt. Define a function called `prompt_pure_precustom` in your `.zshrc` (after `prompt pure`) to set custom prefix and suffix segments on the preprompt line: + +- `psvar[22]` — Custom prefix, rendered before all built-in segments. +- `psvar[23]` — Custom suffix, rendered after all built-in segments. + +The function is called each time the prompt renders (including async redraws), so avoid slow commands. For expensive operations, cache the result in a `precmd` hook and read the cached value in `prompt_pure_precustom`. + +```sh +# .zshrc + +# Cache expensive calls in precmd (runs once per command, not on async redraws). +my_kube_context= +my_precmd() { + my_kube_context=$(kubectl config current-context 2>/dev/null) +} +add-zsh-hook precmd my_precmd + +prompt_pure_precustom() { + psvar[22]=$my_kube_context + psvar[23]=$(date +%H:%M) +} +``` + +The colors can be customized with `zstyle`: + +```sh +zstyle :prompt:pure:custom:prefix color cyan +zstyle :prompt:pure:custom:suffix color yellow +``` + ## Colors As explained in ZSH's [manual](http://zsh.sourceforge.net/Doc/Release/Zsh-Line-Editor.html#Character-Highlighting), color values can be: @@ -141,6 +173,8 @@ As explained in ZSH's [manual](http://zsh.sourceforge.net/Doc/Release/Zsh-Line-E - `#` followed by an RGB triplet in hexadecimal format, for example `#424242`. Only if your terminal supports 24-bit colors (true color) or when the [`zsh/nearcolor` module](http://zsh.sourceforge.net/Doc/Release/Zsh-Modules.html#The-zsh_002fnearcolor-Module) is loaded. Colors can be changed by using [`zstyle`](http://zsh.sourceforge.net/Doc/Release/Zsh-Modules.html#The-zsh_002fzutil-Module) with a pattern of the form `:prompt:pure:$color_name` and style `color`. The color names, their default, and what part they affect are: +- `custom:prefix` (242) - Custom prefix set via `prompt_pure_precustom`. +- `custom:suffix` (242) - Custom suffix set via `prompt_pure_precustom`. - `execution_time` (yellow) - The execution time of the last command when exceeding `PURE_CMD_MAX_EXEC_TIME`. - `git:arrow` (cyan) - For `PURE_GIT_UP_ARROW` and `PURE_GIT_DOWN_ARROW`. - `git:stash` (cyan) - For `PURE_GIT_STASH_SYMBOL`. @@ -162,22 +196,25 @@ Colors can be changed by using [`zstyle`](http://zsh.sourceforge.net/Doc/Release The following diagram shows where each color is applied on the prompt: ``` -┌────────────────────────────────────────────────────── user -│ ┌─────────────────────────────────────────────── host -│ │ ┌─────────────────────────────────── path -│ │ │ ┌──────────────────────── git:branch -│ │ │ │ ┌─────────────────────── git:dirty -│ │ │ │ │ ┌──────────────────── git:action -│ │ │ │ │ │ ┌─────────── git:arrow -│ │ │ │ │ │ │ ┌───────── git:stash -│ │ │ │ │ │ │ │ ┌─────── node_version -│ │ │ │ │ │ │ │ │ ┌── execution_time -│ │ │ │ │ │ │ │ │ │ -zaphod@heartofgold ~/dev/pure main*+ rebase-i ⇡ ≡ ⬢22 42s +┌──────────────────────────────────────────────────────────────────────── custom:prefix +│ ┌─────────────────────────────────────────────────────────────────── suspended_jobs +│ │ ┌───────────────────────────────────────────────────────────────── user +│ │ │ ┌────────────────────────────────────────────────────────── host +│ │ │ │ ┌────────────────────────────────────────────── path +│ │ │ │ │ ┌─────────────────────────────────── git:branch +│ │ │ │ │ │ ┌─────────────────────────────── git:dirty +│ │ │ │ │ │ │ ┌──────────────────────────── git:action +│ │ │ │ │ │ │ │ ┌─────────────────── git:arrow +│ │ │ │ │ │ │ │ │ ┌───────────────── git:stash +│ │ │ │ │ │ │ │ │ │ ┌─────────────── node_version +│ │ │ │ │ │ │ │ │ │ │ ┌─────────── execution_time +│ │ │ │ │ │ │ │ │ │ │ │ ┌────── custom:suffix +│ │ │ │ │ │ │ │ │ │ │ │ │ +prefix ✦ zaphod@heartofgold ~/dev/pure main*+ rebase-i ⇡ ≡ ⬢22 42s suffix venv ❯ │ │ -│ └──────────────────────────────────────────────── prompt -└───────────────────────────────────────────────────── virtualenv (or prompt:continuation) +│ └───────────────────────────────────────────────────────────────────── prompt +└────────────────────────────────────────────────────────────────────────── virtualenv (or prompt:continuation) ``` ### Preview diff --git a/tests/preview.zsh b/tests/preview.zsh index c0717c9..e3a127d 100644 --- a/tests/preview.zsh +++ b/tests/preview.zsh @@ -5,6 +5,8 @@ source "${0:A:h}/test-helper.zsh" main() { # Set up colors like prompt_pure_setup would. typeset -gA prompt_pure_colors=( + custom:prefix 242 + custom:suffix 242 execution_time yellow git:arrow cyan git:stash cyan @@ -29,7 +31,7 @@ main() { local output output=$(prompt_pure_preview 2>&1) - for component in zaphod heartofgold "~/dev/pure" "main" "rebase-i" "42s" "venv" "prompt after error" "continuation prompt" "root" "branch color when data is cached"; do + for component in prefix suffix zaphod heartofgold "~/dev/pure" "main" "rebase-i" "42s" "venv" "prompt after error" "continuation prompt" "root" "branch color when data is cached"; do if [[ $output != *"$component"* ]]; then print -u2 "Missing component in preview output: $component" return 1