terminal: CUF handles right margin

This commit is contained in:
Mitchell Hashimoto
2023-10-07 08:42:08 -07:00
parent 5be96f34cd
commit c089c37b90
2 changed files with 160 additions and 6 deletions

View File

@ -1439,16 +1439,21 @@ pub fn cursorLeft(self: *Terminal, count_req: usize) void {
/// maximum move distance then it is internally adjusted to the maximum. /// maximum move distance then it is internally adjusted to the maximum.
/// This sequence will not scroll the screen or scroll region. If amount is /// This sequence will not scroll the screen or scroll region. If amount is
/// 0, adjust it to 1. /// 0, adjust it to 1.
/// TODO: test pub fn cursorRight(self: *Terminal, count_req: usize) void {
pub fn cursorRight(self: *Terminal, count: usize) void {
const tracy = trace(@src()); const tracy = trace(@src());
defer tracy.end(); defer tracy.end();
self.screen.cursor.x += if (count == 0) 1 else count; // Always resets pending wrap
self.screen.cursor.pending_wrap = false; self.screen.cursor.pending_wrap = false;
if (self.screen.cursor.x >= self.cols) {
self.screen.cursor.x = self.cols - 1; // The max the cursor can move to depends where the cursor currently is
} const max = if (self.screen.cursor.x <= self.scrolling_region.right)
self.scrolling_region.right
else
self.cols - 1;
const count = @max(count_req, 1);
self.screen.cursor.x = @min(max, self.screen.cursor.x +| count);
} }
/// Move the cursor down amount lines. If amount is greater than the maximum /// Move the cursor down amount lines. If amount is greater than the maximum
@ -4044,3 +4049,69 @@ test "Terminal: cursorUp resets wrap" {
try testing.expectEqualStrings("ABCDX", str); try testing.expectEqualStrings("ABCDX", str);
} }
} }
test "Terminal: cursorRight resets wrap" {
const alloc = testing.allocator;
var t = try init(alloc, 5, 5);
defer t.deinit(alloc);
for ("ABCDE") |c| try t.print(c);
try testing.expect(t.screen.cursor.pending_wrap);
t.cursorRight(1);
try testing.expect(!t.screen.cursor.pending_wrap);
try t.print('X');
{
var str = try t.plainString(testing.allocator);
defer testing.allocator.free(str);
try testing.expectEqualStrings("ABCDX", str);
}
}
test "Terminal: cursorRight to the edge of screen" {
const alloc = testing.allocator;
var t = try init(alloc, 5, 5);
defer t.deinit(alloc);
t.cursorRight(100);
try t.print('X');
{
var str = try t.plainString(testing.allocator);
defer testing.allocator.free(str);
try testing.expectEqualStrings(" X", str);
}
}
test "Terminal: cursorRight left of right margin" {
const alloc = testing.allocator;
var t = try init(alloc, 5, 5);
defer t.deinit(alloc);
t.scrolling_region.right = 2;
t.cursorRight(100);
try t.print('X');
{
var str = try t.plainString(testing.allocator);
defer testing.allocator.free(str);
try testing.expectEqualStrings(" X", str);
}
}
test "Terminal: cursorRight right of right margin" {
const alloc = testing.allocator;
var t = try init(alloc, 5, 5);
defer t.deinit(alloc);
t.scrolling_region.right = 2;
t.screen.cursor.x = 3;
t.cursorRight(100);
try t.print('X');
{
var str = try t.plainString(testing.allocator);
defer testing.allocator.free(str);
try testing.expectEqualStrings(" X", str);
}
}

View File

@ -0,0 +1,83 @@
import VTSequence from "@/components/VTSequence";
# Cursor Forward (CUF)
<VTSequence sequence={["CSI", "Pn", "C"]} />
Move the cursor `n` cells right.
The parameter `n` must be an integer greater than or equal to 1. If `n` is less than
or equal to 0, adjust `n` to be 1. If `n` is omitted, `n` defaults to 1.
This sequence always unsets the pending wrap state.
The rightmost boundary the cursor can move to is determined by the current
cursor column and the [right margin](#TODO). If the cursor begins to the right
of the right margin, modify the right margin to be the rightmost column
of the screen for the duration of the sequence. The rightmost column the cursor
can be on is the right margin.
Move the cursor `n` cells to the right up to and including the rightmost boundary.
This sequence never wraps or modifies cell content. This sequence is not affected
by any terminal modes.
## Validation
### CUF V-1: Pending Wrap is Unset
```bash
cols=$(tput cols)
printf "\033[${cols}G" # move to last column
printf "A" # set pending wrap state
printf "\033[C" # move forward one
printf "XYZ"
```
```
|_________X|
|YZ________|
```
### CUF V-2: Rightmost Boundary with Reverse Wrap Disabled
```bash
printf "A"
printf "\033[500C" # forward larger than screen width
printf "B"
```
```
|A________Bc
```
### CUF V-3: Left of the Right Margin
```bash
printf "\033[1;1H" # move to top-left
printf "\033[0J" # clear screen
printf "\033[?69h" # enable left/right margins
printf "\033[3;5s" # scroll region left/right
printf "\033[1G" # move to left
printf "\033[500C" # forward larger than screen width
printf "X"
```
```
|____X_____|
```
### CUF V-4: Right of the Right Margin
```bash
printf "\033[1;1H" # move to top-left
printf "\033[0J" # clear screen
printf "\033[?69h" # enable left/right margins
printf "\033[3;5s" # scroll region left/right
printf "\033[6G" # move to right of margin
printf "\033[500C" # forward larger than screen width
printf "X"
```
```
|_________X|
```