mirror of
https://github.com/ghostty-org/ghostty.git
synced 2025-07-16 08:46:08 +03:00
single shift 2/3
This commit is contained in:
@ -93,6 +93,9 @@ const CharsetState = struct {
|
||||
gl: charsets.Slots = .G0,
|
||||
gr: charsets.Slots = .G2,
|
||||
|
||||
/// Single shift where a slot is used for exactly one char.
|
||||
single_shift: ?charsets.Slots = null,
|
||||
|
||||
/// An array to map a charset slot to a lookup table.
|
||||
const CharsetArray = std.EnumArray(charsets.Slots, charsets.Charset);
|
||||
};
|
||||
@ -407,7 +410,11 @@ pub fn invokeCharset(
|
||||
slot: charsets.Slots,
|
||||
single: bool,
|
||||
) void {
|
||||
assert(!single); // TODO
|
||||
if (single) {
|
||||
assert(active == .GL);
|
||||
self.charset.single_shift = slot;
|
||||
return;
|
||||
}
|
||||
|
||||
switch (active) {
|
||||
.GL => self.charset.gl = slot,
|
||||
@ -481,7 +488,11 @@ fn printCell(self: *Terminal, unmapped_c: u21) *Screen.Cell {
|
||||
const c = c: {
|
||||
// TODO: non-utf8 handling, gr
|
||||
|
||||
const key = self.charset.gl;
|
||||
// If we're single shifting, then we use the key exactly once.
|
||||
const key = if (self.charset.single_shift) |key_once| blk: {
|
||||
self.charset.single_shift = null;
|
||||
break :blk key_once;
|
||||
} else self.charset.gl;
|
||||
const set = self.charset.charsets.get(key);
|
||||
|
||||
// UTF-8 or ASCII is used as-is
|
||||
@ -1342,6 +1353,24 @@ test "Terminal: print invoke charset" {
|
||||
}
|
||||
}
|
||||
|
||||
test "Terminal: print invoke charset single" {
|
||||
var t = try init(testing.allocator, 80, 80);
|
||||
defer t.deinit(testing.allocator);
|
||||
|
||||
t.configureCharset(.G1, .dec_special);
|
||||
|
||||
// Basic grid writing
|
||||
try t.print('`');
|
||||
t.invokeCharset(.GL, .G1, true);
|
||||
try t.print('`');
|
||||
try t.print('`');
|
||||
{
|
||||
var str = try t.plainString(testing.allocator);
|
||||
defer testing.allocator.free(str);
|
||||
try testing.expectEqualStrings("`◆`", str);
|
||||
}
|
||||
}
|
||||
|
||||
test "Terminal: linefeed and carriage return" {
|
||||
var t = try init(testing.allocator, 80, 80);
|
||||
defer t.deinit(testing.allocator);
|
||||
|
@ -526,6 +526,24 @@ pub fn Stream(comptime Handler: type) type {
|
||||
},
|
||||
} else log.warn("unimplemented ESC callback: {}", .{action}),
|
||||
|
||||
// SS2 - Single Shift 2
|
||||
'N' => if (@hasDecl(T, "invokeCharset")) switch (action.intermediates.len) {
|
||||
0 => try self.handler.invokeCharset(.GL, .G2, true),
|
||||
else => {
|
||||
log.warn("invalid single shift 2 command: {}", .{action});
|
||||
return;
|
||||
},
|
||||
} else log.warn("unimplemented invokeCharset: {}", .{action}),
|
||||
|
||||
// SS3 - Single Shift 3
|
||||
'O' => if (@hasDecl(T, "invokeCharset")) switch (action.intermediates.len) {
|
||||
0 => try self.handler.invokeCharset(.GL, .G3, true),
|
||||
else => {
|
||||
log.warn("invalid single shift 3 command: {}", .{action});
|
||||
return;
|
||||
},
|
||||
} else log.warn("unimplemented invokeCharset: {}", .{action}),
|
||||
|
||||
else => if (@hasDecl(T, "escUnimplemented"))
|
||||
try self.handler.escUnimplemented(action)
|
||||
else
|
||||
|
Reference in New Issue
Block a user