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