Editor
A real editor beside the terminal — tree-sitter colours, language servers, vim mode and a git gutter.
The pane beside the terminal exists to save the trip to another app when you want to read what the agent just wrote, or fix one line yourself. It has Zed’s colours, Zed’s keys, Zed’s pickers and Zed’s language servers over AppKit’s own text view — so input methods, undo, accessibility and the find bar come for free, and none of what makes an editor feel right needs a GPU renderer.
Opening a file
Any of these:
- a click on a file in the sidebar’s Files panel, or its Open in Editor menu item;
- ⌘-click on a printed
path:linein the terminal — it opens at that line; - a row in the ⌘F search overlay;
- the ↗ on a file card in the changes pane, a pull request review comment, or a commit’s files;
- a relative link in the Markdown preview;
- New File… in the file tree.
A double-click in the file tree does something different: it opens the file in the app you chose, outside Overterm. See Open With below.
Tabs
A file opens in a tab after the one showing, as Zed does. Two open files
with the same name show their parent folder, so Package.swift and
Package.swift are distinguishable.
An unsaved file shows a dot, which becomes a ✕ on hover. Middle-clicking a tab closes it. Closing a file with unsaved changes asks — Save, Cancel, Don’t Save.
| Key | What it does |
|---|---|
| ⌘S | Save |
| ⌘W | Close the file (not the terminal tab) |
| ⌥⌘→ | Next file |
| ⌥⌘← | Previous file |
Under the tabs is a breadcrumb — root › dir › file › symbol — and clicking
it opens the symbol picker.
The status bar along the bottom shows the problem counts, the vim mode, the line and column with the number of selections, the file’s indentation, its language, and the language server serving it.
Zoom
A file opens beside the terminal. ⇧⎋, or the header’s ⤢, shuts the terminal, inbox and changes columns so the editor has the window. ⇧⎋ again brings them back as they were — and so does choosing a tab, searching the terminal, or giving the terminal the keyboard.
It is instant, not animated: an animated collapse that finished after a quick un-zoom hid the terminal again.
Settings ▸ Editor ▸ Open files zoomed (editor.openZoomed) makes every
file open that way.
Colours
tree-sitter with Helix’s own highlight queries, pinned to the grammar
revisions that Helix release pins so the queries compile. Twenty-seven
languages are built in, including Swift, Go, TypeScript and TSX, JavaScript,
Rust, Python, C, C++, JSON, shell, Markdown, YAML, TOML, Zig, SQL, HTML, CSS,
Dockerfile, Makefile, Lua, Ruby, Java, Kotlin and diffs — matched by
extension and, where it matters, by exact filename (Dockerfile, Makefile,
Gemfile, .zshrc, Cargo.lock).
Parsing is incremental and off the main thread, and only what is on screen
(plus a screen either side) is coloured. Injections are parsed as their own
language over their own ranges, so a fenced code block in Markdown and a
<script> in HTML are highlighted properly. The palette is Zed’s One Dark
and One Light, chosen by the terminal’s background.
A file over about 8 million characters stays plain.
Code intelligence
Settings ▸ Editor ▸ Use language servers (editor.languageServers, on
by default) starts one server per language and project root, on a file’s
first open.
| Language | Server, in the order it is tried |
|---|---|
| Go | gopls |
| TypeScript, JavaScript | typescript-language-server, then vtsls |
| Python | basedpyright-langserver, then pyright-langserver |
| Rust | rust-analyzer |
| Swift | sourcekit-lsp |
| C, C++, Objective-C | clangd |
| JSON | vscode-json-language-server |
| YAML | yaml-language-server |
| Shell | bash-language-server |
Nothing is installed for you. A GUI app’s PATH has no Homebrew, so the
usual places are searched by hand: /opt/homebrew/bin, /usr/local/bin,
~/go/bin, ~/.cargo/bin, ~/.local/bin, /usr/bin. For
sourcekit-lsp and clangd it also looks in Xcode’s toolchain and the
Command Line Tools, and asks xcrun — but only when one of those is
actually installed, so xcrun never pops up its own install dialog.
Failing all that, it uses the servers Zed has already downloaded under
~/Library/Application Support/Zed, running the Node-based ones with
whichever node it can find, including Zed’s own.
The project root is the nearest ancestor holding that language’s marker
(go.mod, Cargo.toml, tsconfig.json, Package.swift,
compile_commands.json, pyproject.toml…), else the nearest .git, else
the file’s folder.
What you get:
| Feature | How it reaches you |
|---|---|
| Problems | gutter dots and underlines, counted in the status bar; F8 and ⇧F8 step through them and show the hover |
| Completions | as you type when editor.completions is on, and always on ⌃Space. The file’s own words are offered as a fallback, badged abc |
| Hover | resting the pointer, or ⌥F1 |
| Go to definition | F12 — one result jumps, several open a picker |
| References | ⇧F12 — a picker of path:line with the line’s text |
| Symbols | ⇧⌘O and the breadcrumb; falls back to the grammar’s own tags query when the server has nothing |
| Formatting | ⌥⇧F, and format on save |
Without a server the editor still opens, colours, edits and saves; there are no diagnostics, and that is the whole difference.
Vim mode
Settings ▸ Editor ▸ Vim mode (editor.vimMode, off by default). The
modes are normal, insert, visual, visual line, replace and the command line,
shown in the status bar as -- NORMAL -- and so on, with pending keys
appended. The cursor is a block everywhere but insert, replace and the
command line.
As in Zed, the unnamed register is the system clipboard: a yy is a
copy. Named registers stay internal.
The usual vocabulary is there — motions, text objects, operators, marks,
counts, ., visual modes, zz/zt/zb, searches with / and ?. The ex
commands the editor answers are :w, :q, :q!, :wq, :x, :wa,
:qa and :noh; anything else reports “Not an editor command”.
Relative line numbers has its own setting.
Markdown preview
⇧⌘V, or the eye in the header, which only appears on a Markdown file.
The file is rendered by Foundation’s own Markdown parser into real text
blocks — code and quotes on a surface, tables as tables. There is no web
view and no bundled script. It follows the file as you type or as an agent
rewrites it, and a relative link in it opens that file in the editor; an
http, https or mailto link goes to your browser.
The git gutter
Settings ▸ Editor ▸ Mark lines changed since the last commit
(editor.gitGutter, on by default). The file at HEAD is fetched with
git show HEAD:./<name> and diffed by line off the main thread shortly
after you stop typing: added and modified lines get a bar at the gutter’s
edge, a deletion gets a small triangle.
The gutter also carries the line numbers — relative when you have asked for that — and a dot for the worst problem on a line. Clicking the gutter selects that whole line.
Saving
⌘S. With Format on save (editor.formatOnSave, off by
default, and dependent on language servers) the formatter runs first.
If the file changed on disk since you opened it, saving asks:
“foo.swift” changed on disk — something else saved it since you opened it, an agent, most likely. Saving replaces those changes with yours.
with Cancel first and Save Anyway second.
Some files cannot be opened for editing at all, and the pane says which: not a regular file, larger than 5 MB, binary (a NUL byte in the first 8 KB), or not UTF-8.
Open With
A file leaves Overterm — the file tree’s double-click, its Open in Package.swift, something unexpected for .md, a terminal for .sh.
The first time, a sheet asks “Open files with which app?” with a pop-up of candidates and their icons, and remembers the answer. There is never a silent fall-back to the system default.
Open With ▸ — the file menu’s submenu, and the right-click on ↗ — lists the candidates with the one in use ticked, then Other… for anything else. Picking one opens the file there and makes it the one.
The candidate order is fixed: installed code editors first, whether or not they claim the file’s type (a Makefile is still code) — VS Code, VS Code Insiders, Cursor, Windsurf, Antigravity, Zed, Xcode, Sublime Text, Nova, BBEdit, then the JetBrains IDEs — then the system default, marked “(default)”, then everything else that can open it, by name. Overterm itself is never offered, even though it claims text files so Finder can list it.
Web links from the terminal and ports from Tab Info still go to the system opener or the browser, not through this.
Editor keys
The editor’s keys are a scope of their own: they apply only while the editor has the keyboard, and they are never menu shortcuts. That is what lets ⌘D add the next match here and split a pane in the terminal. The full list is in Keyboard shortcuts.
⌘F is left alone deliberately: it is AppKit’s incremental find bar in the editor and the terminal’s search overlay in the terminal.