Skip to content

A tour

Every screen Textchum has, in the order you would meet them, on both shells: the macOS app on the left and the GTK one on the right. The screenshots come from a small fictional project — Harbor, a port broker that exists only so these pictures have something honest to show — and each follows your own light or dark setting.

The two shells are the same editor over the same core, so the pictures mostly differ in what the platform contributes: window furniture, where a panel is drawn, and which font the system hands over.

The window

One document per window, tabs by default, and a navigator drawer with two halves: the open buffers grouped by project on top, that project's file tree below.

The editor window: sidebar with open buffers and the project tree, a Rust file with syntax highlighting and line numbers (macOS) The editor window: sidebar with open buffers and the project tree, a Rust file with syntax highlighting and line numbers (macOS)

macOS

The editor window: sidebar with open buffers and the project tree, a Rust file with syntax highlighting and line numbers (Linux) The editor window: sidebar with open buffers and the project tree, a Rust file with syntax highlighting and line numbers (Linux)

Linux

The title bar carries the facts about the document — encoding, size, language, and the problem count once a language server has an opinion. The tree follows along: switching tabs expands the path to the current file and highlights it.

Right-clicking in the text opens the editor's own menu: Jump to Definition, Find References, Rename Symbol, the diagnostics of the line, Blame Line, Format Document and File Properties, beside cut, copy, paste and the spelling suggestions. Those commands act on the character that was clicked rather than on the caret, which the click leaves where it was. What the document has no use for is not there — no server running means no Find References, no findings means no diagnostics rows.

Folding

Fold (⌘[, Ctrl+[ on Linux) closes the block that opens on the caret's line; Fold All (⌥⌘[, Ctrl+Alt+[) closes every block that is not inside one already closed, and Unfold All (⌘], Ctrl+]) opens them again. A closed block shows its opening line with an ellipsis after it.

The blocks come from the same tree the colouring uses, and the folds belong to the document: closing a function in one view closes it in every view of that file.

Columns

A window is a row of columns. A column shows one file at a time and holds one or more views of it, stacked.

New Column (⌘\, Ctrl+\ on Linux) puts a column beside this one, showing the same file until it is given another; Close Column (⇧⌘\, Ctrl+Shift+\) takes one away. Second View (⌥⌘\, Ctrl+Alt+\) stacks another view of the column's file under the first, and Close View (⇧⌥⌘\, Ctrl+Alt+Shift+\) removes it. Next Pane (⌥⌘, Ctrl+Alt+) moves the keyboard through them.

Each view scrolls on its own, which is the point: reading the top of a file while editing the bottom of it. A column owns the file it shows, so changing its tab moves every view in it to the new file.

Both sides are one document. There is one history and one save, so an edit on either side is the same edit, and neither view can be a stale copy of the other. Both toolkits are built for this — a text buffer that several views share — and what does not come free is the colouring, since on macOS that lives on the layout rather than the text; each view gets painted.

Language servers

Diagnostics arrive as tinted marks in the text and a count in the title bar. Nothing about the editor waits on the server: it attaches when it can, and says so when it cannot.

A warning from the language server marked in the text, counted in the title bar (macOS) A warning from the language server marked in the text, counted in the title bar (macOS)

macOS

A warning from the language server marked in the text, counted in the title bar (Linux) A warning from the language server marked in the text, counted in the title bar (Linux)

Linux

Resting the pointer on a symbol shows the server's documentation, with the Markdown it sends rendered — code blocks monospaced, emphasis styled. ⌃⌘H asks for the symbol under the caret instead, which works with mouse hover switched off.

Hover documentation over a function, showing a rendered signature and prose (macOS) Hover documentation over a function, showing a rendered signature and prose (macOS)

macOS

Hover documentation over a function, showing a rendered signature and prose (Linux) Hover documentation over a function, showing a rendered signature and prose (Linux)

Linux

Go to Line (⌘L, Ctrl+L on Linux) takes a number, or the whole src/main.rs:412:8 pasted straight out of a build log — the file name and the trailing noise are ignored, the line is centred, and Go Back returns to where reading was interrupted.

A change bar runs down the left of the gutter, saying which lines differ from the file as it stands in git: a green stripe for a line that is new, blue for one that reads differently, and a red wedge on the boundary where lines were deleted — deleted lines occupy no height, so a stripe would have nothing to cover. It follows the buffer rather than the file on disk, so it is right before you save, and it is recomputed once typing settles. A file with no committed version, or one outside a repository, gets no marks rather than every line claimed as new.

Blame Line (⌃⌘B, Ctrl+Alt+B on Linux) asks git who last touched the line under the caret: the commit, the author and when they wrote it, the subject and the message body — where the reasoning usually is — and the file's name at the time if it has been renamed since. The commit is one button away from the clipboard, which is most of what the answer is for. A line typed since the last commit says so rather than borrowing somebody else's.

It asks with the buffer's text, not the file on disk, so an unsaved edit above the caret cannot quietly shift the answer onto the neighbouring line.

In a line's leading whitespace, two keys mean something more than usual. Backspace deletes back to the previous tab stop rather than one space at a time, and Tab lines the line up with the nearest non-blank line above it — pressing it again, once already level, goes one level deeper. Anywhere else in the line both keys are themselves: it is the position that decides, not a mode, which is what keeps them from surprising anyone. A tab-indented line is left to its tab character, which is already one press per level.

With text selected, typing an opening bracket or quote — (, [, {, ', ", ` — wraps the selection in the pair instead of replacing it. What was wrapped stays selected, so pressing another one wraps that in turn: [, ( and { over hello give [({hello})]. Typing anything else replaces the selection as it always did.

Completions appear as you type after identifier characters and .; ↑/↓ choose, ⏎ or ⇥ accept, ⎋ dismisses. A snippet arrives with its first placeholder selected, so typing replaces it; ⇥ moves to the next placeholder and ⇧⇥ back, and one written twice mirrors as you type. The last ⇥ leaves the caret where the snippet asked for it and hands the keys back.

The completion popup listing members with their types (macOS) The completion popup listing members with their types (macOS)

macOS

The completion popup listing members with their types (Linux) The completion popup listing members with their types (Linux)

Linux

⇧⌘O lists the file's symbols, filterable from the keyboard.

The document outline panel, listing a struct and its methods (macOS) The document outline panel, listing a struct and its methods (macOS)

macOS

The document outline panel, listing a struct and its methods (Linux) The document outline panel, listing a struct and its methods (Linux)

Linux

View ▸ Language Server Status answers "is my server alive?" — what runs where, and the session's recent transitions, refreshed live.

The language server status panel listing one running instance and its status transitions (macOS) The language server status panel listing one running instance and its status transitions (macOS)

macOS

The language server status panel listing one running instance and its status transitions (Linux) The language server status panel listing one running instance and its status transitions (Linux)

Linux

Finding things

⌘T opens files by fuzzy name within the project. The scope is walked once and matched in memory, so typing stays instant; the status strip says how many of how many files matched, and which keys do what — ⏎ searches, ⌘⏎ opens, so refining a query never opens a file by accident.

Open Quickly: a fuzzy query, one matching path, and the status strip naming the keys (macOS) Open Quickly: a fuzzy query, one matching path, and the status strip naming the keys (macOS)

macOS

Open Quickly: a fuzzy query, one matching path, and the status strip naming the keys (Linux) Open Quickly: a fuzzy query, one matching path, and the status strip naming the keys (Linux)

Linux

⇧⌘F searches contents with a regular expression, with stacked filters that refine the results by line text or file path. The status line always says what the search did — matches, files searched, or why nothing was read.

Find in Project: regex results with a file filter applied (macOS) Find in Project: regex results with a file filter applied (macOS)

macOS

Find in Project: regex results with a file filter applied (Linux) Find in Project: regex results with a file filter applied (Linux)

Linux

⇧⌘P is the command palette: every menu action, fuzzy-searchable, with its shortcut alongside.

The command palette listing menu actions and their shortcuts (macOS) The command palette listing menu actions and their shortcuts (macOS)

macOS

The command palette listing menu actions and their shortcuts (Linux) The command palette listing menu actions and their shortcuts (Linux)

Linux

Markdown and prose

Markdown documents open with a live preview beside the text, and the prose spell checker — off until you pick a dictionary — marks misspellings in purple, distinct from diagnostics. In code it looks only at comments; identifiers are never flagged.

A Markdown document with its rendered preview beside it (macOS) A Markdown document with its rendered preview beside it (macOS)

macOS

A Markdown document with its rendered preview beside it (Linux) A Markdown document with its rendered preview beside it (Linux)

Linux

Misspellings marked in prose, with the rendered preview alongside (macOS) Misspellings marked in prose, with the rendered preview alongside (macOS)

macOS

Misspellings marked in prose, with the rendered preview alongside (Linux) Misspellings marked in prose, with the rendered preview alongside (Linux)

Linux

Settings

Settings are a plain JSON file that the window edits; the file is the escape hatch, and it is watched, so an edit in another editor applies at once.

Settings, General tab: appearance, theme, placement, font, and the editor toggles (macOS) Settings, General tab: appearance, theme, placement, font, and the editor toggles (macOS)

macOS

Settings, General tab: appearance, theme, placement, font, and the editor toggles (Linux) Settings, General tab: appearance, theme, placement, font, and the editor toggles (Linux)

Linux

Projects decides how project roots are found, what the tree hides, and which editor settings a root overrides.

Settings, Projects tab: detection toggles, hide patterns, and per-project overrides (macOS) Settings, Projects tab: detection toggles, hide patterns, and per-project overrides (macOS)

macOS

Settings, Projects tab: detection toggles, hide patterns, and per-project overrides (Linux) Settings, Projects tab: detection toggles, hide patterns, and per-project overrides (Linux)

Linux

Hidden names are glob patterns, edited one per line, with a menu that adds a named preset in one click.

The hide editor open as a popover, one pattern per line, with the Add preset menu (macOS) The hide editor open as a popover, one pattern per line, with the Add preset menu (macOS)

macOS

The hide editor open as a popover, one pattern per line, with the Add preset menu (Linux) The hide editor open as a popover, one pattern per line, with the Add preset menu (Linux)

Linux

Presets edits those named sets the same way. They start as built-ins; edit any of them and your list takes over, so a preset you delete stays deleted until you restore the built-ins. This screen and the next have no picture from the GTK shell because they are not screens there: presets sit inside Projects, and preprocessors inside Language Servers.

Settings, Presets tab: named glob sets, each editable one pattern per
line Settings, Presets tab: named glob sets, each editable one pattern per
line

Language Servers overrides which command serves a language, for every project or for one root.

Settings, Language Servers tab: default and per-project server commands (macOS) Settings, Language Servers tab: default and per-project server commands (macOS)

macOS

Settings, Language Servers tab: default and per-project server commands (Linux) Settings, Language Servers tab: default and per-project server commands (Linux)

Linux

Preprocessors runs formatters before every save: one command per line, each reading the document on standard input and writing it back on standard output.

Settings, Preprocessors tab: per-language command chains Settings, Preprocessors tab: per-language command chains

Small things

⇧⌘N starts a new document in a chosen language, filtered from the keyboard, so highlighting works before the first save.

The New with Format picker, filtering the language list (macOS) The New with Format picker, filtering the language list (macOS)

macOS

The New with Format picker, filtering the language list (Linux) The New with Format picker, filtering the language list (Linux)

Linux

And the About panel says which build you are running — a real version, even for a local build.

The About panel showing the build version, author, repository, and license (macOS) The About panel showing the build version, author, repository, and license (macOS)

macOS

The About panel showing the build version, author, repository, and license (Linux) The About panel showing the build version, author, repository, and license (Linux)

Linux