terminal: margins
parent
c1e57dd330
commit
0df4d5c5a4
|
|
@ -121,7 +121,7 @@ pub fn TaggedUnion(
|
|||
|
||||
/// Returns the value type for the given tag.
|
||||
pub fn Value(comptime tag: Tag) type {
|
||||
@setEvalBranchQuota(2000);
|
||||
@setEvalBranchQuota(10000);
|
||||
inline for (@typeInfo(Union).@"union".fields) |field| {
|
||||
const field_tag = @field(Tag, field.name);
|
||||
if (field_tag == tag) return field.type;
|
||||
|
|
|
|||
|
|
@ -75,6 +75,9 @@ pub const Action = union(Key) {
|
|||
restore_mode: Mode,
|
||||
request_mode: Mode,
|
||||
request_mode_unknown: RawMode,
|
||||
top_and_bottom_margin: Margin,
|
||||
left_and_right_margin: Margin,
|
||||
left_and_right_margin_ambiguous,
|
||||
modify_key_format: ansi.ModifyKeyFormat,
|
||||
protected_mode_off,
|
||||
protected_mode_iso,
|
||||
|
|
@ -128,6 +131,9 @@ pub const Action = union(Key) {
|
|||
"restore_mode",
|
||||
"request_mode",
|
||||
"request_mode_unknown",
|
||||
"top_and_bottom_margin",
|
||||
"left_and_right_margin",
|
||||
"left_and_right_margin_ambiguous",
|
||||
"modify_key_format",
|
||||
"protected_mode_off",
|
||||
"protected_mode_iso",
|
||||
|
|
@ -195,6 +201,11 @@ pub const Action = union(Key) {
|
|||
mode: u16,
|
||||
ansi: bool,
|
||||
};
|
||||
|
||||
pub const Margin = extern struct {
|
||||
top_left: u16,
|
||||
bottom_right: u16,
|
||||
};
|
||||
};
|
||||
|
||||
/// Returns a type that can process a stream of tty control characters.
|
||||
|
|
@ -1336,17 +1347,12 @@ pub fn Stream(comptime Handler: type) type {
|
|||
|
||||
'r' => switch (input.intermediates.len) {
|
||||
// DECSTBM - Set Top and Bottom Margins
|
||||
0 => if (@hasDecl(T, "setTopAndBottomMargin")) {
|
||||
switch (input.params.len) {
|
||||
0 => try self.handler.setTopAndBottomMargin(0, 0),
|
||||
1 => try self.handler.setTopAndBottomMargin(input.params[0], 0),
|
||||
2 => try self.handler.setTopAndBottomMargin(input.params[0], input.params[1]),
|
||||
else => log.warn("invalid DECSTBM command: {f}", .{input}),
|
||||
}
|
||||
} else log.warn(
|
||||
"unimplemented CSI callback: {f}",
|
||||
.{input},
|
||||
),
|
||||
0 => switch (input.params.len) {
|
||||
0 => try self.handler.vt(.top_and_bottom_margin, .{ .top_left = 0, .bottom_right = 0 }),
|
||||
1 => try self.handler.vt(.top_and_bottom_margin, .{ .top_left = input.params[0], .bottom_right = 0 }),
|
||||
2 => try self.handler.vt(.top_and_bottom_margin, .{ .top_left = input.params[0], .bottom_right = input.params[1] }),
|
||||
else => log.warn("invalid DECSTBM command: {f}", .{input}),
|
||||
},
|
||||
|
||||
1 => switch (input.intermediates[0]) {
|
||||
// Restore Mode
|
||||
|
|
@ -1377,21 +1383,16 @@ pub fn Stream(comptime Handler: type) type {
|
|||
|
||||
's' => switch (input.intermediates.len) {
|
||||
// DECSLRM
|
||||
0 => if (@hasDecl(T, "setLeftAndRightMargin")) {
|
||||
switch (input.params.len) {
|
||||
// CSI S is ambiguous with zero params so we defer
|
||||
// to our handler to do the proper logic. If mode 69
|
||||
// is set, then we should invoke DECSLRM, otherwise
|
||||
// we should invoke SC.
|
||||
0 => try self.handler.setLeftAndRightMarginAmbiguous(),
|
||||
1 => try self.handler.setLeftAndRightMargin(input.params[0], 0),
|
||||
2 => try self.handler.setLeftAndRightMargin(input.params[0], input.params[1]),
|
||||
else => log.warn("invalid DECSLRM command: {f}", .{input}),
|
||||
}
|
||||
} else log.warn(
|
||||
"unimplemented CSI callback: {f}",
|
||||
.{input},
|
||||
),
|
||||
0 => switch (input.params.len) {
|
||||
// CSI S is ambiguous with zero params so we defer
|
||||
// to our handler to do the proper logic. If mode 69
|
||||
// is set, then we should invoke DECSLRM, otherwise
|
||||
// we should invoke SC.
|
||||
0 => try self.handler.vt(.left_and_right_margin_ambiguous, {}),
|
||||
1 => try self.handler.vt(.left_and_right_margin, .{ .top_left = input.params[0], .bottom_right = 0 }),
|
||||
2 => try self.handler.vt(.left_and_right_margin, .{ .top_left = input.params[0], .bottom_right = input.params[1] }),
|
||||
else => log.warn("invalid DECSLRM command: {f}", .{input}),
|
||||
},
|
||||
|
||||
1 => switch (input.intermediates[0]) {
|
||||
'?' => {
|
||||
|
|
@ -2227,20 +2228,16 @@ test "stream: restore mode" {
|
|||
const Self = @This();
|
||||
called: bool = false,
|
||||
|
||||
pub fn setTopAndBottomMargin(self: *Self, t: u16, b: u16) !void {
|
||||
_ = t;
|
||||
_ = b;
|
||||
self.called = true;
|
||||
}
|
||||
|
||||
pub fn vt(
|
||||
self: *@This(),
|
||||
comptime action: anytype,
|
||||
value: anytype,
|
||||
self: *Self,
|
||||
comptime action: Stream(Self).Action.Tag,
|
||||
value: Stream(Self).Action.Value(action),
|
||||
) !void {
|
||||
_ = self;
|
||||
_ = action;
|
||||
_ = value;
|
||||
switch (action) {
|
||||
.top_and_bottom_margin => self.called = true,
|
||||
else => {},
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
|
|
@ -2654,25 +2651,17 @@ test "stream: SCOSC" {
|
|||
const Self = @This();
|
||||
called: bool = false,
|
||||
|
||||
pub fn setLeftAndRightMargin(self: *Self, left: u16, right: u16) !void {
|
||||
_ = self;
|
||||
_ = left;
|
||||
_ = right;
|
||||
@panic("bad");
|
||||
}
|
||||
|
||||
pub fn setLeftAndRightMarginAmbiguous(self: *Self) !void {
|
||||
self.called = true;
|
||||
}
|
||||
|
||||
pub fn vt(
|
||||
self: *@This(),
|
||||
comptime action: anytype,
|
||||
value: anytype,
|
||||
self: *Self,
|
||||
comptime action: Stream(Self).Action.Tag,
|
||||
value: Stream(Self).Action.Value(action),
|
||||
) !void {
|
||||
_ = self;
|
||||
_ = action;
|
||||
_ = value;
|
||||
switch (action) {
|
||||
.left_and_right_margin => @panic("bad"),
|
||||
.left_and_right_margin_ambiguous => self.called = true,
|
||||
else => {},
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -255,6 +255,15 @@ pub const StreamHandler = struct {
|
|||
},
|
||||
.request_mode => try self.requestMode(value.mode),
|
||||
.request_mode_unknown => try self.requestModeUnknown(value.mode, value.ansi),
|
||||
.top_and_bottom_margin => self.terminal.setTopAndBottomMargin(value.top_left, value.bottom_right),
|
||||
.left_and_right_margin => self.terminal.setLeftAndRightMargin(value.top_left, value.bottom_right),
|
||||
.left_and_right_margin_ambiguous => {
|
||||
if (self.terminal.modes.get(.enable_left_and_right_margin)) {
|
||||
self.terminal.setLeftAndRightMargin(0, 0);
|
||||
} else {
|
||||
self.terminal.saveCursor();
|
||||
}
|
||||
},
|
||||
.modify_key_format => try self.setModifyKeyFormat(value),
|
||||
.protected_mode_off => self.terminal.setProtectedMode(.off),
|
||||
.protected_mode_iso => self.terminal.setProtectedMode(.iso),
|
||||
|
|
@ -437,22 +446,6 @@ pub const StreamHandler = struct {
|
|||
self.terminal.carriageReturn();
|
||||
}
|
||||
|
||||
pub inline fn setTopAndBottomMargin(self: *StreamHandler, top: u16, bot: u16) !void {
|
||||
self.terminal.setTopAndBottomMargin(top, bot);
|
||||
}
|
||||
|
||||
pub inline fn setLeftAndRightMarginAmbiguous(self: *StreamHandler) !void {
|
||||
if (self.terminal.modes.get(.enable_left_and_right_margin)) {
|
||||
try self.setLeftAndRightMargin(0, 0);
|
||||
} else {
|
||||
try self.saveCursor();
|
||||
}
|
||||
}
|
||||
|
||||
pub inline fn setLeftAndRightMargin(self: *StreamHandler, left: u16, right: u16) !void {
|
||||
self.terminal.setLeftAndRightMargin(left, right);
|
||||
}
|
||||
|
||||
pub fn setModifyKeyFormat(self: *StreamHandler, format: terminal.ModifyKeyFormat) !void {
|
||||
self.terminal.flags.modify_other_keys_2 = false;
|
||||
switch (format) {
|
||||
|
|
|
|||
Loading…
Reference in New Issue