# iTerm2 Extensions (OSC 1337)

> iTerm2's own commands: inline images, marks, user variables, the clipboard and the working directory, and its other OSC extensions.

- **Sequence:** `OSC 1337 ; Pt ST`
- **ECMA-48:** [§8.3.89 OSC – Operating System Command, p. 51](https://archive.org/details/ecma-48-5th-edition-june-1991/page/n64/mode/1up)
- **Specification:** [Proprietary Escape Codes, iTerm2 documentation](https://iterm2.com/documentation-escape-codes.html)

iTerm2, the macOS terminal, puts most of its own commands under one OSC
number, `1337`, as `OSC 1337 ; Key=value ST`; it used `OSC 50` once, and
moved because xterm uses `50` for fonts. Their definition is iTerm2's
[Proprietary Escape Codes](https://iterm2.com/documentation-escape-codes.html)
page. Some of the ones programs use most:

| `Pt` | Does | libghostty-vt |
| --- | --- | --- |
| `CurrentDir=dir` | report the shell's working directory | kept, as [OSC 7](https://control-codes.page/osc/cwd/index.html.md) |
| `Copy=:base64` | put text on the clipboard | passed to the host, as [OSC 52](https://control-codes.page/osc/clipboard/index.html.md) |
| `File=args:base64` | show a file, usually an image, inline in the text | ignored |
| `SetMark` | set a mark to jump back to | ignored |
| `SetUserVar=name=base64` | set a variable iTerm2 can show, such as in a tab title | ignored |
| `RemoteHost=user@host` | report the user and host the shell is on | ignored |
| `ShellIntegrationVersion=n` | report the version of iTerm2's shell integration | ignored |
| `CursorShape=n` | `0` block, `1` bar, `2` underline, from Konsole | ignored |
| `ReportCellSize` | ask for a cell's size in points; answered `OSC 1337 ; ReportCellSize=h;w;scale ST` | not answered |
| `ReportVariable=base64` | ask for one of iTerm2's variables | not answered |
| `ClearScrollback` | erase the scrollback | ignored |
| `StealFocus`, `RequestAttention=yes` | bring the window forward, bounce the dock icon | ignored |
| `SetProfile=name`, `SetColors=key=value` | change the session's profile or colors | ignored |
| `CopyToClipboard=name` … `EndCopy` | copy all the text in between to the clipboard | ignored |
| `SetBadgeFormat=base64`, `SetKeyLabel=key=value` | the badge, the Touch Bar's labels | ignored |
| `UnicodeVersion=n` | choose Unicode 8's or 9's character widths | ignored |

The page lists more, such as annotations, blocks and buttons, and
`Custom=id=secret:pattern` for sequences a script defines itself.
libghostty-vt recognizes every key it lists, without regard to case, and
acts on the two above; it consumes the rest without doing anything.

iTerm2 has a few extensions outside `1337` as well:

| Sequence | Does | libghostty-vt |
| --- | --- | --- |
| `OSC 4 ; -1 ; ? ST`, `OSC 4 ; -2 ; ? ST` | ask for the default foreground and background, through the [palette](https://control-codes.page/osc/palette/index.html.md) query | not answered |
| `OSC 6 ; 1 ; bg ; red ; brightness ; n ST` | color the tab; the same for `green` and `blue` | ignored |
| `OSC 21337 ; status=text ST` | set the tab's status line and indicator | ignored |
| `OSC P n rrggbb ST` | change a color, the Linux console's way | ignored |

and it documents others that this site gives pages of their own:
[notifications](https://control-codes.page/osc/notify/index.html.md) with `OSC 9`, [progress](https://control-codes.page/osc/conemu/index.html.md) with
`OSC 9 ; 4`, FinalTerm's [shell integration](https://control-codes.page/osc/prompt/index.html.md) marks with
`OSC 133`, [hyperlinks](https://control-codes.page/osc/hyperlink/index.html.md), and its answer to
[XTVERSION](https://control-codes.page/csi/xtversion/index.html.md), `iTerm2` and its version.

A default xterm has none of these and ignores them
([the OSC numbers it knows](https://github.com/ThomasDickey/xterm-snapshots/blob/xterm-411a/misc.c#L3476-L3504)).
`OSC 6` is xterm's own, for turning its special colors on and off, but
iTerm2's string does not parse as that and changes nothing
([`do_osc`](https://github.com/ThomasDickey/xterm-snapshots/blob/xterm-411a/misc.c#L4197-L4249));
`OSC 4 ; -1` is a negative color number, where xterm stops
([`ChangeAnsiColorRequest`](https://github.com/ThomasDickey/xterm-snapshots/blob/xterm-411a/misc.c#L2980-L3029)).
The cases follow xterm, so the one where libghostty-vt keeps the working
directory is a known difference.

## Validation

### ITERM2-1: The working directory

*A known difference: libghostty-vt does not pass this case.*

Input, one step per line:

```text
\e]1337;CurrentDir=/home/user\a
```

Expected screen:

```text
|______|
pwd ""
```

### ITERM2-2: The clipboard changes nothing on screen

Input, one step per line:

```text
A
\e]1337;Copy=:SGVsbG8=\a  # "Hello"
B
```

Expected screen:

```text
|AB____|
cursor 1,3
reply none
```

### ITERM2-3: The rest are consumed

Input, one step per line:

```text
A
\e]1337;SetMark\a
\e]1337;SetUserVar=name=dmFsdWU=\a
\e]1337;RemoteHost=user@example.com\a
\e]1337;CursorShape=1\a
\e]1337;File=inline=1:SGVsbG8=\a
B
```

Expected screen:

```text
|AB____|
cursor 1,3
reply none
```

### ITERM2-4: Questions are not answered

Input, one step per line:

```text
\e]1337;ReportCellSize\a
\e]1337;ReportVariable=c2Vzc2lvbi5uYW1l\a
\e]4;-1;?\a
```

Expected screen:

```text
|______|
reply none
```

### ITERM2-5: Tab colors and status

Input, one step per line:

```text
A
\e]6;1;bg;red;brightness;255\a
\e]21337;indicator=#ff0000;status=busy\a
B
```

Expected screen:

```text
|AB____|
cursor 1,3
```

### ITERM2-6: OSC P does not change a color

Input, one step per line:

```text
\e]Pg4040ff\e\\  # the foreground, the Linux console's way
\e]10;?\a
```

Expected screen:

```text
|______|
reply \e]10;rgb:0000/0000/0000\a
```

---

This is the Markdown version of <https://control-codes.page/osc/iterm2/>. On that page every validation case runs live in libghostty-vt, the terminal emulation core of Ghostty, compiled to WebAssembly.

The validation cases are written in the notation described in <https://control-codes.page/notation/index.html.md>.
