Merge pull request #1185 from mitchellh/cub-rw

terminal: cub with reverse wrap consumes pending wrap state as one
This commit is contained in:
Mitchell Hashimoto
2023-12-29 12:49:36 -08:00
committed by GitHub
2 changed files with 72 additions and 3 deletions

View File

@ -1564,18 +1564,23 @@ pub fn cursorLeft(self: *Terminal, count_req: usize) void {
break :wrap_mode .none;
};
// Unset the pending wrap state no matter what
self.screen.cursor.pending_wrap = false;
var count: usize = @max(count_req, 1);
// If we are in no wrap mode, then we move the cursor left and exit
// since this is the fastest and most typical path.
if (wrap_mode == .none) {
self.screen.cursor.x -|= count;
self.screen.cursor.pending_wrap = false;
return;
}
// If we have a pending wrap state and we are in either reverse wrap
// modes then we decrement the amount we move by one to match xterm.
if (self.screen.cursor.pending_wrap) {
count -= 1;
self.screen.cursor.pending_wrap = false;
}
// The margins we can move to.
const top = self.scrolling_region.top;
const bottom = self.scrolling_region.bottom;
@ -6265,6 +6270,48 @@ test "Terminal: cursorLeft unsets pending wrap state with longer jump" {
}
}
test "Terminal: cursorLeft reverse wrap with pending wrap state" {
const alloc = testing.allocator;
var t = try init(alloc, 5, 5);
defer t.deinit(alloc);
t.modes.set(.wraparound, true);
t.modes.set(.reverse_wrap, true);
for ("ABCDE") |c| try t.print(c);
try testing.expect(t.screen.cursor.pending_wrap);
t.cursorLeft(1);
try testing.expect(!t.screen.cursor.pending_wrap);
try t.print('X');
{
const str = try t.plainString(testing.allocator);
defer testing.allocator.free(str);
try testing.expectEqualStrings("ABCDX", str);
}
}
test "Terminal: cursorLeft reverse wrap extended with pending wrap state" {
const alloc = testing.allocator;
var t = try init(alloc, 5, 5);
defer t.deinit(alloc);
t.modes.set(.wraparound, true);
t.modes.set(.reverse_wrap_extended, true);
for ("ABCDE") |c| try t.print(c);
try testing.expect(t.screen.cursor.pending_wrap);
t.cursorLeft(1);
try testing.expect(!t.screen.cursor.pending_wrap);
try t.print('X');
{
const str = try t.plainString(testing.allocator);
defer testing.allocator.free(str);
try testing.expectEqualStrings("ABCDX", str);
}
}
test "Terminal: cursorLeft reverse wrap" {
const alloc = testing.allocator;
var t = try init(alloc, 5, 5);

View File

@ -51,6 +51,11 @@ is a remaining value of `n`. If the cursor
is already on the [top margin](#TODO), do not move the cursor up.
This wrapping mode does not wrap the cursor row back to the bottom margin.
For **extended reverse wrap** or **reverse wrap** modes, if the pending
wrap state is set, decrease `n` by 1. In these modes, the initial cursor
backward count is consumed by the pending wrap state, as if you pressed
"backspace" on an empty newline and the cursor moved back to the previous line.
## Validation
### CUB V-1: Pending Wrap is Unset
@ -159,3 +164,20 @@ printf "X"
|__________|
|Xc________|
```
### CUB V-7: Reverse Wrap with Pending Wrap State
```bash
cols=$(tput cols)
printf "\033[?45h"
printf "\033[${cols}G"
printf "\033[4D"
printf "ABCDE"
printf "\033[D"
printf "X"
```
```
|_____ABCDX|
```