Configuration#
Config Files#
toe reads configuration in this order:
| File | Purpose |
|---|---|
$XDG_CONFIG_HOME/toe/config.toml | User config |
$XDG_CONFIG_HOME/toe/languages.toml | User language config |
.toe/config.toml | Workspace config (trusted workspaces only) |
.toe/languages.toml | Workspace 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:movestill work - automatic workspace session restore/save is skipped
- workspace-local config files (
.toe/config.tomland.toe/languages.toml) are not loaded - workspace-configured language servers and formatter commands are not started from workspace config
:config-open-workspacerefuses to create or open workspace config until you trust the workspace
User config still applies in untrusted workspaces.
Trust the current workspace:
:workspace-trustRemove trust:
:workspace-untrustTrusted 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 = trueEditor 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 crlfTheme#
theme = "mocha" # frappe | latte | macchiato | mochaGeneral#
| Config key | Type | Default | Description |
|---|---|---|---|
mouse | bool | true | Enable mouse support |
insecure | bool | false | Disable workspace trust checks |
editor-config | bool | true | Respect .editorconfig files |
auto-session | bool | true | Save/restore session automatically |
file-watch | bool | true | Detect external changes to workspace files. Git state is always tracked |
nerd-fonts | bool | true | Enable enhanced UI glyphs |
default-line-ending | string | (system) | lf, crlf, or native |
Display#
| Config key | Type | Default | Description |
|---|---|---|---|
line-number | string | "absolute" | absolute or relative |
cursorline | bool | true | Highlight cursor line |
cursorcolumn | bool | false | Highlight cursor column |
scrollbar | bool | true | Show a scrollbar with diff, diagnostic, search, and cursor markers |
color-swatches | bool | true | Show swatches beside color literals |
animation | bool | true | Animate UI transitions; when off they snap instantly |
auto-size | bool | false | Widen a focused pane to fit its content: the leftmost ruler for text, a full hex row for binary, 80 columns for terminals |
text-width | int | 80 | Wrap column for :reflow and for soft wrap when wrap-at-text-width is on |
rulers | int[] | [] | Column ruler positions, e.g. [80, 120] |
bufferline | string | "never" | Show buffer tabs: never, always, multiple |
inactive-dim | int | 10 | Percent 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:
| Marker | Meaning |
|---|---|
| Cursor | A line holding a cursor |
| Diagnostic | The most severe diagnostic on the line |
| Diff | An added, modified, or removed line |
| Search | A 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 key | Type | Default | Description |
|---|---|---|---|
soft-wrap.enable | bool | false | Enable soft wrap |
soft-wrap.wrap-indicator | string | "↪ " | Continuation indicator |
soft-wrap.wrap-at-text-width | bool | false | Wrap at text-width instead of window width |
Whitespace and Indentation#
| Config key | Type | Default | Description |
|---|---|---|---|
whitespace.render | string/table | "none" | none or all, globally or by whitespace type |
indent-guides.render | bool | false | Show indent guides |
indent-guides.character | string | "│" | Guide character |
indent-guides.skip-levels | int | 0 | Indent levels to skip |
gutters.layout | string[] | built-in | Ordered list of diagnostics, line-numbers, diff, and spacer gutters |
gutters.line-numbers.min-width | int | 3 | Minimum 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 = 3Editing#
| Config key | Type | Default | Description |
|---|---|---|---|
auto-pairs | bool/table | true | Auto-insert closing brackets and quotes |
continue-comments | bool | true | Extend comment tokens on new lines |
atomic-save | bool | true | Write via temp file to prevent partial writes |
insert-final-newline | bool | true | Ensure file ends with a newline |
trim-final-newlines | bool | false | Remove trailing blank lines on save |
trim-trailing-whitespace | bool | false | Remove 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 key | Type | Default | Description |
|---|---|---|---|
auto-save.focus-lost | bool | false | Save when focus leaves the view |
auto-save.after-delay.enable | bool | false | Save after idle delay |
auto-save.after-delay.timeout | int | 3000 | Idle delay in milliseconds |
Completion#
| Config key | Type | Default | Description |
|---|---|---|---|
completion.auto | bool | true | Show the completion popup while typing |
completion.delay | int | 250 | Idle milliseconds before an automatic request |
completion.trigger-len | int | 2 | Word 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.
Search#
| Config key | Type | Default | Description |
|---|---|---|---|
search.smart-case | bool | true | Case-insensitive unless pattern has uppercase |
search.wrap-around | bool | true | Wrap search at end of file |
Scrolling#
| Config key | Type | Default | Description |
|---|---|---|---|
scrolloff | int | 5 | Lines of context kept above/below cursor |
scroll-lines | int | 3 | Lines moved per scroll step |
Cursor Shape#
| Config key | Type | Default | Description |
|---|---|---|---|
cursor-shape.normal | string | "block" | block, bar, underline, or hidden |
cursor-shape.insert | string | "bar" | Cursor shape in Insert mode |
cursor-shape.select | string | "underline" | Cursor shape in Select mode |
Status Bar#
| Config key | Type | Default | Description |
|---|---|---|---|
statusline.left | string[] | built-in | Left-aligned statusline elements |
statusline.right | string[] | built-in | Right-aligned statusline elements |
statusline.edges | string | "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 key | Type | Default | Description |
|---|---|---|---|
buffer-picker.start-position | string | "top" | top or previous |
file-explorer.hidden | bool | false | Show hidden files |
file-explorer.follow-symlinks | bool | false | Follow symlinks |
file-explorer.parents | bool | false | Include parent directories |
file-explorer.ignore-files | bool | false | Respect .ignore, .gitignore, and git exclude rules |
file-explorer.flatten-dirs | bool | true | Collapse single-child directories |
Shell#
[editor]
shell = ["sh", "-c"] # default on Unix; ["cmd", "/C"] on WindowsConfig 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.