Skip to content
overterm
Documentation

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:line in 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 item, the editor header’s ↗ — in the app you picked, not the macOS default for its type. The default was the wrong answer too often: Xcode for 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.