Configuration#

Config Files#

toe reads configuration in this order:

FilePurpose
$XDG_CONFIG_HOME/toe/config.tomlUser config
$XDG_CONFIG_HOME/toe/languages.tomlUser language config
.toe/config.tomlWorkspace config (trusted workspaces only)
.toe/languages.tomlWorkspace language config (trusted workspaces only)

$XDG_CONFIG_HOME defaults to ~/.config.

Later TOML values override earlier ones.

Open your user config directly: :config-open Open workspace config: :config-open-workspace Reload after editing: :config-reload

Interface Language#

toe selects English, German, French, or Italian from LC_ALL, LC_MESSAGES, then LANG. Unsupported locales use English.

Workspace Trust#

toe treats a directory with .git or .toe as a workspace. Workspace trust is the explicit opt-in that lets workspace-controlled config and tooling affect toe.

Until a workspace is trusted:

  • normal file editing, :write, :write-all, and :move still work
  • automatic workspace session restore/save is skipped
  • workspace-local config files (.toe/config.toml and .toe/languages.toml) are not loaded
  • workspace-configured language servers and formatter commands are not started from workspace config
  • :config-open-workspace refuses to create or open workspace config until you trust the workspace

User config still applies in untrusted workspaces.

Trust the current workspace:

:workspace-trust

Remove trust:

:workspace-untrust

Trusted workspaces are stored in $XDG_DATA_HOME/toe/trusted_workspaces (normally ~/.local/share/toe/trusted_workspaces). If a workspace is untrusted at startup, toe shows a status message asking you to run :workspace-trust.

To bypass trust checks entirely, set in your user config:

[editor]
insecure = true

Editor Configuration#

Except for the top-level theme key, the settings below belong under [editor] in config.toml. They can also be changed for the current session with :set <key> <value>, :get <key>, and :toggle <key> for booleans, or :toggle <key> <value>... to cycle a key through the given values. Lists and tables use TOML syntax. Completion after :set shows the available keys.

Examples:

:set gutters.layout ["diagnostics", "line-numbers", "diff"]
:set statusline.left ["mode!", "file-name"]
:set whitespace.render.tab all
:set whitespace.characters.tab "→"
:set auto-pairs {"(" = ")", "[" = "]"}
:set buffer-picker.start-position previous
:toggle file-explorer.hidden
:toggle default-line-ending lf crlf

Theme#

theme = "mocha"   # frappe | latte | macchiato | mocha

General#

Config keyTypeDefaultDescription
mousebooltrueEnable mouse support
insecureboolfalseDisable workspace trust checks
editor-configbooltrueRespect .editorconfig files
auto-sessionbooltrueSave/restore session automatically
file-watchbooltrueDetect external changes to workspace files. Git state is always tracked
nerd-fontsbooltrueEnable enhanced UI glyphs
default-line-endingstring(system)lf, crlf, or native

Display#

Config keyTypeDefaultDescription
line-numberstring"absolute"absolute or relative
cursorlinebooltrueHighlight cursor line
cursorcolumnboolfalseHighlight cursor column
scrollbarbooltrueShow a scrollbar with diff, diagnostic, search, and cursor markers
color-swatchesbooltrueShow swatches beside color literals
animationbooltrueAnimate UI transitions; when off they snap instantly
auto-sizeboolfalseWiden a focused pane to fit its content: the leftmost ruler for text, a full hex row for binary, 80 columns for terminals
text-widthint80Wrap column for :reflow and for soft wrap when wrap-at-text-width is on
rulersint[][]Column ruler positions, e.g. [80, 120]
bufferlinestring"never"Show buffer tabs: never, always, multiple
inactive-dimint10Percent to darken unfocused editor panes; 0 disables

Scrollbar#

Each editor pane and each file preview reserves its rightmost column for a scrollbar. The thumb shows which part of the document is on screen, and markers show where the interesting lines are, so changes, problems, and matches stay visible while they are scrolled out of sight:

MarkerMeaning
CursorA line holding a cursor
DiagnosticThe most severe diagnostic on the line
DiffAn added, modified, or removed line
SearchA line with a match for the current search

Each marker takes half a row. A half-row standing for a single document line draws a hairline rule, and one standing for several draws a half block, so the weight of a marker tells how much it covers. Where markers collide on one half-row, it shows the most important one, in the order above: a cursor beats a diagnostic, a diagnostic beats a diff, and a diff beats a search match.

Click the bar to scroll to that part of the document, or drag along it to scroll continuously. This works on a preview’s bar as well as an editor pane’s. Neither moves the cursor, so the view stays where it was put until the cursor moves again.

Set scrollbar to false to hide it and give the column back to the text.

Diff markers need version control, and search markers appear while search highlights are on.

Soft Wrap#

Config keyTypeDefaultDescription
soft-wrap.enableboolfalseEnable soft wrap
soft-wrap.wrap-indicatorstring"↪ "Continuation indicator
soft-wrap.wrap-at-text-widthboolfalseWrap at text-width instead of window width

Whitespace and Indentation#

Config keyTypeDefaultDescription
whitespace.renderstring/table"none"none or all, globally or by whitespace type
indent-guides.renderboolfalseShow indent guides
indent-guides.characterstring"│"Guide character
indent-guides.skip-levelsint0Indent levels to skip
gutters.layoutstring[]built-inOrdered list of diagnostics, line-numbers, diff, and spacer gutters
gutters.line-numbers.min-widthint3Minimum gutter width

Whitespace rendering can be set separately for space, nbsp, tab, and newline, and each display character can be replaced:

[editor.whitespace]
render = { default = "none", tab = "all", newline = "all" }

[editor.whitespace.characters]
space = "·"
nbsp = "⍽"
tab = "→"
tabpad = " "
newline = "⏎"

Use whitespace.render.<type> and whitespace.characters.<type> to change individual values at runtime.

To change gutter order or visibility:

[editor.gutters]
layout = ["diagnostics", "spacer", "line-numbers", "spacer", "diff"]

[editor.gutters.line-numbers]
min-width = 3

Editing#

Config keyTypeDefaultDescription
auto-pairsbool/tabletrueAuto-insert closing brackets and quotes
continue-commentsbooltrueExtend comment tokens on new lines
atomic-savebooltrueWrite via temp file to prevent partial writes
insert-final-newlinebooltrueEnsure file ends with a newline
trim-final-newlinesboolfalseRemove trailing blank lines on save
trim-trailing-whitespaceboolfalseRemove trailing spaces on save

auto-pairs also accepts a table of custom opening and closing characters:

auto-pairs = { "(" = ")", "[" = "]", "{" = "}" }

At runtime, auto-pairs accepts a boolean or an inline table of custom pairs.

Auto-Save#

Config keyTypeDefaultDescription
auto-save.focus-lostboolfalseSave when focus leaves the view
auto-save.after-delay.enableboolfalseSave after idle delay
auto-save.after-delay.timeoutint3000Idle delay in milliseconds

Completion#

Config keyTypeDefaultDescription
completion.autobooltrueShow the completion popup while typing
completion.delayint250Idle milliseconds before an automatic request
completion.trigger-lenint2Word characters typed before an automatic request

Automatic completion is in addition to Ctrl+x, which requests completions at any time, and to the trigger characters a language server advertises.

Config keyTypeDefaultDescription
search.smart-casebooltrueCase-insensitive unless pattern has uppercase
search.wrap-aroundbooltrueWrap search at end of file

Scrolling#

Config keyTypeDefaultDescription
scrolloffint5Lines of context kept above/below cursor
scroll-linesint3Lines moved per scroll step

Cursor Shape#

Config keyTypeDefaultDescription
cursor-shape.normalstring"block"block, bar, underline, or hidden
cursor-shape.insertstring"bar"Cursor shape in Insert mode
cursor-shape.selectstring"underline"Cursor shape in Select mode

Status Bar#

Config keyTypeDefaultDescription
statusline.leftstring[]built-inLeft-aligned statusline elements
statusline.rightstring[]built-inRight-aligned statusline elements
statusline.edgesstring"arrow"Divider shape: arrow, round, slant, or line. Without nerd fonts, line is used whatever the setting

Valid statusline elements: mode, file-name, file-base-name, file-absolute-path, file-status, file-modified-indicator, read-only-indicator, file-encoding, file-line-ending, file-indent-style, file-type, diagnostics, selections, primary-selection-length, position, position-percentage, total-line-numbers, spinner, version-control, macro-recording, and pane-maximized.

file-status marks a read-only or modified document with an icon next to its name, and shows both marks when both apply. read-only-indicator and file-modified-indicator draw the same marks, one condition each, for a statusline that wants them apart. Without nerd fonts the marks fall back to ro and *.

macro-recording and pane-maximized report editor-wide state rather than the pane’s own. macro-recording draws only on the statusline in the bottom-right corner of the frame, so a split shows it once.

When the pane is too narrow, toe drops unpinned status items from the right section and then the left. Suffix an element with ! (for example "mode!" or "position!") to keep it visible.

[editor.statusline]
left = ["mode!", "file-name", "read-only-indicator", "file-modified-indicator"]
right = ["diagnostics", "selections", "position!"]

The selected register and the macro-recording indicator appear on the statusline in the bottom-right corner of the frame.

Example:

[editor.statusline]
left = ["mode", "file-name", "file-modified-indicator"]
right = ["version-control", "diagnostics", "position"]

Pickers#

Dragging a picker’s split divider adjusts its list/preview ratio, and dragging its border resizes it. Both are remembered per picker by auto-session rather than set in config.

TOML keyTypeDefaultDescription
buffer-picker.start-positionstring"top"top or previous
file-explorer.hiddenboolfalseShow hidden files
file-explorer.follow-symlinksboolfalseFollow symlinks
file-explorer.parentsboolfalseInclude parent directories
file-explorer.ignore-filesboolfalseRespect .ignore, .gitignore, and git exclude rules
file-explorer.flatten-dirsbooltrueCollapse single-child directories

Shell#

[editor]
shell = ["sh", "-c"]   # default on Unix; ["cmd", "/C"] on Windows

Config Example#

theme = "mocha"

[editor]
cursorline = true
soft-wrap.enable = true
auto-session = true
rulers = [80, 120]

[editor.cursor-shape]
normal = "block"
insert = "bar"

Language Config#

See Language Servers for languages.toml configuration.