mirror of
https://github.com/ghostty-org/ghostty.git
synced 2025-07-14 15:56:13 +03:00
terminal: collect intermediates properly
This commit is contained in:
@ -153,18 +153,24 @@ fn doAction(self: *Parser, action: TransitionAction, c: u8) ?Action {
|
|||||||
.print => Action{ .print = c },
|
.print => Action{ .print = c },
|
||||||
.execute => Action{ .execute = c },
|
.execute => Action{ .execute = c },
|
||||||
.collect => collect: {
|
.collect => collect: {
|
||||||
|
if (self.intermediates_idx >= MAX_INTERMEDIATE) {
|
||||||
|
log.warn("invalid intermediates count", .{});
|
||||||
|
break :collect null;
|
||||||
|
}
|
||||||
|
|
||||||
self.intermediates[self.intermediates_idx] = c;
|
self.intermediates[self.intermediates_idx] = c;
|
||||||
// TODO: incr, bounds check
|
self.intermediates_idx += 1;
|
||||||
|
|
||||||
// The client is expected to perform no action.
|
// The client is expected to perform no action.
|
||||||
break :collect null;
|
break :collect null;
|
||||||
},
|
},
|
||||||
.param => param: {
|
.param => param: {
|
||||||
// TODO: bounds check
|
|
||||||
|
|
||||||
// Semicolon separates parameters. If we encounter a semicolon
|
// Semicolon separates parameters. If we encounter a semicolon
|
||||||
// we need to store and move on to the next parameter.
|
// we need to store and move on to the next parameter.
|
||||||
if (c == ';') {
|
if (c == ';') {
|
||||||
|
// Ignore too many parameters
|
||||||
|
if (self.params_idx >= MAX_PARAMS) break :param null;
|
||||||
|
|
||||||
// Set param final value
|
// Set param final value
|
||||||
self.params[self.params_idx] = self.param_acc;
|
self.params[self.params_idx] = self.param_acc;
|
||||||
self.params_idx += 1;
|
self.params_idx += 1;
|
||||||
@ -244,6 +250,25 @@ test {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
test "esc: ESC ( B" {
|
||||||
|
var p = init();
|
||||||
|
_ = p.next(0x1B);
|
||||||
|
_ = p.next('(');
|
||||||
|
|
||||||
|
{
|
||||||
|
const a = p.next('B');
|
||||||
|
try testing.expect(p.state == .ground);
|
||||||
|
try testing.expect(a[0] == null);
|
||||||
|
try testing.expect(a[1].? == .esc_dispatch);
|
||||||
|
try testing.expect(a[2] == null);
|
||||||
|
|
||||||
|
const d = a[1].?.esc_dispatch;
|
||||||
|
try testing.expect(d.final == 'B');
|
||||||
|
try testing.expect(d.intermediates.len == 1);
|
||||||
|
try testing.expect(d.intermediates[0] == '(');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
test "csi: ESC [ H" {
|
test "csi: ESC [ H" {
|
||||||
var p = init();
|
var p = init();
|
||||||
_ = p.next(0x1B);
|
_ = p.next(0x1B);
|
||||||
|
@ -56,6 +56,7 @@ const Cursor = struct {
|
|||||||
y: usize,
|
y: usize,
|
||||||
|
|
||||||
// Bold specifies that text written should be bold
|
// Bold specifies that text written should be bold
|
||||||
|
// TODO: connect to render
|
||||||
bold: bool = false,
|
bold: bool = false,
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -307,7 +308,15 @@ pub fn eraseDisplay(
|
|||||||
for (self.screen.items) |*line| line.deinit(alloc);
|
for (self.screen.items) |*line| line.deinit(alloc);
|
||||||
self.screen.clearRetainingCapacity();
|
self.screen.clearRetainingCapacity();
|
||||||
},
|
},
|
||||||
else => @panic("unimplemented"),
|
|
||||||
|
.below => {
|
||||||
|
log.warn("TODO: below eraseDisplay", .{});
|
||||||
|
},
|
||||||
|
|
||||||
|
else => {
|
||||||
|
log.err("unimplemented display mode: {}", .{mode});
|
||||||
|
@panic("unimplemented");
|
||||||
|
},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -329,7 +338,22 @@ pub fn eraseLine(
|
|||||||
for (line.items[self.cursor.x..line.items.len]) |*cell|
|
for (line.items[self.cursor.x..line.items.len]) |*cell|
|
||||||
cell.char = 0;
|
cell.char = 0;
|
||||||
},
|
},
|
||||||
else => @panic("unimplemented"),
|
|
||||||
|
.left => {
|
||||||
|
// If our cursor is outside our screen, we can't erase anything.
|
||||||
|
if (self.cursor.y >= self.screen.items.len) return;
|
||||||
|
var line = &self.screen.items[self.cursor.y];
|
||||||
|
|
||||||
|
// Clear up to our cursor
|
||||||
|
const end = @minimum(line.items.len - 1, self.cursor.x);
|
||||||
|
for (line.items[0..end]) |*cell|
|
||||||
|
cell.char = 0;
|
||||||
|
},
|
||||||
|
|
||||||
|
else => {
|
||||||
|
log.err("unimplemented erase line mode: {}", .{mode});
|
||||||
|
@panic("unimplemented");
|
||||||
|
},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user