Configuration#
One file, in KDL:
$SLOSH_CONFIG, else $XDG_CONFIG_HOME/slosh/config.kdl, else
~/.config/slosh/config.kdl
C-a e (edit_config) opens it in a pane, writing a starting file first if you have none.
Saving it applies to every running session immediately.
Some tips:
slosh --dump-configwrites every setting with its _default_ value, not the value your config gives it. It is generated from the code, so it cannot drift, and it is a supported way to start a config:slosh --dump-config > ~/.config/slosh/config.kdl.- To see what your own file does,
slosh --checkreads it and reports what it understood.
Sanity checking your slosh config#
$ slosh --check # the config a session would read
$ slosh --check themes/mine.kdl # or one you have not installed yet
Every problem it found, one per line, with the file and line it happened at, including a setting it does not know:
cannot open /home/you/.config/slosh/themes/nope.kdl
config.kdl:2: bad prefix: ctrl+nope
config.kdl:3: bad key: wobble
config.kdl:5: padding takes 1, 2 or 4 values (all, vertical horizontal, or top right bottom left), not 3
config.kdl:6: unknown setting: wobble
themes/mine.kdl:7: unknown shader: bloom
~/.config/slosh/config.kdl: 6 problems
The problems go to stderr and the summary with them. It exits 1 when it has anything to say, so it drops into an editor's compile step or a pre-commit hook with no glue. A clean run prints what it read (the files, the prefix it ended up with, how many bindings).
include#
A config can be composed of multiple files:
include "themes/amber.kdl"
include "keys/vim.kdl" "shaders/crt.kdl"
- A relative path is relative to the file doing the including, never to the directory you started the session from.
~is your home directory, an absolute path is itself, and an included file may include others. - What you include is the base: the file with the
includeline in it wins wherever they disagree, and a later include wins over an earlier one. That holds wherever the line sits in the file. keysblocks add to what came before; ashadersorstatesblock replaces the one it inherited.- Every included file is watched, so saving the theme reloads the session too.
Themes#
A theme is a file of colours in a directory, and a config names it:
theme_name "phosphor" // themes/phosphor.kdl
theme { frame_focus "#00ff88" } // ...but that one colour is mine
Named rather than pasted, because a name is a thing you can change. It is one line to edit, one {"cmd":"theme","name":"amber"} to switch while the session is running, and one row in a list something can show you. Sixty colours pasted into a config are none of those — and they freeze the palette at the moment they were pasted, so every later improvement to the theme they came from is one you never see.
Yours first, then the ones that ship with slosh. themes/ beside your config (so ~/.config/slosh/themes for the usual one), and then the shipped set, found relative to the binary that is running: <bin>/../share/slosh/themes for an installed slosh, <repo>/contrib/themes when you are running one out of a build tree, and the prefix the build was compiled with as a last resort. The binary is asked where it is rather than trusting the compiled-in prefix alone, because the two disagree all the time — a distro builds with PREFIX=/usr while the default is /usr/local, and a binary can be moved after the fact.
A shipped theme is therefore nameable without being copied anywhere, and a file of yours with the same name shadows it — which is how you edit a shipped theme without touching a root-owned file. theme_dir replaces the first of those directories, never the shipped set. cmd theme reports the whole list in dirs, in the order it searches, which is what to read when a name is not found.
theme_name takes a name, not a path: the directory is what makes a theme switchable, listable and shadowable, and a path quietly does none of that. For a file somewhere a directory of names cannot reach, include is unchanged and still works.
Seven themes ship in contrib/themes: amber, mono, paper, phosphor, sl0p, slate, and default — the annotated reference, every colour with what it is for, matching exactly what no config at all gets you. A theme file is a config file with one theme { } block in it, so slosh --check lints one and saving one reloads the session wearing it.
Start your own from the session in front of you rather than from an empty file:
slosh --dump-theme > ~/.config/slosh/themes/mine.kdl # the palette in force
--dump-config writes theme_name and the colours you overrode, not the resolved palette, so a dumped config keeps following its theme.
Switching without editing anything:
slosh -s main cmd theme # amber default* mono ...
slosh -s main cmd '{"cmd":"theme","name":"amber"}' # now
slosh -s main cmd '{"cmd":"theme","name":"amber","save":true}' # ...and from now on
The session holds the name over later reloads, so editing your config does not put the old colours back; save writes the theme_name line into the config, replacing the one already there, and leaves every other line and comment alone. {"cmd":"theme","name":""} drops the session's own answer and goes back to whatever the file says.
The knobs, briefly#
| group | what is in it |
|---|---|
| geometry | gap gap_aspect padding compact rounded title_align title_inset min_pane min_split |
| chrome | status_bar status_line status_pad tab_bar_side tab_bar_index tab_bar_width tab_bar_padding tab_bar_pad tab_gap tab_bar_status tab_bar_status_lines tab_bar_chrome hints version_banner pane_buttons bell_indicator newtab_button newtab_pad and the marks (zoom_mark zoom_on_mark close_mark min_mark newtab_mark bell_mark busy_mark busy_ms) |
| behaviour | focus_follows_mouse ctrl_d_exits scroll_lines scrollback scrollback_bytes toast_ms splash_ms hover_delay_ms double_click_ms word_separators anim_ms modal_scrim dim_unfocused float_shadow keep_dead in_band_shaders multi_attach attach_indicator size_follows shell editor |
| projects | project_roots project_layout (see workspaces) |
| colour | theme { } |
| effects | shaders { }, states { } (see shaders and chrome) |
| keys | keys { } (see keys) |
A few of those take more than one value. gap is in rows, and gap_aspect says how many columns a row is worth (2 by default, because a cell is about twice as tall as it is wide), so both gap and padding are written in rows and come out looking square. min_pane cols=24 rows=6 and min_split cols=32 rows=8 name their two floors as properties (what each floor _means_ is on the panes page), and project_roots takes one path per argument; see workspaces.
padding is the space between a pane's frame and its contents, written the way CSS does it:
padding 1 // every side
padding 0 2 // vertical, horizontal
padding 2 0 0 1 // top, right, bottom, left
Three values is refused: CSS reads it as top/horizontal/bottom, and a line whose meaning you have to look up is a line nobody can read.
Compact#
compact true
Shared borders instead of gaps.
╭────── nvim ───── ▬ □ ✕ ─┬── npm run dev ── ▬ □ ✕ ─╮
│ │ │
│ ├────── shell ──── ▬ □ ✕ ─┤
│ │ │
╰─────────────────────────┴─────────────────────────╯
What changes, and what does not:
gapstops applying.- Dividers drag exactly as gaps did, corners included, and the same hover hints appear on them. A pane whose title line is a shared divider is still dragged, by its name.
- Interior edges give up click-to-split: a one-cell line cannot honestly hold both verbs, and the whole line is the resize handle. The outer frame keeps its split handles, and the keyboard splits anything, as ever.
- Floats keep the classic frame (an overlay needs its own edge), and so does a zoomed pane or a flattened tab: nothing there is packed against anything.
- Chrome shaders run over the pane's stretch of the shared lines; a line between two panes belongs to both, which is what sharing means.
Scrollback#
scrollback 10000 // lines of history per pane; 0 keeps none
scrollback_bytes 16777216 // .. and the byte ceiling
Pane states#
A pane can be tinted depending on what "state" it is in. This way you easily make different states visually apparent.
For common tinting configuration we have some short hands:
dim_unfocused 60 // the one knob most people want
float_shadow 110 // the shade a floating pane casts; 0 for none
But they can also be more fine grainly configured:
states { // ...and the whole table underneath it
dead { grayscale amount=200; dim amount=90 }
suspended { grayscale amount=170; dim amount=60 }
scrolled { tint amount=22 color="#7aa2f7" } // follows theme's scroll_bg;
unfocused { dim amount=60 } // writing this replaces dim_unfocused
// floating { } // a float; above unfocused, so floats are never dimmed
}
The full ranking, most urgent first:
draggingdrop_hoverdrop_target,deadsuspendedbellscrolledfloatingunfocused
Exactly one wins, the first that matches.