Zsh Mailing List Archive
Messages sorted by:
Reverse Date,
Date,
Thread,
Author
PATCH: Fiddling with colors
- X-seq: zsh-workers 11866
- From: "Bart Schaefer" <schaefer@xxxxxxxxxxxxxxxxxxxxxxx>
- To: zsh-workers@xxxxxxxxxxxxxx
- Subject: PATCH: Fiddling with colors
- Date: Sun, 11 Jun 2000 21:39:16 +0000
- Mailing-list: contact zsh-workers-help@xxxxxxxxxxxxxx; run by ezmlm
This discussion of a more understandable way to set the list-colors style
got me looking at the `colors' function, `dircolors --print-database` and
the docs for an ANSI terminal emulator. In the process I noticed several
glitches with the themed prompt system (none of which were mentioned in
sourceforge bug #104884).
After this patch the `colors' function creates an associative array `color'
(and copies it to `colour' for the color-blind) that maps ANSI code numbers
to descriptive words and vice-versa. (Calling these all colors is a bit of
a misnomer; "text properties" as in emacs would be better, but ...)
The {f,b}g{,{,_no}_bold} arrays are then filled in by looping over indices
in $color. I removed the fg_zzzz and bg_zzzz parameters, which were only
there to clean up the output of `typeset`, and instead typeset parameters
that contain escape sequences with -H so the values aren't shown. This is
something that probably should be done throughout Functions/Prompts/, but
I didn't get that ambitious.
BTW, see the note in `colors' about black and white, to see why the themed
prompt system is a bit strange in its use of the term "grey".
The promptinit patch adds `psvar' to the variables that are preserved when
previewing prompt settings and adds a `prompt_preview_safely' wrapper that
preserves those values around individual prompt previewings as well. It's
a bit of overkill in the current situation because everything utimately goes
through `prompt_preview_theme', which I also modified to preserve the same
parameters, but I did it anyway in case somebody writes a prompt_xxx_preview
function that behaves badly.
An unrelated thing that this patch points up is how painful it is to create
a local *copy* of an array parameter; see the lines marked "Ick" below.
I also fixed a problem with simulation of preexec in `prompt_preview_theme';
and I put the themes in alphabetical rather than reverse-alphabetical order
for previewing, just because.
Index: Functions/Misc/colors
===================================================================
@@ -1,85 +1,79 @@
-# Put standard ANSI color codes in environment for easy use
-reset_color=$'\e[0m'
-bold_color=$'\e[1m'
+# Put standard ANSI color codes in shell parameters for easy use.
+# Note that some terminals do not support all combinations.
-# Foreground
+typeset -Ag color colour
-typeset -Ag fg
-fg=(
- grey $'\e[30m'
- red $'\e[31m'
- green $'\e[32m'
- yellow $'\e[33m'
- blue $'\e[34m'
- magenta $'\e[35m'
- cyan $'\e[36m'
- white $'\e[37m'
-)
-fg_zzzz="$reset_color"
+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
-typeset -Ag fg_no_bold
-fg_no_bold=(
- grey $'\e[0;30m'
- red $'\e[0;31m'
- green $'\e[0;32m'
- yellow $'\e[0;33m'
- blue $'\e[0;34m'
- magenta $'\e[0;35m'
- cyan $'\e[0;36m'
- white $'\e[0;37m'
+# 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
)
-fg_no_bold_zzzz="$reset_color"
-typeset -Ag fg_bold
-fg_bold=(
- grey $'\e[1;30m'
- red $'\e[1;31m'
- green $'\e[1;32m'
- yellow $'\e[1;33m'
- blue $'\e[1;34m'
- magenta $'\e[1;35m'
- cyan $'\e[1;36m'
- white $'\e[1;37m'
-)
-fg_bold_zzzz="$reset_color"
+# 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).
-# Background
+# Map in both directions; could do this with e.g. ${(k)colors[(i)normal]},
+# but it's clearer to include them all both ways.
-typeset -Ag bg
-bg=(
- grey $'\e[40m'
- red $'\e[41m'
- green $'\e[42m'
- yellow $'\e[43m'
- blue $'\e[44m'
- magenta $'\e[45m'
- cyan $'\e[46m'
- white $'\e[47m'
-)
-bg_zzzz="$reset_color"
+local k
+for k in ${(k)color}; do color[${color[$k]}]=$k; done
-typeset -Ag bg_no_bold
-bg_no_bold=(
- grey $'\e[0;40m'
- red $'\e[0;41m'
- green $'\e[0;42m'
- yellow $'\e[0;43m'
- blue $'\e[0;44m'
- magenta $'\e[0;45m'
- cyan $'\e[0;46m'
- white $'\e[0;47m'
-)
-bg_no_bold_zzzz="$reset_color"
+# Add "fg-" keys for all the text colors, for clarity.
-typeset -Ag bg_bold
-bg_bold=(
- grey $'\e[1;40m'
- red $'\e[1;41m'
- green $'\e[1;42m'
- yellow $'\e[1;43m'
- blue $'\e[1;44m'
- magenta $'\e[1;45m'
- cyan $'\e[1;46m'
- white $'\e[1;47m'
-)
-bg_bold_zzzz="$reset_color"
+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
+
+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
+
+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
Index: Functions/Prompts/promptinit
===================================================================
@@ -20,7 +20,7 @@
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 read file $theme containing theme $name."
@@ -38,6 +38,29 @@
prompt_newline=$'\n%{\r%}'
}
+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
@@ -59,6 +82,7 @@
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
@@ -102,26 +126,10 @@
p) preview=( $prompt_themes )
(( $#* > 1 )) && preview=( "$@[2,-1]" )
for theme in $preview; do
- theme_args=( "$=theme" )
[[ "$theme" == "$prompt_theme[*]" ]] && continue
- if [[ -z "$prompt_themes[(r)$theme_args[1]]" ]]; then
- print "\nUnknown theme: $theme_args[1]"
- continue
- fi
- print
-
- # 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_${theme_args[1]}_setup
-
- if functions prompt_${theme_args[1]}_preview >&/dev/null; then
- prompt_${theme_args[1]}_preview "${(@)theme_args[2,-1]}"
- else
- prompt_preview_theme "${(@)theme_args}"
- fi
+ prompt_preview_safely "$=theme"
done
- print
+ print $reset_color
;;
s) print "Set and save not yet implemented. Please ensure your ~/.zshrc"
print "contains something similar to the following:\n"
@@ -167,14 +175,17 @@
}
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 -n -P "${PS1}"
+ print -P "${PS1}command arg1 arg2 ... argn"
preexec
- print "command arg1 arg2 ... argn"
}
[[ -o kshautoload ]] || promptinit "$@"
--
Bart Schaefer Brass Lantern Enterprises
http://www.well.com/user/barts http://www.brasslantern.com
Zsh: http://www.zsh.org | PHPerl Project: http://phperl.sourceforge.net
Messages sorted by:
Reverse Date,
Date,
Thread,
Author