terminal: convert modes
parent
dc5406781f
commit
94a8fa05cb
|
|
@ -69,6 +69,10 @@ pub const Action = union(Key) {
|
|||
tab_clear_all,
|
||||
tab_set,
|
||||
tab_reset,
|
||||
set_mode: Mode,
|
||||
reset_mode: Mode,
|
||||
save_mode: Mode,
|
||||
restore_mode: Mode,
|
||||
|
||||
pub const Key = lib.Enum(
|
||||
lib_target,
|
||||
|
|
@ -112,6 +116,10 @@ pub const Action = union(Key) {
|
|||
"tab_clear_all",
|
||||
"tab_set",
|
||||
"tab_reset",
|
||||
"set_mode",
|
||||
"reset_mode",
|
||||
"save_mode",
|
||||
"restore_mode",
|
||||
},
|
||||
);
|
||||
|
||||
|
|
@ -160,6 +168,16 @@ pub const Action = union(Key) {
|
|||
row: u16,
|
||||
col: u16,
|
||||
};
|
||||
|
||||
pub const Mode = struct {
|
||||
mode: modes.Mode,
|
||||
|
||||
pub const C = u16;
|
||||
|
||||
pub fn cval(self: Mode) Mode.C {
|
||||
return @bitCast(self.mode);
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
/// Returns a type that can process a stream of tty control characters.
|
||||
|
|
@ -1022,7 +1040,7 @@ pub fn Stream(comptime Handler: type) type {
|
|||
},
|
||||
|
||||
// SM - Set Mode
|
||||
'h' => if (@hasDecl(T, "setMode")) mode: {
|
||||
'h' => mode: {
|
||||
const ansi_mode = ansi: {
|
||||
if (input.intermediates.len == 0) break :ansi true;
|
||||
if (input.intermediates.len == 1 and
|
||||
|
|
@ -1034,15 +1052,15 @@ pub fn Stream(comptime Handler: type) type {
|
|||
|
||||
for (input.params) |mode_int| {
|
||||
if (modes.modeFromInt(mode_int, ansi_mode)) |mode| {
|
||||
try self.handler.setMode(mode, true);
|
||||
try self.handler.vt(.set_mode, .{ .mode = mode });
|
||||
} else {
|
||||
log.warn("unimplemented mode: {}", .{mode_int});
|
||||
}
|
||||
}
|
||||
} else log.warn("unimplemented CSI callback: {f}", .{input}),
|
||||
},
|
||||
|
||||
// RM - Reset Mode
|
||||
'l' => if (@hasDecl(T, "setMode")) mode: {
|
||||
'l' => mode: {
|
||||
const ansi_mode = ansi: {
|
||||
if (input.intermediates.len == 0) break :ansi true;
|
||||
if (input.intermediates.len == 1 and
|
||||
|
|
@ -1054,12 +1072,12 @@ pub fn Stream(comptime Handler: type) type {
|
|||
|
||||
for (input.params) |mode_int| {
|
||||
if (modes.modeFromInt(mode_int, ansi_mode)) |mode| {
|
||||
try self.handler.setMode(mode, false);
|
||||
try self.handler.vt(.reset_mode, .{ .mode = mode });
|
||||
} else {
|
||||
log.warn("unimplemented mode: {}", .{mode_int});
|
||||
}
|
||||
}
|
||||
} else log.warn("unimplemented CSI callback: {f}", .{input}),
|
||||
},
|
||||
|
||||
// SGR - Select Graphic Rendition
|
||||
'm' => switch (input.intermediates.len) {
|
||||
|
|
@ -1304,10 +1322,10 @@ pub fn Stream(comptime Handler: type) type {
|
|||
|
||||
1 => switch (input.intermediates[0]) {
|
||||
// Restore Mode
|
||||
'?' => if (@hasDecl(T, "restoreMode")) {
|
||||
'?' => {
|
||||
for (input.params) |mode_int| {
|
||||
if (modes.modeFromInt(mode_int, false)) |mode| {
|
||||
try self.handler.restoreMode(mode);
|
||||
try self.handler.vt(.restore_mode, .{ .mode = mode });
|
||||
} else {
|
||||
log.warn(
|
||||
"unimplemented restore mode: {}",
|
||||
|
|
@ -1348,10 +1366,10 @@ pub fn Stream(comptime Handler: type) type {
|
|||
),
|
||||
|
||||
1 => switch (input.intermediates[0]) {
|
||||
'?' => if (@hasDecl(T, "saveMode")) {
|
||||
'?' => {
|
||||
for (input.params) |mode_int| {
|
||||
if (modes.modeFromInt(mode_int, false)) |mode| {
|
||||
try self.handler.saveMode(mode);
|
||||
try self.handler.vt(.save_mode, .{ .mode = mode });
|
||||
} else {
|
||||
log.warn(
|
||||
"unimplemented save mode: {}",
|
||||
|
|
@ -2091,19 +2109,17 @@ test "stream: cursor right (CUF)" {
|
|||
test "stream: dec set mode (SM) and reset mode (RM)" {
|
||||
const H = struct {
|
||||
mode: modes.Mode = @as(modes.Mode, @enumFromInt(1)),
|
||||
pub fn setMode(self: *@This(), mode: modes.Mode, v: bool) !void {
|
||||
self.mode = @as(modes.Mode, @enumFromInt(1));
|
||||
if (v) self.mode = mode;
|
||||
}
|
||||
|
||||
pub fn vt(
|
||||
self: *@This(),
|
||||
comptime action: anytype,
|
||||
value: anytype,
|
||||
) !void {
|
||||
_ = self;
|
||||
_ = action;
|
||||
_ = value;
|
||||
switch (action) {
|
||||
.set_mode => self.mode = value.mode,
|
||||
.reset_mode => self.mode = @as(modes.Mode, @enumFromInt(1)),
|
||||
else => {},
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
|
|
@ -2123,19 +2139,16 @@ test "stream: ansi set mode (SM) and reset mode (RM)" {
|
|||
const H = struct {
|
||||
mode: ?modes.Mode = null,
|
||||
|
||||
pub fn setMode(self: *@This(), mode: modes.Mode, v: bool) !void {
|
||||
self.mode = null;
|
||||
if (v) self.mode = mode;
|
||||
}
|
||||
|
||||
pub fn vt(
|
||||
self: *@This(),
|
||||
comptime action: anytype,
|
||||
value: anytype,
|
||||
) !void {
|
||||
_ = self;
|
||||
_ = action;
|
||||
_ = value;
|
||||
switch (action) {
|
||||
.set_mode => self.mode = value.mode,
|
||||
.reset_mode => self.mode = null,
|
||||
else => {},
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -243,6 +243,16 @@ pub const StreamHandler = struct {
|
|||
.tab_clear_all => self.terminal.tabClear(.all),
|
||||
.tab_set => self.terminal.tabSet(),
|
||||
.tab_reset => self.terminal.tabReset(),
|
||||
.set_mode => try self.setMode(value.mode, true),
|
||||
.reset_mode => try self.setMode(value.mode, false),
|
||||
.save_mode => self.terminal.modes.save(value.mode),
|
||||
.restore_mode => {
|
||||
// For restore mode we have to restore but if we set it, we
|
||||
// always have to call setMode because setting some modes have
|
||||
// side effects and we want to make sure we process those.
|
||||
const v = self.terminal.modes.restore(value.mode);
|
||||
try self.setMode(value.mode, v);
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -470,20 +480,6 @@ pub const StreamHandler = struct {
|
|||
self.messageWriter(msg);
|
||||
}
|
||||
|
||||
pub inline fn saveMode(self: *StreamHandler, mode: terminal.Mode) !void {
|
||||
// log.debug("save mode={}", .{mode});
|
||||
self.terminal.modes.save(mode);
|
||||
}
|
||||
|
||||
pub inline fn restoreMode(self: *StreamHandler, mode: terminal.Mode) !void {
|
||||
// For restore mode we have to restore but if we set it, we
|
||||
// always have to call setMode because setting some modes have
|
||||
// side effects and we want to make sure we process those.
|
||||
const v = self.terminal.modes.restore(mode);
|
||||
// log.debug("restore mode={} v={}", .{ mode, v });
|
||||
try self.setMode(mode, v);
|
||||
}
|
||||
|
||||
pub fn setMode(self: *StreamHandler, mode: terminal.Mode, enabled: bool) !void {
|
||||
// Note: this function doesn't need to grab the render state or
|
||||
// terminal locks because it is only called from process() which
|
||||
|
|
|
|||
Loading…
Reference in New Issue