zsh, prompt, variable expansion, ANSI color sequences

Hi!

I am using latest ZSH and I have setopt prompt_subst

I have a global hash array variable which contains some color definitions with color names as keys and 256-color ANSI codes (with %{ and %}) as values, eg %{\e[38;5;51m%}

If at function precmd() I set prompt as

PS1="$FG[red5] Hello World (%M) > "

or

PS1=$'$FG[red5] Hello World (%M) > '

then it becomes

\e[38;5;196m Hello World (localhost) > 

As you see %{ and %} were removed, but ANSI code remained.

If I set

PS1=$(print -P "$FG[red5] Hello World (%M) > ")

then prompt appears as expected, but zsh does not calculate it's length correctly (it thinks that it's length is as if control sequences were printable), and tab completion transfers the command way further.

I think that a possible solution would be that the array did not include the %{ and %} and using something like %{$FG[red5]%} to set the color, but it's ugly.

I know there is built-in support for colors but it's only 16 color.

Any help please?

Using %{ and %} works fine for me using version zsh 4.3.12 eg:

# PS1=$'%{\e[38;5;196m%}Testing$ %{\e[0m%}'
Testing $ 

Even works when I resize my xterm window

Yes, but you did not use variables.
My issue seems to be with variable expansion.

Do the print -P when assigning the variables then:

# RED=$(print -P '\e[38;5;196m')
# NORM=$(print -P '\e[0m')        
# PS1="%{$RED%}Testing$ %{$NORM%}"
Testing $ 

or

# RED='%{'$(print -P '\e[38;5;196m')'%}'
# NORM='%{'$(print -P '\e[0m')'%}'
# PS1="${RED}Testing$ ${NORM}"
Testing $ 
1 Like