Coloring and theming in Nu

Many parts of Nushell’s interface can have their color customized. All of these can be set in the config.nu configuration file. If you see the hash/hashtag/pound mark # in the config file it means the text after it is commented out.

  1. table borders
  2. primitive values
  3. shapes (this is the command line syntax)
  4. prompt
  5. LS_COLORS

Table borders


Table borders are controlled by the table_mode setting in config.nu. Here is an example:

  1. > let $config = {
  2. table_mode: rounded
  3. }

Here are the current options for table_mode:

  • rounded # of course, this is the best one 😃
  • basic
  • compact
  • compact_double
  • light
  • thin
  • with_love
  • reinforced
  • heavy
  • none
  • other

Color symbologies


  • r - normal color red’s abbreviation
  • rb - normal color red’s abbreviation with bold attribute
  • red - normal color red
  • red_bold - normal color red with bold attribute
  • "#ff0000" - “#hex” format foreground color red (quotes are required)
  • { fg: "#ff0000" bg: "#0000ff" attr: b } - “full #hex” format foreground red in “#hex” format with a background of blue in “#hex” format with an attribute of bold abbreviated.

attributes


codemeaning
lblink
bbold
ddimmed
hhidden
iitalic
rreverse
sstrikethrough
uunderline
nnothing
defaults to nothing

normal colors and abbreviations

codename
ggreen
gbgreen_bold
gugreen_underline
gigreen_italic
gdgreen_dimmed
grgreen_reverse
gblgreen_blink
gstgreen_strike
lglight_green
lgblight_green_bold
lgulight_green_underline
lgilight_green_italic
lgdlight_green_dimmed
lgrlight_green_reverse
lgbllight_green_blink
lgstlight_green_strike
rred
rbred_bold
rured_underline
rired_italic
rdred_dimmed
rrred_reverse
rblred_blink
rstred_strike
lrlight_red
lrblight_red_bold
lrulight_red_underline
lrilight_red_italic
lrdlight_red_dimmed
lrrlight_red_reverse
lrbllight_red_blink
lrstlight_red_strike
ublue
ubblue_bold
uublue_underline
uiblue_italic
udblue_dimmed
urblue_reverse
ublblue_blink
ustblue_strike
lulight_blue
lublight_blue_bold
luulight_blue_underline
luilight_blue_italic
ludlight_blue_dimmed
lurlight_blue_reverse
lubllight_blue_blink
lustlight_blue_strike
bblack
bbblack_bold
bublack_underline
biblack_italic
bdblack_dimmed
brblack_reverse
bblblack_blink
bstblack_strike
ligrlight_gray
ligrblight_gray_bold
ligrulight_gray_underline
ligrilight_gray_italic
ligrdlight_gray_dimmed
ligrrlight_gray_reverse
ligrbllight_gray_blink
ligrstlight_gray_strike
yyellow
ybyellow_bold
yuyellow_underline
yiyellow_italic
ydyellow_dimmed
yryellow_reverse
yblyellow_blink
ystyellow_strike
lylight_yellow
lyblight_yellow_bold
lyulight_yellow_underline
lyilight_yellow_italic
lydlight_yellow_dimmed
lyrlight_yellow_reverse
lybllight_yellow_blink
lystlight_yellow_strike
ppurple
pbpurple_bold
pupurple_underline
pipurple_italic
pdpurple_dimmed
prpurple_reverse
pblpurple_blink
pstpurple_strike
lplight_purple
lpblight_purple_bold
lpulight_purple_underline
lpilight_purple_italic
lpdlight_purple_dimmed
lprlight_purple_reverse
lpbllight_purple_blink
lpstlight_purple_strike
ccyan
cbcyan_bold
cucyan_underline
cicyan_italic
cdcyan_dimmed
crcyan_reverse
cblcyan_blink
cstcyan_strike
lclight_cyan
lcblight_cyan_bold
lculight_cyan_underline
lcilight_cyan_italic
lcdlight_cyan_dimmed
lcrlight_cyan_reverse
lcbllight_cyan_blink
lcstlight_cyan_strike
wwhite
wbwhite_bold
wuwhite_underline
wiwhite_italic
wdwhite_dimmed
wrwhite_reverse
wblwhite_blink
wstwhite_strike
dgrdark_gray
dgrbdark_gray_bold
dgrudark_gray_underline
dgridark_gray_italic
dgrddark_gray_dimmed
dgrrdark_gray_reverse
dgrbldark_gray_blink
dgrstdark_gray_strike

"#hex" format


The “#hex” format is one way you typically see colors represented. It’s simply the # character followed by 6 characters. The first two are for red, the second two are for green, and the third two are for blue. It’s important that this string be surrounded in quotes, otherwise Nushell thinks it’s a commented out string.

Example: The primary red color is "#ff0000" or "#FF0000". Upper and lower case in letters shouldn’t make a difference.

This "#hex" format allows us to specify 24-bit truecolor tones to different parts of Nushell.

full "#hex" format


The full "#hex" format is a take on the "#hex" format but allows one to specify the foreground, background, and attributes in one line.

Example: { fg: "#ff0000" bg: "#0000ff" attr: b }

  • foreground of red in “#hex” format
  • background of blue in “#hex” format
  • attribute of bold abbreviated

Primitive values


Primitive values are things like int and string. Primitive values and shapes can be set with a variety of color symbologies seen above.

This is the current list of primitives. Not all of these are configurable. The configurable ones are marked with *.

primitivedefault colorconfigurable
any
binaryColor::White.normal()
blockColor::White.normal()
boolColor::White.normal()
cellpathColor::White.normal()
condition
custom
dateColor::White.normal()
durationColor::White.normal()
expression
filesizeColor::White.normal()
floatColor::White.normal()
glob
import
intColor::White.normal()
listColor::White.normal()
nothingColor::White.normal()
number
operator
path
rangeColor::White.normal()
recordColor::White.normal()
signature
stringColor::White.normal()
table
var
vardecl
variable

special “primitives” (not really primitives but they exist solely for coloring)

primitivedefault colorconfigurable
leading_trailing_space_bgColor::Rgb(128, 128, 128))
headerColor::Green.bold()
emptyColor::Blue.normal()
row_indexColor::Green.bold()
hintsColor::DarkGray.normal()*

Here’s a small example of changing some of these values.

  1. > let config = {
  2. color_config: {
  3. separator: purple
  4. leading_trailing_space_bg: "#ffffff"
  5. header: gb
  6. date: wd
  7. filesize: c
  8. row_index: cb
  9. bool: red
  10. int: green
  11. duration: blue_bold
  12. range: purple
  13. float: red
  14. string: white
  15. nothing: red
  16. binary: red
  17. cellpath: cyan
  18. hints: dark_gray
  19. }
  20. }

Here’s another small example using multiple color syntaxes with some comments.

  1. > let config = {
  2. color_config: {
  3. separator: "#88b719" # this sets only the foreground color like PR #486
  4. leading_trailing_space_bg: white # this sets only the foreground color in the original style
  5. header: { # this is like PR #489
  6. fg: "#B01455", # note, quotes are required on the values with hex colors
  7. bg: "#ffb900",# note, commas are not required, it could also be all on one line
  8. attr: bli # note, there are no quotes around this value. it works with or without quotes
  9. }
  10. date: "#75507B"
  11. filesize: "#729fcf"
  12. row_index: {
  13. # note, that this is another way to set only the foreground, no need to specify bg and attr
  14. fg: "#e50914"
  15. }
  16. }
  17. }

Shape values

As mentioned above, shape is a term used to indicate the syntax coloring.

Here’s the current list of flat shapes.

shapedefault styleconfigurable
shape_blockfg(Color::Blue).bold()
shape_boolfg(Color::LightCyan)
shape_custombold()
shape_externalfg(Color::Cyan)
shape_externalargfg(Color::Green).bold()
shape_filepathfg(Color::Cyan)
shape_flagfg(Color::Blue).bold()
shape_floatfg(Color::Purple).bold()
shape_garbagefg(Color::White).on(Color::Red).bold()
shape_globpatternfg(Color::Cyan).bold()
shape_intfg(Color::Purple).bold()
shape_internalcallfg(Color::Cyan).bold()
shape_listfg(Color::Cyan).bold()
shape_literalfg(Color::Blue)
shape_nothingfg(Color::LightCyan)
shape_operatorfg(Color::Yellow)
shape_rangefg(Color::Yellow).bold()
shape_recordfg(Color::Cyan).bold()
shape_signaturefg(Color::Green).bold()
shape_stringfg(Color::Green)
shape_string_interpolationfg(Color::Cyan).bold()
shape_tablefg(Color::Blue).bold()
shape_variablefg(Color::Purple)*

Here’s a small example of how to apply color to these items. Anything not specified will receive the default color.

  1. > let $config = {
  2. color_config: {
  3. shape_garbage: { fg: "#FFFFFF" bg: "#FF0000" attr: b}
  4. shape_bool: green
  5. shape_int: { fg: "#0000ff" attr: b}
  6. }
  7. }

Prompt configuration and coloring

The Nushell prompt is configurable through these environment variables:

  • PROMPT_COMMAND: Code to execute for setting up the prompt (block)
  • PROMPT_COMMAND_RIGHT: Code to execute for setting up the RIGHT prompt (block) (see oh-my.nu in nu_scripts)
  • PROMPT_INDICATOR = “〉”: The indicator printed after the prompt (by default “>”-like Unicode symbol)
  • PROMPT_INDICATOR_VI_INSERT = “: “
  • PROMPT_INDICATOR_VI_NORMAL = “v “
  • PROMPT_MULTILINE_INDICATOR = “::: “

Example: For a simple prompt one could do this. Note that PROMPT_COMMAND requires a block whereas the others require a string.

  1. > let-env PROMPT_COMMAND = { build-string (date now | date format '%m/%d/%Y %I:%M:%S%.3f') ': ' (pwd | path basename) }

If you don’t like the default PROMPT_INDICATOR you could change it like this.

  1. > let-env PROMPT_INDICATOR = "> "

Coloring of the prompt is controlled by the block in PROMPT_COMMAND where you can write your own custom prompt. We’ve written a slightly fancy one that has git statuses located in the nu_scripts repoColoring and theming in Nu - 图1 (opens new window).

LS_COLORS colors for the ls command

Nushell will respect and use the LS_COLORS environment variable setting on Mac, Linux, and Windows. This setting allows you to define the color of file types when you do a ls. For instance, you can make directories one color, _.md markdown files another color, _.toml files yet another color, etc. There are a variety of ways to color your file types.

There’s an exhaustive list hereColoring and theming in Nu - 图2 (opens new window), which is overkill, but gives you an rudimentary understanding of how to create a ls_colors file that dircolors can turn into a LS_COLORS environment variable.

ThisColoring and theming in Nu - 图3 (opens new window) is a pretty good introduction to LS_COLORS. I’m sure you can find many more tutorials on the web.

I like the vivid application and currently have it configured in my config.nu like this. You can find vivid hereColoring and theming in Nu - 图4 (opens new window).

let-env LS_COLORS = (vivid generate molokai | str trim)

If LS_COLORS is not set, nushell will default to a builtin LS_COLORS setting, based on 8-bit (extended) ANSI colors.

Theming

Theming combines all the coloring above. Here’s a quick example of one we put together quickly to demonstrate the ability to theme. This is a spin on the base16 themes that we see so widespread on the web.

The key to making theming work is to make sure you specify all themes and colors you’re going to use in the config.nu file before you declare the let config = line.

  1. # let's define some colors
  2. let base00 = "#181818" # Default Background
  3. let base01 = "#282828" # Lighter Background (Used for status bars, line number and folding marks)
  4. let base02 = "#383838" # Selection Background
  5. let base03 = "#585858" # Comments, Invisibles, Line Highlighting
  6. let base04 = "#b8b8b8" # Dark Foreground (Used for status bars)
  7. let base05 = "#d8d8d8" # Default Foreground, Caret, Delimiters, Operators
  8. let base06 = "#e8e8e8" # Light Foreground (Not often used)
  9. let base07 = "#f8f8f8" # Light Background (Not often used)
  10. let base08 = "#ab4642" # Variables, XML Tags, Markup Link Text, Markup Lists, Diff Deleted
  11. let base09 = "#dc9656" # Integers, Boolean, Constants, XML Attributes, Markup Link Url
  12. let base0a = "#f7ca88" # Classes, Markup Bold, Search Text Background
  13. let base0b = "#a1b56c" # Strings, Inherited Class, Markup Code, Diff Inserted
  14. let base0c = "#86c1b9" # Support, Regular Expressions, Escape Characters, Markup Quotes
  15. let base0d = "#7cafc2" # Functions, Methods, Attribute IDs, Headings
  16. let base0e = "#ba8baf" # Keywords, Storage, Selector, Markup Italic, Diff Changed
  17. let base0f = "#a16946" # Deprecated, Opening/Closing Embedded Language Tags, e.g. <?php ?>
  18. # we're creating a theme here that uses the colors we defined above.
  19. let base16_theme = {
  20. separator: $base03
  21. leading_trailing_space_bg: $base04
  22. header: $base0b
  23. date: $base0e
  24. filesize: $base0d
  25. row_index: $base0c
  26. bool: $base08
  27. int: $base0b
  28. duration: $base08
  29. range: $base08
  30. float: $base08
  31. string: $base04
  32. nothing: $base08
  33. binary: $base08
  34. cellpath: $base08
  35. hints: dark_gray
  36. # shape_garbage: { fg: $base07 bg: $base08 attr: b} # base16 white on red
  37. # but i like the regular white on red for parse errors
  38. shape_garbage: { fg: "#FFFFFF" bg: "#FF0000" attr: b}
  39. shape_bool: $base0d
  40. shape_int: { fg: $base0e attr: b}
  41. shape_float: { fg: $base0e attr: b}
  42. shape_range: { fg: $base0a attr: b}
  43. shape_internalcall: { fg: $base0c attr: b}
  44. shape_external: $base0c
  45. shape_externalarg: { fg: $base0b attr: b}
  46. shape_literal: $base0d
  47. shape_operator: $base0a
  48. shape_signature: { fg: $base0b attr: b}
  49. shape_string: $base0b
  50. shape_filepath: $base0d
  51. shape_globpattern: { fg: $base0d attr: b}
  52. shape_variable: $base0e
  53. shape_flag: { fg: $base0d attr: b}
  54. shape_custom: {attr: b}
  55. }
  56. # now let's apply our regular config settings but also apply the "color_config:" theme that we specified above.
  57. let config = {
  58. filesize_metric: true
  59. table_mode: rounded # basic, compact, compact_double, light, thin, with_love, rounded, reinforced, heavy, none, other
  60. use_ls_colors: true
  61. color_config: $base16_theme # <-- this is the theme
  62. use_grid_icons: true
  63. footer_mode: always #always, never, number_of_rows, auto
  64. animate_prompt: false
  65. float_precision: 2
  66. use_ansi_coloring: true
  67. filesize_format: "b" # b, kb, kib, mb, mib, gb, gib, tb, tib, pb, pib, eb, eib, zb, zib, auto
  68. edit_mode: emacs # vi
  69. max_history_size: 10000
  70. log_level: error
  71. }

if you want to go full-tilt on theming, you’ll want to theme all the items I mentioned at the very beginning, including LS_COLORS, and the prompt. Good luck!