summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--ChangeLog4
-rw-r--r--Functions/Misc/colors132
-rw-r--r--Functions/Prompts/promptinit154
3 files changed, 195 insertions, 95 deletions
diff --git a/ChangeLog b/ChangeLog
index 0dbfc405f..b1766e856 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,9 @@
2000-06-11 Bart Schaefer <schaefer@zsh.org>
+ * 11866: Functions/Misc/colors, Functions/Prompts/promptinit: Set
+ up color/colour assoc arrays to map the full range of ANSI text
+ properties; preserve more state during themed prompt previewing.
+
* Alexandre: 11864: Src/Zle/complist.c: Shift an array the opposite
way to fix colored listings crash.
diff --git a/Functions/Misc/colors b/Functions/Misc/colors
index 8ce2326e6..0a31afcf6 100644
--- a/Functions/Misc/colors
+++ b/Functions/Misc/colors
@@ -1,67 +1,79 @@
-# Put standard ANSI color codes in environment for easy use
+# Put standard ANSI color codes in shell parameters for easy use.
+# Note that some terminals do not support all combinations.
-reset_color="$(echo -n '\e[0m')"
-bold_color="$(echo -n '\e[1m')"
+typeset -Ag color colour
+
+color=(
+# Attribute codes:
+ 00 none
+ 01 bold
+ 02 faint 22 normal
+ 03 standout 23 no-standout
+ 04 underline 24 no-underline
+ 05 blink 25 no-blink
+ 07 reverse 27 no-reverse
+ 08 conceal
+
+# Text color codes:
+ 30 black 40 bg-black
+ 31 red 41 bg-red
+ 32 green 42 bg-green
+ 33 yellow 43 bg-yellow
+ 34 blue 44 bg-blue
+ 35 magenta 45 bg-magenta
+ 36 cyan 46 bg-cyan
+ 37 white 47 bg-white
+ 39 default 49 bg-default
+)
+
+# A word about black and white: The "normal" shade of white is really a
+# very pale grey on many terminals; to get truly white text, you have to
+# use bold white, and to get a truly white background you have to use
+# bold reverse white bg-xxx where xxx is your desired foreground color
+# (and which means the foreground is also bold).
+
+# Map in both directions; could do this with e.g. ${(k)colors[(i)normal]},
+# but it's clearer to include them all both ways.
+
+local k
+for k in ${(k)color}; do color[${color[$k]}]=$k; done
+
+# Add "fg-" keys for all the text colors, for clarity.
+
+for k in ${color[(I)3?]}; do color[fg-${color[$k]}]=$k; done
+
+# This is inaccurate, but the prompt theme system needs it.
+
+color[grey]=${color[black]}
+color[fg-grey]=${color[grey]}
+color[bg-grey]=${color[bg-black]}
+
+# Assistance for the color-blind.
+
+colour=(${(kv)color}) # A case where ksh namerefs would be useful ...
+
+# The following are terminal escape sequences used by colored prompt themes.
+
+local lc=$'\e[' rc=m # Standard ANSI terminal escape values
+
+typeset -Hg reset_color bold_color
+reset_color="$lc${color[none]}$rc"
+bold_color="$lc${color[bold]}$rc"
# Foreground
-fg_grey="$(echo -n '\e[30m')"
-fg_red="$(echo -n '\e[31m')"
-fg_green="$(echo -n '\e[32m')"
-fg_yellow="$(echo -n '\e[33m')"
-fg_blue="$(echo -n '\e[34m')"
-fg_magenta="$(echo -n '\e[35m')"
-fg_cyan="$(echo -n '\e[36m')"
-fg_white="$(echo -n '\e[37m')"
-
-fg_no_bold_grey="$(echo -n '\e[0;30m')"
-fg_no_bold_red="$(echo -n '\e[0;31m')"
-fg_no_bold_green="$(echo -n '\e[0;32m')"
-fg_no_bold_yellow="$(echo -n '\e[0;33m')"
-fg_no_bold_blue="$(echo -n '\e[0;34m')"
-fg_no_bold_magenta="$(echo -n '\e[0;35m')"
-fg_no_bold_cyan="$(echo -n '\e[0;36m')"
-fg_no_bold_white="$(echo -n '\e[0;37m')"
-
-fg_bold_grey="$(echo -n '\e[1;30m')"
-fg_bold_red="$(echo -n '\e[1;31m')"
-fg_bold_green="$(echo -n '\e[1;32m')"
-fg_bold_yellow="$(echo -n '\e[1;33m')"
-fg_bold_blue="$(echo -n '\e[1;34m')"
-fg_bold_magenta="$(echo -n '\e[1;35m')"
-fg_bold_cyan="$(echo -n '\e[1;36m')"
-fg_bold_white="$(echo -n '\e[1;37m')"
+typeset -AHg fg fg_bold fg_no_bold
+for k in ${(v)color[(I)fg-*]}; do
+ fg[${color[$k]}]="$lc$k$rc"
+ fg_bold[${color[$k]}]="$lc${color[bold]};$k$rc"
+ fg_no_bold[${color[$k]}]="$lc${color[normal]};$k$rc"
+done
# Background
-bg_grey="$(echo -n '\e[40m')"
-bg_red="$(echo -n '\e[41m')"
-bg_green="$(echo -n '\e[42m')"
-bg_yellow="$(echo -n '\e[43m')"
-bg_blue="$(echo -n '\e[44m')"
-bg_magenta="$(echo -n '\e[45m')"
-bg_cyan="$(echo -n '\e[46m')"
-bg_white="$(echo -n '\e[47m')"
-
-bg_no_bold_grey="$(echo -n '\e[0;40m')"
-bg_no_bold_red="$(echo -n '\e[0;41m')"
-bg_no_bold_green="$(echo -n '\e[0;42m')"
-bg_no_bold_yellow="$(echo -n '\e[0;43m')"
-bg_no_bold_blue="$(echo -n '\e[0;44m')"
-bg_no_bold_magenta="$(echo -n '\e[0;45m')"
-bg_no_bold_cyan="$(echo -n '\e[0;46m')"
-bg_no_bold_white="$(echo -n '\e[0;47m')"
-
-bg_bold_grey="$(echo -n '\e[1;40m')"
-bg_bold_red="$(echo -n '\e[1;41m')"
-bg_bold_green="$(echo -n '\e[1;42m')"
-bg_bold_yellow="$(echo -n '\e[1;43m')"
-bg_bold_blue="$(echo -n '\e[1;44m')"
-bg_bold_magenta="$(echo -n '\e[1;45m')"
-bg_bold_cyan="$(echo -n '\e[1;46m')"
-bg_bold_white="$(echo -n '\e[1;47m')"
-
-# Stop these screwing the environment listing up
-bg_zzzz=$reset_color
-fg_zzzz=$reset_color
-bold_zzzz=$reset_color
+typeset -AHg bg bg_bold bg_no_bold
+for k in ${(v)color[(I)bg-*]}; do
+ bg[${color[$k]}]="$lc$k$rc"
+ bg_bold[${color[$k]}]="$lc${color[bold]};$k$rc"
+ bg_no_bold[${color[$k]}]="$lc${color[normal]};$k$rc"
+done
diff --git a/Functions/Prompts/promptinit b/Functions/Prompts/promptinit
index 2cf2a4674..a07650500 100644
--- a/Functions/Prompts/promptinit
+++ b/Functions/Prompts/promptinit
@@ -1,27 +1,32 @@
-# zsh prompt themes extension
-#
-# Load with `autoload -U promptinit; promptinit'.
+##
+## zsh prompt themes extension
+## by Adam Spiers <adam@spiers.net>
+##
+## Load with `autoload -U promptinit; promptinit'.
+## Type `prompt -h' for help.
+##
prompt_themes=()
typeset -gU prompt_themes
-typeset -g prompt_theme
+typeset -g prompt_theme >/dev/null
promptinit () {
emulate -L zsh
- local ppath='' name
+ setopt extendedglob
+ local ppath='' name theme
# Autoload all prompt_*_setup functions in fpath
- for theme in $fpath/prompt_*_setup(N); do
+ for theme in $^fpath/prompt_*_setup(N); do
if [[ $theme == */prompt_(#b)(*)_setup ]]; then
name="$match[1]"
if [[ -r "$theme" ]]; then
- prompt_themes=($name $prompt_themes)
+ prompt_themes=($prompt_themes $name)
autoload -U prompt_${name}_setup
else
- print "Couldn't find theme $theme"
+ print "Couldn't read file $theme containing theme $name."
fi
else
- print "eh?"
+ print "Eh? Mismatch between glob patterns in promptinit."
fi
done
@@ -30,29 +35,86 @@ promptinit () {
colors
# Variables common to all prompt styles
- prompt_newline=$(echo -ne "\n%{\r%}")
+ prompt_newline=$'\n%{\r%}'
}
-prompt () {
+prompt_preview_safely() {
+ print $reset_color
+ if [[ -z "$prompt_themes[(r)$1]" ]]; then
+ print "Unknown theme: $1"
+ 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
+ trap "${$(functions precmd):-:} ; ${$(functions preexec):-:}" 0
+
+ # 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
+}
+
+set_prompt() {
+ emulate -L zsh
local opt preview theme usage old_theme
usage='Usage: prompt <options>
Options:
+ -c Show currently selected theme and parameters
-l List currently available prompt themes
-p [<themes>] Preview given themes (defaults to all)
-h [<theme>] Display help (for given theme)
-s <theme> Set and save theme
- <theme> Switch to new theme immediately (changes not saved)'
+ <theme> Switch to new theme immediately (changes not saved)
- getopts "hlps" opt
+Use prompt -h <theme> for help on specific themes.'
+
+ getopts "chlps" opt
+ case "$opt" in
+ (h|p)
+ 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
+ trap "${$(functions precmd):-:} ; ${$(functions preexec):-:}" 0
+ else
+ trap 'prompt_${prompt_theme[1]}_setup "${(@)prompt_theme[2,-1]}"' 0
+ fi
+ ;;
+ esac
case "$opt" in
+ c) if (( $+prompt_theme )); then
+ print -n "Current prompt theme"
+ (( $#prompt_theme > 1 )) && print -n " with parameters"
+ print " is:\n $prompt_theme"
+ else
+ print "Current prompt is not a theme."
+ fi
+ return
+ ;;
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
if functions prompt_$2_help >/dev/null; then
- print "Help for $2 theme:\n"
+ print "Help for $2 theme:\n"
prompt_$2_help
else
- print "No help available for $2 theme"
+ print "No help available for $2 theme."
fi
+ print "\nType \`prompt -p $2' to preview the theme, \`prompt $2'"
+ print "to try it out, and \`prompt -s $2' to use it in future sessions."
else
print "$usage"
fi
@@ -61,24 +123,13 @@ Options:
print $prompt_themes
return
;;
- p) if (( ! $+prompt_theme )); then
- print "Cannot preview; current prompt is non-themeable and would"
- print "be destroyed."
- return
- fi
- preview=( $prompt_themes )
- [[ -n "$2" && -n $prompt_themes[(r)$2] ]] && preview=( $*[2,-1] )
+ p) preview=( $prompt_themes )
+ (( $#* > 1 )) && preview=( "$@[2,-1]" )
for theme in $preview; do
- [[ $theme == $prompt_theme[1] ]] && continue
- print "\nTheme: $theme"
- prompt_${theme}_setup
- precmd
- print -n -P "${PS1}"
- preexec
- print "command arg1 arg2 ... argn"
+ [[ "$theme" == "$prompt_theme[*]" ]] && continue
+ prompt_preview_safely "$=theme"
done
- print
- prompt_${prompt_theme}_setup
+ print $reset_color
;;
s) print "Set and save not yet implemented. Please ensure your ~/.zshrc"
print "contains something similar to the following:\n"
@@ -86,12 +137,21 @@ Options:
print " promptinit"
print " prompt $*[2,-1]"
;;
- *) if [[ -z "$1" || -z $prompt_themes[(r)$1] ]]; then
+ *) if [[ "$1" == 'random' ]]; then
+ local random_themes
+ if (( $#* == 1 )); then
+ random_themes=( $prompt_themes )
+ else
+ random_themes=( "$@[2,-1]" )
+ fi
+ local i=$(( ( $RANDOM % $#random_themes ) + 1 ))
+ argv=( "${=random_themes[$i]}" )
+ fi
+ if [[ -z "$1" || -z $prompt_themes[(r)$1] ]]; then
print "$usage"
return
fi
- prompt_$1_setup "$*[2,-1]"
- prompt_theme=( $* )
+ prompt_$1_setup "$@[2,-1]" && prompt_theme=( "$@" )
# Avoid screwing up the environment listing
PSZZZZ=$reset_color
@@ -103,5 +163,29 @@ Options:
esac
}
-promptinit "$@"
+prompt () {
+ local prompt_opts
+
+ set_prompt "$@"
+
+ (( $#prompt_opts )) &&
+ setopt noprompt{bang,cr,percent,subst} prompt${^prompt_opts[@]}
+
+ true
+}
+
+prompt_preview_theme () {
+ local -a psv; psv=($psvar); local -a +h psvar; psvar=($psv) # Ick
+ local +h PS1=$PS1 PS2=$PS2 PS3=$PS3 PS4=$PS4 RPS1=$RPS1
+ trap "${$(functions precmd):-:} ; ${$(functions preexec):-:}" 0
+
+ print -n "$1 theme"
+ (( $#* > 1 )) && print -n " with parameters \`$*[2,-1]'"
+ print ":"
+ prompt_${1}_setup "$@[2,-1]"
+ precmd
+ print -P "${PS1}command arg1 arg2 ... argn"
+ preexec
+}
+[[ -o kshautoload ]] || promptinit "$@"