Terminal
The terminal panel (`Ctrl+``) runs your shell inside the editor, with the tabs and splits you would expect and a few things that only an editor can do.
Splits and tabs
A tab holds one or more terminals side by side. Ctrl+\`` opens the panel, the+` in its
header opens another tab, and the split commands (Split Vertical, Split Left,
Split Right, Split Exchange) divide the tab you are in. Each terminal keeps its own
shell, its own scrollback and its own find bar.
Clicking what a tool printed
Cmd/Ctrl and a click on a path opens the file, at the line and column when the tool
printed them. The formats of cargo, clang, go, eslint (src/main.rs:12:5), tsc and
msbuild (src/a.ts(3,5)), Python tracebacks (File "app.py", line 12), file:// urls and
bare paths are understood; web addresses open in the browser. A path is only a link when
the file is really there, resolved against the terminal's directory and then the
workspace.
Finding in the scrollback
Cmd/Ctrl+F with the terminal focused opens a find bar over it. It searches everything the
terminal has printed, not only what is on screen: every match is highlighted, the one you
are on is picked out, and Enter / Shift+Enter walk them, scrolling the grid to each
one and wrapping round at either end. Esc closes the bar. What is selected in the
terminal when you open it is what it looks for, and the search is case-insensitive unless
the query has a capital in it. It is text, not a regular expression: a.rs:12 finds that.
Shell integration
A terminal only sees bytes, so it cannot tell a prompt from output. Shells can say so, and GraphoOS prints the script that teaches them:
# ~/.zshrc
eval "$(graphoos shell-integration zsh)"
# ~/.bashrc
eval "$(graphoos shell-integration bash)"
# ~/.config/fish/config.fish
graphoos shell-integration fish | source
It sends the marks of the OSC 133 convention (where the prompt starts, what was typed, where the output starts, and the exit code) and OSC 7 (the directory the shell is in). They print nothing, and a shell without them behaves exactly as before.
With it in place the editor knows:
- Where the shell is. A path printed by a program running in another directory is resolved against that directory, so its links work.
- What was run and how it ended. Terminal: Run a Recent Command Again lists the commands of the active terminal, most recent first, with the exit code of the ones that failed, and runs the one you pick.
How it looks
terminal.font-family, terminal.font-size and terminal.line-height
default to the editor's. terminal.letter-spacing adds pixels between
letters, terminal.cursor-blinking makes the cursor blink while the
terminal has the focus, and terminal.font-ligatures lets a font that has
ligatures join =>, != or -> (off by default, as they change what the
letters look like).
A font does not need to be installed in the system: put it in the fonts
folder of the data folder (next to settings.toml) and it is there the
next time the editor starts, for this editor only.
The tab shows a bell for a few seconds when a program rings it, and how far
a program says it is when it uses the progress sequence (OSC 9;4, as
winget and systemd do): 42 %, ✕ when it failed, ⏸ paused, … with no
end known. It is cleared when the command ends.
What programs can ask of it
What a program writes to the terminal, and what the terminal does with it
(checked in the app: tools/terminal_mouse_smoke.py,
tools/terminal_bell_progress_smoke.py, tools/terminal_osc52_smoke.py,
tools/terminal_flood_measure.py, the styles in tools/terminal_styles_look.py).
| Sequence | What it asks | What happens |
|---|---|---|
CSI 3 m, 4 m (and 4:2–4:5), 9 m, 8 m |
italic, underline (single, double, curly, dotted, dashed), strikethrough, hidden | drawn |
CSI ? 1000/1002/1003 h with 1006 h or without |
the mouse: clicks, drags, any movement; SGR or the old form | reported to the program (vim, htop, less, tmux); Shift keeps the selection for you |
CSI ? 1007 h (alternate scroll) |
the wheel as arrows in full-screen programs | less and man scroll with the wheel |
CSI ? 1004 h |
focus in and out | ESC [I / ESC [O sent |
CSI n SP q |
the cursor's shape (block, bar, underline) | drawn as asked (vim: a bar when inserting) |
BEL |
the bell | 🔔 on the tab for a few seconds |
OSC 0 / OSC 2 |
the title | the tab's title (a name you gave it wins) |
OSC 7 |
the directory | new splits and links start there |
OSC 8 |
a link | Cmd+click (Ctrl+click) opens it: files, web and mail only |
OSC 9;4 |
progress | 42 %, ✕, ⏸ or … next to the tab's name |
OSC 52 |
copy to the clipboard | copied; reading the clipboard is not answered |
OSC 133 / OSC 633 |
the shell's marks | green/red marks, Cmd+↑/↓ from command to command, the exact command line |
endless output (yes for 10 s, cat of 100 MB, 3 M lines) |
— | the editor keeps answering in 0.02–0.03 s; 100 MB in 1.2 s |
Profiles
[terminal.profiles] in the settings names the shells to offer, and
[terminal.default-profile] picks one per operating system. Open a New Terminal with a
profile is in the palette under Terminal Profile.
Source: docs/terminal.md