zsh-users
 help / color / mirror / code / Atom feed
From: Rick Bowen <rbowen@gmail.com>
To: Kannan Varadhan <kvaradhan3@gmail.com>
Cc: Zsh Users <zsh-users@zsh.org>
Subject: Re: colorizing printfs
Date: Mon, 13 May 2024 13:53:55 -0700	[thread overview]
Message-ID: <CAEnqoMCmYwyFkduwaokScPMJsMABeH+EJr=P--YjhHUuJbtR2w@mail.gmail.com> (raw)
In-Reply-To: <c7606614-3510-4e20-a2da-0e9e16a0605f@gmail.com>

I know I'm late, but I do like a colorful terminal...

Kannan - I think you may be overcomplicating it - the StackExchange
post certainly does! I personally find overly complex parameter
expansion somewhat distasteful. Keep It Simple.

The first part of the top answer is actually preferred, but it was
answered in the context of the original question, rather than "how can
I print colors in ZSH?"

Specifically, line 13 is what you're looking for:
    print -P "%F{$color}$ip%f\n"

print -P is what you probably want - unless you're trying to do
something portable (a.k.a. bash), in which case you can't use autoload
colors or zsh prompt expansion anyways, and should just stick to the
more portable style of ANSI escape codes with 8 or 256 colors or
truecolor modes.

This is the "old fashioned" (portable) way of printing colors:

    printf "\e[32m%s\e[0m\n" "this is green"
    printf "\e[92m%s\e[0m\n" "this is bright green"
    printf "\e[38;5;120m%s\e[0m\n" "this is probably green"
    printf "\e[38;2;0;255;0m%s\e[0m\n" "as green as it gets"

But in ZSH we can just use 'print -P' (see also: print in
zshbuiltins(1)). Note: this doesn't require "autoload colors''

    text="What color is grass?"
    print -P "%F{green}$text%f"

Using "autoload colors":

    autoload -Uz colors && colors
    text="grass is green"
    echo "Did you know, ${fg[green]}${text}${fg[default]} but the sky is not"

Under the hood, all we're doing is emitting "Select Graphic Rendition
(SGR)" terminal control sequences - e.g. "ESC [ ATTR m" where ESC is
one of: \e or \033 or \x1b followed by a literal "[", then an SGR
attribute number and maybe optional parameters separated by a
semi-colon ";", finally ending in the letter "m".

printf-style SGR examples with "autoload colors" associative array and
PROMPT_PERCENT/print -P equivalents:

1. \e[31m = \033[31m = \x1b[31m = red foreground using the terminal's
16 color palette = $fg[red] = $color[red] = %F{red} = %F{1}
2. \e[91m = "bright" red foreground = $fg_bold[red] = %B%F{red} = %F{9}
3. \033[41m = red background = $bg[red] = %K{red} = %K{1}
4. \x1b[38;2;255;0;0m = red foreground using 24-bit (truecolor) RGB
5. \x1b[48;2;255;0;0m = red background using 24-bit (truecolor) RGB
6. \x1b[38;5;196m = red foreground using the terminal's 256 color
palette = %F{196}
7. \e[0m = reset all
foreground/background/bold/italic/underline/blinking = $colors[none]
8. \e[39m = reset foreground color to default = $fg[default] = %f
9. \e[49m = reset background color to default = $bg[default] = %k

A rainbow of resources are available for the color curious:

- README_FIRST.txt: https://en.wikipedia.org/wiki/ANSI_escape_code
- zshcontrib(1) "Other Functions" -
https://zsh.sourceforge.io/Doc/Release/User-Contributions.html#Other-Functions
- zshmisc(1) "Expansion of Prompt Sequences: Visual Effects" -
https://zsh.sourceforge.io/Doc/Release/Prompt-Expansion.html#Visual-effects
- zshzle(1) "Character Highlighting" -
https://zsh.sourceforge.io/Doc/Release/Zsh-Line-Editor.html#Character-Highlighting
- zshmodules(1) "zsh/nearcolor module" -
https://zsh.sourceforge.io/Doc/Release/Zsh-Modules.html#The-zsh_002fnearcolor-Module
- https://github.com/termstandard/colors
- https://terminalguide.namepad.de/

Rick

Thanks,

Rick


On Sat, May 11, 2024 at 5:19 PM Kannan Varadhan <kvaradhan3@gmail.com> wrote:
>
>
> On 5/11/24 07:37, Roman Perepelitsa wrote:
>
> On Sat, May 11, 2024 at 4:27 PM Mikael Magnusson <mikachu@gmail.com> wrote:
>
> On Sat, May 11, 2024 at 2:54 AM Kannan Varadhan <kvaradhan3@gmail.com> wrote:
>
> ~⦒printf '%s.%s.%s\n' "${(%):-%F{blue}%B}" "test" "${(%):-%b}${(%):-%f}"
> %B}.test.
>
> You probably have a badly made / cargo culted precmd() function
> active.
>
> I am sorry, I did not follow this.
>
> That output is actually expected. The right curly must be escaped.
>
>     printf '%s.%s.%s\n' "${(%):-%F{blue\}%B}" "test" "${(%):-%b}${(%):-%f}"
>
> Yes, this works,
>
> Is this something that I missed in the documentation?
>
> Many useful, useable variants, thank you for these.
>
> However, it's easier to use `print -P`:
>
>     print -P '%F{blue}%Btest%b%f'
>
> Or, when printing $var:
>
>     print -rP '%F{blue}%B'${var//\%/%%}'%b%f'
>
> Alternatively:
>
>     print -Pn '%F{blue}%B'
>     print -rn -- $var
>     print -P '%b%f'
>
> Another alternative:
>
>     print -r -- ${(%):-'%F{blue}%B'${var//\%/%%}'%b%f'}
>
>
> Kannan


  parent reply	other threads:[~2024-05-13 20:55 UTC|newest]

Thread overview: 7+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2024-05-11  0:52 Kannan Varadhan
2024-05-11 14:26 ` Mikael Magnusson
2024-05-11 14:37   ` Roman Perepelitsa
2024-05-12  0:19     ` Kannan Varadhan
2024-05-12  6:44       ` Roman Perepelitsa
2024-05-13 20:53       ` Rick Bowen [this message]
2024-05-14  6:48     ` Stephane Chazelas

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to='CAEnqoMCmYwyFkduwaokScPMJsMABeH+EJr=P--YjhHUuJbtR2w@mail.gmail.com' \
    --to=rbowen@gmail.com \
    --cc=kvaradhan3@gmail.com \
    --cc=zsh-users@zsh.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
Code repositories for project(s) associated with this public inbox

	https://git.vuxu.org/mirror/zsh/

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).