noshdocs

Themes

Customize your prompt with themes

Themes

Themes control how your prompt looks. They define the format, colors, and what information to display.

How Themes Work

When you start nosh, it loads your theme file and uses it to render your prompt. The theme contains:

  1. Format string - What to show and in what order
  2. Colors and styles - How each part looks
  3. Plugin settings - Which plugins to enable and their options

Theme Locations

Themes can come from three places:

~/.config/nosh/
├── themes/                  # Your local themes
│   └── mytheme.toml
└── packages/
    ├── builtins/            # Built-in themes (ships with nosh)
    │   └── themes/
    │       └── default.toml
    └── cool-themes/         # Installed packages
        └── themes/
            └── dark.toml

Setting Your Theme

Edit ~/.config/nosh/config.toml:

[prompt]
# Built-in theme (this is the default)
theme = "builtins/default"

# Your own theme (in ~/.config/nosh/themes/)
theme = "mytheme"

# Theme from an installed package
theme = "cool-themes/dark"

Theme Inheritance

Instead of starting from scratch, extend an existing theme:

# ~/.config/nosh/themes/mytheme.toml
extends = "builtins/default"

[prompt]
# Only change what you want - everything else inherited
format = "[{user}](green)@[{host}](yellow) [{dir}](blue) $ "
char = "$"

This gives you:

  • All the conditional colors from the default theme
  • All plugin configurations
  • Your custom prompt format

Creating Your First Theme

Step 1: Create the file

Run /create and select "Theme", or manually create a file:

# The file will be at ~/.config/nosh/packages/local/themes/mytheme.toml

Step 2: Write the theme

Here's a minimal theme:

[prompt]
format = "[{dir}](blue) $ "
char = "$"
char_error = "!"

This shows:

  • Current directory in blue
  • A $ prompt character
  • ! when the last command failed

Step 3: Activate it

In ~/.config/nosh/config.toml:

[prompt]
theme = "local/mytheme"

Format String Syntax

The format string uses a special syntax:

Styled Segments

Wrap text in [brackets](style):

format = "[hello](red) [world](blue bold)"

Variables

Use {curly braces} for dynamic values:

format = "[{user}](green)@[{host}](yellow) [{dir}](blue) "

Plugin Variables

For plugin values, use {plugin:variable}:

format = "[{builtins/context:git_branch}](purple)"

Available Variables

Built-in Variables

These work without any plugins:

VariableExample OutputDescription
{user}johnYour username
{host}macbookHostname
{cwd}/Users/john/projectsFull path
{dir}projectsJust the folder name
{newline}Line break
{prompt:char} or Changes based on last exit code

Plugin Variables

These require plugins to be enabled:

From builtins/context:

VariableExampleDescription
{builtins/context:git_branch}mainCurrent git branch
{builtins/context:git_status}*Dirty indicator
{builtins/context:rust_version}1.75.0Rust version
{builtins/context:rust_icon}🦀Shows in Rust projects
{builtins/context:node_version}20.10.0Node.js version
{builtins/context:node_icon}Shows in Node projects
{builtins/context:python_version}3.12.0Python version
{builtins/context:python_icon}🐍Shows in Python projects

From builtins/exec_time:

VariableExampleDescription
{builtins/exec_time:took}took 2.3sWith prefix
{builtins/exec_time:duration}2.3sDuration only

Colors and Styles

Named Colors

black, red, green, yellow, blue, purple (or magenta), cyan, white

Hex Colors

Use #RRGGBB for precise colors:

format = "[{dir}](#5f87af)"

Style Modifiers

  • bold - Bold text
  • dim - Dimmed/faded
  • italic - Italic text
  • underline - Underlined

Combine them:

format = "[{dir}](blue bold underline)"

Conditional Colors

Make colors change based on the value! Perfect for temperature, battery level, git status, etc.

Basic Example

[prompt]
format = "[{weather/weather:temp}](temperature)"

[colors.temperature]
default = "white"
rules = [
  { match = "^-", color = "blue" },    # Negative = cold
  { above = 25, color = "red" },        # Hot
]

Battery Example

[prompt]
format = "[{battery:percent}](battery_level)"

[colors.battery_level]
default = "green"
rules = [
  { below = 20, color = "red" },        # Critical
  { below = 50, color = "yellow" },     # Low
]

Git Status Example

[prompt]
format = "[{builtins/context:git_status}](git_indicator)"

[colors.git_indicator]
default = "green"
rules = [
  { not_empty = true, color = "yellow" },  # Has changes
]

Available Conditions

ConditionWhat it checksExample
emptyValue is empty{ empty = true, color = "gray" }
not_emptyValue has content{ not_empty = true, color = "red" }
containsValue contains text{ contains = "error", color = "red" }
matchRegex pattern{ match = "^-", color = "blue" }
aboveNumber > threshold{ above = 25, color = "red" }
belowNumber < threshold{ below = 10, color = "blue" }

Rules are checked in order - first match wins. The default color is used if no rules match.

Combining Conditions

Multiple conditions in one rule must ALL be true:

rules = [
  { above = 10, below = 25, color = "green" },  # Between 10-25
]

How Numbers are Extracted

For above/below, nosh extracts numbers from values like +5°C, -10°F, 85%, etc.

Built-in Conditional Colors

The default theme includes these ready-to-use conditional colors:

ColorForBehavior
temperatureWeatherblue (cold) → cyan → white → yellow → red (hot)
batteryBattery %red (below 15%) → yellow (below 30%) → green
percentageAny %red (below 20%) → yellow (below 50%) → green
git_indicatorGit statusgreen (clean) → yellow (dirty)
loadCPU loadgreen (below 1.0) → yellow (below 2.0) → red

Use them directly:

format = "[{weather:temp}](temperature) [{battery:percent}](battery)"

Or inherit them via extends = "builtins/default".

Enabling Plugins

Plugins provide the dynamic values. Enable them in your theme:

[plugins]
"builtins/context" = { enabled = true }
"builtins/exec_time" = { enabled = true, min_ms = 500 }

The min_ms setting means exec_time only shows for commands taking longer than 500ms.

Complete Theme Examples

Minimal Theme

Just the essentials:

[prompt]
format = "[{dir}](blue) $ "
char = "$"
char_error = "!"

Developer Theme

Shows git info and language versions:

[prompt]
format = """
[{dir}](blue bold) \
[{builtins/context:git_branch}](purple){builtins/context:git_status} \
{builtins/context:rust_icon}[{builtins/context:rust_version}](red) \
{builtins/context:node_icon}[{builtins/context:node_version}](green) \
[{builtins/exec_time:took}](dim)
[{prompt:char}](green bold) """
char = "❯"
char_error = "❯"

[plugins]
"builtins/context" = { enabled = true }
"builtins/exec_time" = { enabled = true, min_ms = 1000 }

Two-Line Theme

More room for information:

[prompt]
format = """
[{user}](green)@[{host}](yellow):[{cwd}](blue bold)
[{builtins/context:git_branch}](purple) [{prompt:char}](green) """
char = "❯"
char_error = "✗"

[plugins]
"builtins/context" = { enabled = true }

Tips

  • Empty values hide automatically - If git_branch is empty (not in a repo), nothing shows
  • Use \ for line continuation - Keeps format strings readable
  • Start simple - Add features one at a time
  • Test as you go - Changes apply on the next prompt
  • Plugins run in parallel - Adding more plugins doesn't slow down your prompt proportionally since they all execute concurrently with a 100ms soft timeout

Installing Theme Packages

Get themes made by others:

/install user/repo          # Install from GitHub
/sync                       # Update all packages
/packages                   # List and remove packages

Then use with:

[prompt]
theme = "repo-name/theme-name"