-
Notifications
You must be signed in to change notification settings - Fork 4
Syntax Highlighting
shed highlights the command line as you type it. Highlighting colors commands, keywords, strings, variables, operators, and more, and flags things like unknown commands in red before you ever hit enter. Every color is configurable through the highlight.* shopt namespace. The highlighter uses shed's lexer and parser internally, so it can be used to see exactly how shed will interpret the line before you submit it.
Highlighting is on by default. Two toggles control it:
| Option | Effect |
|---|---|
highlight.enable |
master on/off switch for syntax highlighting (default true) |
highlight.check_files |
check the filesystem so that arguments naming a real file are styled (see argument_file below), and command-position directories are recognized. Involves a stat per candidate, so it can be slow on network mounts - set false to skip it (default true) |
shopt highlight.enable=false # turn highlighting off entirelyEvery highlight.* color takes a style description: a space-separated list of style words that combine into one style. This is the exact same grammar used by the prompt's \c{...} escape (see Prompt), so anything you learn here works there too.
A description is built from these pieces, in any order:
-
Attributes - any of
bold,dim,italic,underline,strikethrough,blink,inverted,hidden. -
A foreground color - one of
black,red,green,yellow,blue,magenta,cyan,white. -
bright- prefix that selects the bright variant of the color that follows it, e.g.bright black(a common "gray") orbright cyan. -
A hex color -
#rrggbbfor a truecolor foreground, e.g.#89b4fa. -
A background -
onfollowed by a color:on blue,on bright black, oron #1e1e2e. -
reset- clears styling back to the terminal default.
So all of these are valid:
shopt highlight.string="yellow"
shopt highlight.comment="italic bright black"
shopt highlight.operator="bold magenta"
shopt highlight.variable="#89b4fa"
shopt highlight.invalid_command="bold underline red on black"An invalid description is rejected when you set the option (for highlight.*) with an error explaining what didn't parse, so you'll know immediately if you typo a color name.
Each category below is a highlight.* option. Setting it changes the color of that syntax element in the line editor.
Commands (the word in command position):
| Option | Colors | Default |
|---|---|---|
highlight.external_command |
commands found on $PATH
|
green |
highlight.builtin |
builtin commands | green |
highlight.function |
shell functions | green |
highlight.alias |
aliases | green |
highlight.directory |
a directory in command position (with core.autocd) |
green |
highlight.invalid_command |
a command name that doesn't resolve to anything | bold red |
Syntax:
| Option | Colors | Default |
|---|---|---|
highlight.keyword |
keywords like if and for
|
yellow |
highlight.control_flow_keyword |
control-flow words like break and return
|
magenta |
highlight.operator |
pipes, redirects, and other operators | bold magenta |
highlight.string |
quoted strings | yellow |
highlight.variable |
variable expansions | cyan |
highlight.glob |
glob characters | bright cyan |
highlight.comment |
comments | italic bright black |
Arguments:
| Option | Colors | Default |
|---|---|---|
highlight.argument |
ordinary command arguments | white |
highlight.argument_file |
an argument that names an existing file | underline white |
The argument_file styling depends on highlight.check_files being enabled - it's what lets shed know an argument points at a real file. Likewise, highlight.directory (command-position directories) relies on both check_files and core.autocd. If you turn check_files off for speed, both fall back to the plain argument/invalid_command styling.
Since every value is a full color description, you can restyle the whole editor to match a theme by dropping a block of shopt highlight.* lines into your rc file (see Configuration) - or snapshot your live colors into one with genrc -s.
Some commands run another command passed as their argument, for instance: sudo ls, env FOO=bar make, nice -n10 build. For highlighting, the wrapped word (ls, make, build) is still in command position, so shed highlights and validates it as a command rather than as a plain argument. Without this, a typo like sudo lx would be painted as an ordinary argument instead of being flagged with highlight.invalid_command.
shed recognizes a built-in set of these wrappers out of the box: sudo, doas, pkexec, run0, env, nice, ionice, nohup, setsid, unshare, strace, valgrind, command, builtin, exec, and more. The word immediately following any of them is treated and validated as the command.
If you have your own wrapper that ultimately execs its argument, add it to the SHED_EXEC_WRAPPERS array and the highlighter treats it the same way:
SHED_EXEC_WRAPPERS+=(invoke)
invoke ls # `ls` is highlighted as a command, not an argumentYour entries extend the built-in list rather than replacing it.