# Copy Rectangular Area (DECCRA)

> Copy a rectangle of the screen, characters and attributes, to another place.

- **Sequence:** `CSI Pm $ v`
- **Defaults:** the source is the whole page; the destination is line 1, column 1
- **DEC STD 070:** [§5.12.1 Copy Rectangular Area, p. 5-169](https://archive.org/details/bitsavers_decstandar0VideoSystemsReferenceManualDec91_74264381/page/n423/mode/1up)
- **VT510:** [DECCRA—Copy Rectangular Area](https://vt100.net/docs/vt510-rm/DECCRA.html)

Copy a rectangle of characters, with their attributes, to another place.
The eight parameters are

    CSI Pts ; Pls ; Pbs ; Prs ; Pps ; Ptd ; Pld ; Ppd $ v

`Pts`, `Pls`, `Pbs` and `Prs` are the top line, left column, bottom line
and right column of the source, `Ptd` and `Pld` the top line and left
column of the destination, and `Pps` and `Ppd` the pages of each. Left
out, the source is the whole page and the destination its top-left corner. A
value past the edge of the page is taken as the edge, and a source whose top
is below its bottom, or whose left is right of its right, makes the whole
sequence ignored. The cursor does not move.

The copy is made as if the source were read in full before anything was
written, so a destination that overlaps the source still gets the source as
it was. Whatever of the destination falls off the page is clipped. Origin
mode makes the coordinates count from the margins; the margins do not
otherwise matter.

DECCRA is a VT420 function, at level 4 in DEC STD 070. xterm, a VT420 unless
told otherwise, implements it
([`CASE_DECCRA`](https://github.com/ThomasDickey/xterm-snapshots/blob/xterm-411a/charproc.c#L5648-L5655),
[`xtermParseRect`](https://github.com/ThomasDickey/xterm-snapshots/blob/xterm-411a/screen.c#L2633-L2652),
[`ScrnCopyRectangle`](https://github.com/ThomasDickey/xterm-snapshots/blob/xterm-411a/screen.c#L2797-L2893)),
ignoring the page numbers, and the cases follow xterm and esctest2's
`deccra.py`.

libghostty-vt, a VT220 (see [DA](https://control-codes.page/csi/da/index.html.md)), has no case for `$ v` in
`stream.zig`, so it ignores DECCRA, and the cases are known differences.

## Validation

### DECCRA-1: Copy a block

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

Input, one step per line:

```text
AB\r\n
CD
\e[1;1;2;2;1;3;4;1$v
```

Expected screen:

```text
|AB____|
|CD____|
|___AB_|
|___CD_|
cursor 2,3
```

### DECCRA-2: Overlapping source and destination

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

Input, one step per line:

```text
ABCD
\e[1;1;1;4;1;1;3;1$v
```

Expected screen:

```text
|ABABCD|
```

### DECCRA-3: Clipped at the edge of the screen

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

Input, one step per line:

```text
AB\r\n
CD
\e[1;1;2;2;1;2;6;1$v
```

Expected screen:

```text
|AB____|
|CD___A|
|_____C|
```

### DECCRA-4: The destination left out

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

Input, one step per line:

```text
\e[2;3H
XY
\e[2;3;2;4$v
```

Expected screen:

```text
|XY____|
|__XY__|
```

### DECCRA-5: Counted from the margins in origin mode

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

Input, one step per line:

```text
\e[2;1H
AB
\e[2;3r   # region is lines 2 and 3
\e[?6h    # origin mode
\e[1;1;1;2;1;2;1$v
```

Expected screen:

```text
|______|
|AB____|
|AB____|
|______|
cursor 2,1
```

---

This is the Markdown version of <https://control-codes.page/csi/deccra/>. 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>.
