55

zstyle seems like it's just a central place to store and retrieve data, like an alternative to export-ing shell parameters. Is that true, or is there more to it?

1
  • 7
    Upvoted the q for two reasons; a) Google sends me here anyway; b) zstyle seems to have a lot going for it that seems to have nothing to do with "style" or auto-completion. One of the answers here even comments on how the feature is terribly-named.
    – zaTricky
    Commented Feb 27, 2017 at 7:20

5 Answers 5

43

zstyle handles the obvious style control for the completion system, but it seems to cover more than just that. E.g., the vcs_info module relies on it for display of git status in your prompt. You can start by looking at the few explanatory paragraphs in man zshmodules in the zstyle section.

You can simply invoke it to see what settings are in effect. This can be instructive.

The Zsh Book has a nice chapter treatment on zstyle, also, explaining in detail its various fields.

You could grep around in the .../Completion/ directory on your system to see how some of those files make use of zstyle. A common location is near /usr/share/zsh/functions/Completion/*. I see it used in 100+ files on my system there. Users often have zstyle sprinkled around their ~/.zshrc, too. Here are some nice ones to add some color and descriptions to your completing:

# Do menu-driven completion.
zstyle ':completion:*' menu select

# Color completion for some things.
# http://linuxshellaccount.blogspot.com/2008/12/color-completion-using-zsh-modules-on.html
zstyle ':completion:*' list-colors ${(s.:.)LS_COLORS}

# formatting and messages
# http://www.masterzen.fr/2009/04/19/in-love-with-zsh-part-one/
zstyle ':completion:*' verbose yes
zstyle ':completion:*:descriptions' format "$fg[yellow]%B--- %d%b"
zstyle ':completion:*:messages' format '%d'
zstyle ':completion:*:warnings' format "$fg[red]No matches for:$reset_color %d"
zstyle ':completion:*:corrections' format '%B%d (errors: %e)%b'
zstyle ':completion:*' group-name ''

# Completers for my own scripts
zstyle ':completion:*:*:sstrans*:*' file-patterns '*.(lst|clst)'
zstyle ':completion:*:*:ssnorm*:*' file-patterns '*.tsv'
# ...

The completion system makes most of the fields clear if you play around with it. Try typing zstyle :«tab» and you see some options. Tab-complete to the next colon and you’ll see the next set of options, etc.

3
  • 2
    Thanks for the link to the Zsh book, and the tip about the Completion directory. The Zsh manual is heavy on functionality and very light on use cases and examples Commented Jul 8, 2015 at 20:54
  • "...is heavy on functionality and very light on use cases and examples" - unfortunately the case for most material written by programmers.
    – aaaaaa
    Commented Oct 20, 2016 at 19:52
  • You're mixing variables and format specifiers here, and you aren't resetting the yellow color, just the bold. Using format specifiers: "$fg[yellow]%B--- %d%b" would be '%F{yellow}%B--- %d%f%b', and "$fg[red]No matches for:$reset_color %d" would be '%fg{red}%BNo matches for:%b%f %d' Commented Dec 11, 2021 at 6:13
21

To properly understand how zstyle works, you first need to understand that zsh is a modular program. From man zshmodules

Some optional parts of zsh are in modules, separate from the core of the shell. Each of these modules may be linked in to the shell at build time, or can be dynamically linked while the shell is running if the installation supports this feature. [...]

In this regard zsh is more like an interpreter like PHP where the main builtin commands are defined in the "core" module, but other builtin commands are contained in "modules".
Ok great, so then what is "zstyle"?
zsh, like other shells has builtin commands, such as source, cd or declare - zstyle is a just another one of these "builtins".

Scope of builtins and shell options

builtins and shell options are usually "global" in the sense that they are generally (but not always) applicable/usable at any time or context throughout the shell process, or in other words, they generally apply to zsh and all the sub-systems (modules). Note this applies whether a shell is invoked as an interactive or non-interactive interpreter.
So, for example you can use the builtin's source or cd or the shell option "globstar" will be valid whether at a command prompt or in a case statement in a non-interactive script or in a function in that same script.
Contrary to another answer above, zstyle is not a builtin that is specific to the "compsys" (completions system) module, zstyle is a "global" builtin.

zstyle is defined by the zsh/util module, this simply means that the code which defines how to parse, and "do" zstyle is defined in the zsh/zutil module.
You could just as well forget this fact, i.e. bash doesn't require you to know that the code for the eval builtin is contained in the file eval.c, but to get help for zstyle, it helps to know that zstyle is a builtin defined in the zsh/zutil module, and the documentation for the zsh/zutil module can be accessed by runningman zshmodules.

Setting options that are specific to a module or a shell function

So traditionally shell options have generally been "global", but as per the description from man zshmodules, Some optional parts of zsh are in modules, and also, a lot of the zsh functionality has been written in shell functions. (similar to how a lot of core and optional functionality of vim has been written in vimscript).
So then if you want to be able to specify options that apply just to these modules or functions, how would you do it?
Well that's what zstyle does, give you the ability to "target" options at a much finer level than traditional "global" shell options.
zstyle achieves this through the argument "pattern"

An example command which configures some optional behavior specific to "compsys":

zstyle ':completion::complete:lsof:*' menu yes select

and configuring some optional behavior specific to "vcs_info":

zstyle ':vcs_info:*' actionformats \
      '%F{5}(%f%s%F{5})%F{3}-%F{5}[%F{2}%b%F{3}|%F{1}%a%F{5}]%f '

But it doesn't stop there, zstyles ability to target contexts is incredibly powerful, for example, say you wanted to define some behaviour/options for the vcs_info feature, when you were is a .git repository, as opposed to a svn repo, then you could modify the context pattern

:vcs_info:<svn_or_whatever_SCM_system>:* <style>

What about optional behaviour for a specific project, with a svn repo? then

:vcs_info:<svn_or_whatever_SCM_system>:*:repo-root-name <style>
1
  • So the "pattern" is decided on by the feature, not zstyle? So everything after :vcs_info: is decided by that feature itself (targeting git as opposed to svn)?
    – Marko
    Commented Dec 11, 2023 at 11:30
10

There is a huge lack of good examples in the zsh space, and the documentation is obtuse. I recommend spending some time looking at how Prezto uses zstyle, as well as reading the docs and trying some things. zstyle seems to be mainly used in completions, but is actually really good for other purposes, for example storing data in a way that's more sophisticated than plain-old-environment variables.

This gist shows how you might use zstyle to store and retrieve information:

# reference: http://zsh.sourceforge.net/Doc/Release/Zsh-Modules.html#The-zsh_002fzutil-Module

# list all zstyle settings
zstyle -L

# store value in zstyle
zstyle :example:favorites fruit apple

# store multiple values in zstyle
zstyle :example:list fruits banana mango pear

# retrieve from zstyle and assign new $fav variable with -g
zstyle -g fav ':example:favorites' fruit && echo $fav

# retrieve from zstyle and be explicit about the assignment data type:
# -a: array, -b: boolean, -s: string
zstyle -a :example:list fruits myfruitlist && echo $myfruitlist

# test that a zstyle value exists with -t
if zstyle -t ':example:favorites' 'fruit' 'apple'; then
  echo "an apple a day keeps the dr. away"
fi
if ! zstyle -t ':example:favorites:vegtable' 'broccoli'; then
  echo "Broccoli is the deadliest plant on Earth - why, it tries to warn you itself with its terrible taste"
fi

# delete a value with -d
zstyle -d ':example:favorites' 'fruit'

# list only zstyle settings for a certain pattern
zstyle -L ':example:favorites*'

zstyles can be really helpful when working with boolean values. For example, we showed how -t will test the value of a style, but additionally, it understands boolean words like 'yes', 'true', 'on', or '1', so you can let a user configure the features they want like so:

# Turn on foo feature, and turn off bar feature... baz isn't specified
zstyle ':example:foo' enabled 'yes'
zstyle ':example:bar' enabled 'no'

# Now, test whether the user wanted those features
for feat in foo bar baz; do
  zstyle -t ":example:$feat" enabled && echo "enabling $feat" || echo "disabling $feat"
done

# If you prefer non-specified options to default to true
# instead of false, swap the `-t` flag for `-T`, which will
# make baz enabled instead of disabled in our example
# Now, test whether the user wanted those features
for feat in foo bar baz; do
  zstyle -T ":example:$feat" enabled && echo "enabling $feat" || echo "disabling $feat"
done

And finally, perhaps the most powerful part of zstyles is the ability to use cascading settings via '*' patterns. Let's imagine you have a plugin that has 3 features: foo, bar, and baz. Those features let you specify whether you want them to create Zsh aliases. You can specify that you want all aliases enabled except for the ones 'bar' provides like so:

zstyle ':example:*:aliases' enabled 'yes'
zstyle ':example:bar:aliases' enabled 'no'

Then, even though we didn't specify foo, zstyle -t ':example:foo:aliases' enabled still works because of the * pattern.

3
  • Showing array value with echo $fav can be confusing if some array element contains space; I would recommend typeset fav instead. Commented Sep 28, 2020 at 18:42
  • BTW this doesn’t seem to work: zstyle -s ':example:favorites' 'computer' 'apple' Commented Sep 29, 2020 at 2:42
  • Thanks @FranklinYu. Made a couple edits to make it work. I was using -s incorrectly, as it's for retrieval, not storage.
    – mattmc3
    Commented Sep 30, 2020 at 15:07
9

The only vaguely meaningful description of the stupidly named, and ill-documented "(z)style" I've found - comes from the glossary of From Bash To The Z Shell

style

In zsh, the style mechanism is a flexible way of configuring shell add- ons that use functions, such as the completion system and editor widgets. Unlike variables they can be different in different contexts and unlike shell options they can take values. The mechanism is based on the command style.

also, in the section "Handling Styles", the author further elaborates...

With more sophisticated completion functions, you may want to allow aspects of the function’s behavior to be configurable using style.

... many helper functions look up styles for you so your function will react to many styles without your function having to do anything in particular. To get an idea of the styles looked up in a particular situation, invoke the _complete_help function with a numeric argument. Normally, you can do this by pressing Esc2 followed by Ctrl-x h. This is primarily useful when configuring completion because it allows you to see what styles are looked up and the associated context.

6

One of the most frustrating things about ZSH is figuring out where to find its various commands in the man pages. In this case documentation for zstyle can be found in man zshmodules or here online.

This builtin command is used to define and lookup styles. Styles are pairs of names and values, where the values consist of any number of strings. They are stored together with patterns and lookup is done by giving a string, called the ‘context’, which is compared to the patterns. The definition stored for the first matching pattern will be returned.

1
  • 3
    This is the best answer because it links to the docs. I needed that to learn how to read from zstyle. The other answers only address setting styles.
    – cbarrick
    Commented Jul 5, 2019 at 1:09

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .