terminal: reverse index xterm audit

This commit is contained in:
Mitchell Hashimoto
2023-10-10 15:15:53 -07:00
parent d8f2a8dff0
commit fbc305c901
2 changed files with 273 additions and 7 deletions

View File

@ -973,15 +973,15 @@ pub fn reverseIndex(self: *Terminal) !void {
const tracy = trace(@src()); const tracy = trace(@src());
defer tracy.end(); defer tracy.end();
// If the cursor is on the top-most line of the scroll region or if (self.screen.cursor.y != self.scrolling_region.top or
// its on the top of the screen we scroll down. self.screen.cursor.x < self.scrolling_region.left or
if (self.screen.cursor.y == self.scrolling_region.top or self.screen.cursor.x > self.scrolling_region.right)
self.screen.cursor.y == 0)
{ {
try self.scrollDown(1); self.cursorUp(1);
} else { return;
self.screen.cursor.y -|= 1;
} }
try self.scrollDown(1);
} }
// Set Cursor Position. Move cursor to the position indicated // Set Cursor Position. Move cursor to the position indicated
@ -3346,6 +3346,134 @@ test "Terminal: reverseIndex top of scrolling region" {
} }
} }
test "Terminal: reverseIndex top of screen" {
const alloc = testing.allocator;
var t = try init(alloc, 5, 5);
defer t.deinit(alloc);
try t.print('A');
t.setCursorPos(2, 1);
try t.print('B');
t.setCursorPos(3, 1);
try t.print('C');
t.setCursorPos(1, 1);
try t.reverseIndex();
try t.print('X');
{
var str = try t.plainString(testing.allocator);
defer testing.allocator.free(str);
try testing.expectEqualStrings("X\nA\nB\nC", str);
}
}
test "Terminal: reverseIndex not top of screen" {
const alloc = testing.allocator;
var t = try init(alloc, 5, 5);
defer t.deinit(alloc);
try t.print('A');
t.setCursorPos(2, 1);
try t.print('B');
t.setCursorPos(3, 1);
try t.print('C');
t.setCursorPos(2, 1);
try t.reverseIndex();
try t.print('X');
{
var str = try t.plainString(testing.allocator);
defer testing.allocator.free(str);
try testing.expectEqualStrings("X\nB\nC", str);
}
}
test "Terminal: reverseIndex top/bottom margins" {
const alloc = testing.allocator;
var t = try init(alloc, 5, 5);
defer t.deinit(alloc);
try t.print('A');
t.setCursorPos(2, 1);
try t.print('B');
t.setCursorPos(3, 1);
try t.print('C');
t.setTopAndBottomMargin(2, 3);
t.setCursorPos(2, 1);
try t.reverseIndex();
{
var str = try t.plainString(testing.allocator);
defer testing.allocator.free(str);
try testing.expectEqualStrings("A\n\nB", str);
}
}
test "Terminal: reverseIndex outside top/bottom margins" {
const alloc = testing.allocator;
var t = try init(alloc, 5, 5);
defer t.deinit(alloc);
try t.print('A');
t.setCursorPos(2, 1);
try t.print('B');
t.setCursorPos(3, 1);
try t.print('C');
t.setTopAndBottomMargin(2, 3);
t.setCursorPos(1, 1);
try t.reverseIndex();
{
var str = try t.plainString(testing.allocator);
defer testing.allocator.free(str);
try testing.expectEqualStrings("A\nB\nC", str);
}
}
test "Terminal: reverseIndex left/right margins" {
const alloc = testing.allocator;
var t = try init(alloc, 5, 5);
defer t.deinit(alloc);
try t.printString("ABC");
t.setCursorPos(2, 1);
try t.printString("DEF");
t.setCursorPos(3, 1);
try t.printString("GHI");
t.modes.set(.enable_left_and_right_margin, true);
t.setLeftAndRightMargin(2, 3);
t.setCursorPos(1, 2);
try t.reverseIndex();
{
var str = try t.plainString(testing.allocator);
defer testing.allocator.free(str);
try testing.expectEqualStrings("A\nDBC\nGEF\n HI", str);
}
}
test "Terminal: reverseIndex outside left/right margins" {
const alloc = testing.allocator;
var t = try init(alloc, 5, 5);
defer t.deinit(alloc);
try t.printString("ABC");
t.setCursorPos(2, 1);
try t.printString("DEF");
t.setCursorPos(3, 1);
try t.printString("GHI");
t.modes.set(.enable_left_and_right_margin, true);
t.setLeftAndRightMargin(2, 3);
t.setCursorPos(1, 1);
try t.reverseIndex();
{
var str = try t.plainString(testing.allocator);
defer testing.allocator.free(str);
try testing.expectEqualStrings("ABC\nDEF\nGHI", str);
}
}
test "Terminal: index" { test "Terminal: index" {
const alloc = testing.allocator; const alloc = testing.allocator;
var t = try init(alloc, 2, 5); var t = try init(alloc, 2, 5);

138
website/app/vt/ri/page.mdx Normal file
View File

@ -0,0 +1,138 @@
import VTSequence from "@/components/VTSequence";
# Reverse Index (RI)
<VTSequence sequence={["ESC", "M"]} />
Move the cursor up one cell, scrolling if necessary.
This sequence does not unset the pending wrap state.
If the cursor is exactly on the [top margin](/vt/decstbm) and is within
[left and right margins](/vt/decslrm), invoke [scroll down (SD)](/vt/sd)
with `n = 1`. The operation is complete.
Otherwise, scrolling isn't necessary. Perform a
[cursor up](/vt/cuu) operation with `n = 1`.
## Validation
### RI V-1: No Scroll Region, Top of Screen
```bash
printf "\033[1;1H" # move to top-left
printf "\033[0J" # clear screen
printf "A\n"
printf "B\n"
printf "C\n"
printf "\033[1;1H" # move to top-left
printf "\033M" # reverse index
printf "X"
```
```
|Xc________|
|A_________|
|B_________|
|C_________|
```
### RI V-2: No Scroll Region, Not Top of Screen
```bash
printf "\033[1;1H" # move to top-left
printf "\033[0J" # clear screen
printf "A\n"
printf "B\n"
printf "C\n"
printf "\033[2;1H"
printf "\033M" # reverse index
printf "X"
```
```
|Xc________|
|B_________|
|C_________|
```
### RI V-3: Top/Bottom Scroll Region
```bash
printf "\033[1;1H" # move to top-left
printf "\033[0J" # clear screen
printf "A\n"
printf "B\n"
printf "C\n"
printf "\033[2;3r" # scroll region
printf "\033[2;1H"
printf "\033M" # reverse index
```
```
|A_________|
|c_________|
|B_________|
```
### RI V-4: Outside of Top/Bottom Scroll Region
```bash
printf "\033[1;1H" # move to top-left
printf "\033[0J" # clear screen
printf "A\n"
printf "B\n"
printf "C\n"
printf "\033[2;3r" # scroll region
printf "\033[1;1H"
printf "\033M" # reverse index
```
```
|A_________|
|B_________|
|C_________|
```
### RI V-5: Left/Right Scroll Region
```bash
printf "\033[1;1H" # move to top-left
printf "\033[0J" # clear screen
printf "ABC\n"
printf "DEF\n"
printf "GHI\n"
printf "\033[?69h" # enable left/right margins
printf "\033[2;3s" # scroll region left/right
printf "\033[1;2H"
printf "\033M"
```
```
|A_________|
|DBC_______|
|GEF_______|
|_HI_______|
```
### RI V-6: Outside Left/Right Scroll Region
```bash
printf "\033[1;1H" # move to top-left
printf "\033[0J" # clear screen
printf "ABC\n"
printf "DEF\n"
printf "GHI\n"
printf "\033[?69h" # enable left/right margins
printf "\033[2;3s" # scroll region left/right
printf "\033[2;1H"
printf "\033M"
```
```
|ABC_______|
|DEF_______|
|GHI_______|
```
Cursor on the `A`.