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:
- Format string - What to show and in what order
- Colors and styles - How each part looks
- 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:
| Variable | Example Output | Description |
|---|---|---|
{user} | john | Your username |
{host} | macbook | Hostname |
{cwd} | /Users/john/projects | Full path |
{dir} | projects | Just 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:
| Variable | Example | Description |
|---|---|---|
{builtins/context:git_branch} | main | Current git branch |
{builtins/context:git_status} | * | Dirty indicator |
{builtins/context:rust_version} | 1.75.0 | Rust version |
{builtins/context:rust_icon} | 🦀 | Shows in Rust projects |
{builtins/context:node_version} | 20.10.0 | Node.js version |
{builtins/context:node_icon} | ⬢ | Shows in Node projects |
{builtins/context:python_version} | 3.12.0 | Python version |
{builtins/context:python_icon} | 🐍 | Shows in Python projects |
From builtins/exec_time:
| Variable | Example | Description |
|---|---|---|
{builtins/exec_time:took} | took 2.3s | With prefix |
{builtins/exec_time:duration} | 2.3s | Duration 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 textdim- Dimmed/fadeditalic- Italic textunderline- 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
| Condition | What it checks | Example |
|---|---|---|
empty | Value is empty | { empty = true, color = "gray" } |
not_empty | Value has content | { not_empty = true, color = "red" } |
contains | Value contains text | { contains = "error", color = "red" } |
match | Regex pattern | { match = "^-", color = "blue" } |
above | Number > threshold | { above = 25, color = "red" } |
below | Number < 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:
| Color | For | Behavior |
|---|---|---|
temperature | Weather | blue (cold) → cyan → white → yellow → red (hot) |
battery | Battery % | red (below 15%) → yellow (below 30%) → green |
percentage | Any % | red (below 20%) → yellow (below 50%) → green |
git_indicator | Git status | green (clean) → yellow (dirty) |
load | CPU load | green (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"