Documentation

The editor

Editor panes: files as tabs, saving that cannot lose work, reading markdown, and the keys a VS Code hand already knows.

On this page

A pane can hold a file. Ctrl+Shift+E opens an empty editor pane, and it behaves like every other pane — drag it, stash it, maximize it, resize it, zoom its text, and find it where you left it when the workspace comes back.

Its header works the way a terminal’s does. A page mark stands where a terminal shows its prompt; double-click the header to maximize the pane, and right-click it or press F2 on it to rename the pane. The focused pane keeps its header tools — Stash, Maximize, and the reading view for a markdown file — in view, while other panes show theirs when the pointer is over them. On a narrow pane they move into a ⋯ menu, so Close is always in reach.

TermHQ is still a terminal, not an IDE. The editor exists for the edit you make while something else is running: the config line an agent asked about, the README you are reading, the fix that is faster to type than to explain.

Opening a file

The Files panel is the daily door. Double-click a file and it opens in the editor pane you last used — or opens a new one if you have none. Right-click gives you the choice: Open in editor, Open in new editor pane, or the external routes — the system default, your IDE, and the editors grouped under Open with, terminal editors included. The same menu can reveal the file in File Explorer or Finder with the file selected (on Linux it opens the containing folder), Copy path, Copy relative path — the path from the panel’s root — and File history, which opens the file’s history in the Git panel.

You can also drag a file onto an editor pane — out of the Files tree, or from your desktop — and it opens there as a tab. An empty cell in the grid offers New terminal and Open file…; a file picked there opens in a new editor pane in that cell.

Opening a file that is already open just switches to its tab. Opening it in a different pane gives you a second live view of the same file — type in one and the other keeps up, because both are looking at the same file rather than at two copies of it. Duplicating an editor pane does the same thing for every tab at once: a second view of the same files, not a copy of them.

If the appropriate editor is stashed, opening a file brings it back into the grid. An editor that already holds that file is preferred, so opening it again does not leave duplicate editors on the shelf.

An empty editor pane has an Open file… button that goes through the system picker, for when the Files panel is closed or showing the Git tab.

Files are tabs

Each editor pane has its own tab strip. Scroll it with the wheel, drag tabs to reorder them, middle-click to close one. The strip keeps the active tab in view, and fades at an edge where more tabs continue. Every tab carries the same file-type icon the Files panel uses, so the tree and the strip always show the same picture. Two tabs with the same name each show their parent folder, so index.ts from src and index.ts from lib can be told apart.

The selected tab is exposed to accessibility tools. When the tab strip has keyboard focus, the left/right arrows switch files, and Home or End selects the first or last tab. The shortcuts below still work from inside the editor.

The active tab renames the pane and sets its working directory, which means the Files and Git tabs follow what you are editing exactly as they follow a shell.

Action Shortcut
Next / previous tab Ctrl+Tab / Ctrl+Shift+Tab
Next / previous tab, again Ctrl+PageDown / Ctrl+PageUp
Jump to a tab Ctrl+1 … Ctrl+8
Jump to the last tab Ctrl+9
Reopen the tab you just closed Ctrl+Shift+T
Close the tab Ctrl+W
Save Ctrl+S
Save every unsaved file in the window Ctrl+K then S

Tab cycling wraps, so with two tabs open one chord flips between them. Ctrl+9 is the last tab however many there are, the way it works in a browser. Ctrl+W on the last remaining tab closes the pane.

On macOS, ⌘ replaces Ctrl in all of these — with one exception: Ctrl+Tab stays Ctrl on every platform, because that is the cycle-through-tabs key everywhere.

Those chords are bound inside the pane, which is why they cost your shell nothing: Ctrl+S still freezes a terminal’s output and Ctrl+W still deletes a word, everywhere except an editor.

Going back

Alt+← and Alt+→ walk back and forward through the places you have been, so a go-to-definition that landed somewhere unhelpful is one key from being undone. On macOS these are Ctrl+- and Ctrl+Shift+-, because Alt+arrow is word movement there.

The history belongs to the pane, not the window. With three editors open, going back in one never scrolls another you were not looking at.

Editing

The editing surface is Monaco — the engine behind VS Code — so multi-cursor, column selection, find and replace, bracket matching and the rest of the usual moves are already there. It uses your terminal font, and Ctrl+= / - / 0 zoom one pane’s text exactly as they do a terminal’s, as does Ctrl+wheel (⌘+wheel on macOS), each showing the new size low in the pane — on top of a base size that follows your terminal font until you turn Settings → Editor → Font size follows the terminal off and set the editor’s own. That panel also carries soft word wrap and the minimap, both off by default, and a reference list of Monaco’s own keys.

The editor wears the active theme, including its surface, cursor, selections, widgets, diffs, and syntax. Built-in and hand-made themes draw syntax from the terminal palette, so an editor and terminal beside each other belong to the same workspace. Themes imported from Open VSX keep their own editor colors and syntax rules. See Theming.

Ctrl+F opens Monaco’s find widget while an editor is focused, rather than the terminal’s scrollback search. That is one of a small set of chords the editor keeps for itself — see Keyboard shortcuts.

For diagnostics, hover, completion, go-to-definition and formatting, see Language servers. Those come from tools you install; TermHQ ships none.

Saving cannot lose your work

Every save writes to a temporary file first and then swaps it into place, so a save that fails partway — a full disk, a permission, a read-only file — leaves the original exactly as it was. You get a card naming which of those happened, a Retry, and your edits still sitting in the buffer. A save that lands shows Saved on the pane for a moment.

Saves are also guarded against overwriting someone else: if the file changed on disk since you opened it, TermHQ notices before writing rather than after.

When the file changes underneath you

Agents write files. So do formatters, git checkout, and the pane next door.

  • With no unsaved edits, the tab quietly reloads within a second or two, keeping your cursor and your undo history.
  • With unsaved edits, a card appears offering three honest options: Compare (a side-by-side diff of disk against what you typed), Reload from disk (throw your edits away), or Keep my changes (your next save wins, and you knew it would).

A file deleted while you have it open is flagged rather than closed. The card waits 800 ms first — a program that saves by writing a new file and renaming it over the old one looks like a delete for an instant — and then offers Dismiss, Close tab, or Save to restore it, which writes your buffer back to disk.

These cards arrive on the file’s schedule, not yours, so they are careful with the keyboard. A card takes it only in the pane you are using, and then it focuses the card itself rather than one of its buttons, so an Enter meant for another pane can never answer it. Esc returns the keyboard to your text.

Renaming a file or folder in the Files panel carries open tabs along to the new name. A tab with unsaved edits stays where it was, because its buffer holds the only copy of that work; its card then reports the file as deleted, and saving writes it back under the old name.

Closing without losing work

Three guards, at three scales:

  1. Closing a tab with unsaved edits asks Save / Don’t save / Cancel.
  2. Closing a pane asks once about every unsaved file about to lose its last view — Save all and close, Discard and close, or Cancel. A file still open in another pane needs no question — it is not going anywhere.
  3. Closing the window with unsaved work anywhere stops and offers Save all & quit, Quit without saving, or Cancel.

If the app dies instead

Those guards cover the endings you choose. Unsaved text is also mirrored to disk about a second and a half after you stop typing, so the endings you do not choose — a crash, an end-task, a power cut — do not take your work either.

When the file reopens, the tab comes back still unsaved, dirty dot and all. There is no “restore your work?” prompt, because the answer to that question is always yes; one undo reaches the version on disk if the restore was unwanted. If the file also changed while the app was gone, you get the ordinary conflict card instead.

Records clear the moment they stop being true — on save, on reload, on undoing back to the saved text, on closing the tab. Settings → Editor → Recover unsaved changes after a crash turns the whole thing off and deletes anything it had mirrored. Text over 4 MB is not mirrored.

An orderly quit deliberately does not preserve unsaved buffers. The quit guard above exists so that is always a decision you made rather than a surprise.

Reading markdown

A .md tab has three views, and each chord toggles:

View Chord What you get
Source — The file as text
Split Ctrl+K then V Source on the left, rendered on the right
Full Ctrl+Shift+V The rendered page, filling the tab

On macOS those are ⌘+Shift+V and ⌘+K then V. The header button walks all three if you would rather not learn the chords, and the split divider drags wherever you want it — double-click to even it up.

Saving and closing work the same in every view, so Ctrl+S and Ctrl+W still do their jobs while you are reading. Find is the one that moves you: the rendered page has no search of its own, so Ctrl+F flips the tab back to source and opens the find widget there rather than appearing to do nothing.

The two halves scroll together, anchored on the source line each rendered block came from rather than on a percentage of the two heights, so a long table, a code fence or an image cannot drift them apart.

The view belongs to the tab, so a README can sit rendered beside code that stays source. And it renders the buffer, not the file: your unsaved edits show up, and an agent rewriting the file redraws it.

Headings, tables, quotes and code blocks are themed from the same colors as the rest of the app, so an imported theme carries the preview with it. Code fences are syntax highlighted, by the same colorizer the editor uses on the file itself — so a fence is painted in the theme you are already wearing, and switching themes recolors it. A fence tagged with a language name the editor does not know simply renders plain. Relative links open as another tab in the same pane; web links open a browser pane.

Two current limits: relative images do not load, and [[wikilinks]] render as plain text.

A document is never trusted. Real READMEs contain HTML, so the preview keeps what merely presents — centered blocks, badge images, collapsible sections, and the checkboxes of a - [x] task list — and drops anything that could run, embed, restyle or navigate somewhere of its own accord. Link destinations are limited to safe ones.

Images, binaries, and very large files

Images (PNG, JPEG, GIF, WebP, SVG and friends) open in an image view inside the same tab strip. Binary files, anything that is not UTF-8 text, and files over 20 MB get a plain notice rather than a mangled buffer. SVG opens as a picture — to edit one as text, use the Files panel’s Open with routes.

The Files panel while you edit

With an editor focused on a file inside a git repository, the Files panel roots itself at the repository rather than at the file’s own folder, expands the tree down to that file, and keeps its row highlighted — the shape VS Code’s explorer uses. A file outside any repository falls back to the folder view, and terminals are never affected either way.

Wandering the tree yourself is respected: nothing yanks the view back until the file you are editing actually changes. Settings → Editor → Files panel shows the repo while editing turns it off.

Inside a repository, the tree also shows where things stand with Git: a changed file’s name is tinted and carries its status letter, a folder holding changes is marked with a dot, and names Git ignores are slightly gray — hover one and it says “Ignored by Git”. Outside a repository, nothing in the tree looks different.

The tree draws a hairline down each level of indentation so a deeply nested file still reads as belonging to its folder. Most stay invisible until your pointer is in the panel; the deepest open folder on each branch stays lit, so “how far down am I on this side” is answerable at a glance.

Saving a file refreshes its row in the tree, so a size shown there is the size on disk rather than the size from the last listing.

What it does not do yet

  • No creating, renaming or deleting files from the editor — the Files panel’s right-click menu is where that lives.
  • Cursor position survives tab switches and stashing, but not an app restart.
  • UTF-8 only.
  • A read-only file refuses to save and says why, rather than offering to change the file’s permissions for you.
Type to search the documentation.
↑ ↓ navigate↵ openEsc close