mirror of
https://github.com/ghostty-org/ghostty.git
synced 2025-07-15 00:06:09 +03:00
Revert "parse string literal at load time"
This reverts commit 9c3e2b4ddd546e5f0c9d60c25a22bc5ab0be1283.
This commit is contained in:
@ -2254,6 +2254,39 @@ fn showMouse(self: *Surface) void {
|
|||||||
self.rt_surface.setMouseVisibility(true);
|
self.rt_surface.setMouseVisibility(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn parseStringLiteral(out: []u8, bytes: []const u8) []u8 {
|
||||||
|
var offset: usize = 0;
|
||||||
|
var index: usize = 0;
|
||||||
|
while (true) {
|
||||||
|
if (index >= bytes.len or offset >= out.len) break;
|
||||||
|
const b = bytes[index];
|
||||||
|
switch (b) {
|
||||||
|
'\\' => {
|
||||||
|
const escape_char_index = index + 1;
|
||||||
|
const result = std.zig.string_literal.parseEscapeSequence(bytes, &index);
|
||||||
|
switch (result) {
|
||||||
|
.success => |codepoint| {
|
||||||
|
if (bytes[escape_char_index] == 'u') {
|
||||||
|
const len = std.unicode.utf8Encode(codepoint, out[offset..]) catch break;
|
||||||
|
offset += len;
|
||||||
|
} else {
|
||||||
|
out[offset] = @as(u8, @intCast(codepoint));
|
||||||
|
offset += 1;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
.failure => break,
|
||||||
|
}
|
||||||
|
},
|
||||||
|
else => {
|
||||||
|
out[offset] = b;
|
||||||
|
offset += 1;
|
||||||
|
index += 1;
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return out[0..offset];
|
||||||
|
}
|
||||||
|
|
||||||
/// Perform a binding action. A binding is a keybinding. This function
|
/// Perform a binding action. A binding is a keybinding. This function
|
||||||
/// must be called from the GUI thread.
|
/// must be called from the GUI thread.
|
||||||
///
|
///
|
||||||
@ -2279,7 +2312,7 @@ pub fn performBindingAction(self: *Surface, action: input.Binding.Action) !bool
|
|||||||
const full_data = switch (action) {
|
const full_data = switch (action) {
|
||||||
.csi => try std.fmt.bufPrint(&buf, "\x1b[{s}", .{data}),
|
.csi => try std.fmt.bufPrint(&buf, "\x1b[{s}", .{data}),
|
||||||
.esc => try std.fmt.bufPrint(&buf, "\x1b{s}", .{data}),
|
.esc => try std.fmt.bufPrint(&buf, "\x1b{s}", .{data}),
|
||||||
.text => data,
|
.text => parseStringLiteral(&buf, data),
|
||||||
else => unreachable,
|
else => unreachable,
|
||||||
};
|
};
|
||||||
_ = self.io_thread.mailbox.push(try termio.Message.writeReq(
|
_ = self.io_thread.mailbox.push(try termio.Message.writeReq(
|
||||||
|
@ -321,47 +321,6 @@ pub const Action = union(enum) {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
// Use Zig syntax to parse a string literal.
|
|
||||||
// Since the escaping syntax is verbose, we can do the parsing inplace.
|
|
||||||
pub fn parseStringLiteralInPlace(bytes: []const u8) []const u8 {
|
|
||||||
var out: [128]u8 = undefined;
|
|
||||||
var offset: usize = 0;
|
|
||||||
var index: usize = 0;
|
|
||||||
while (true) {
|
|
||||||
assert(offset <= index);
|
|
||||||
if (index >= bytes.len or offset >= out.len) break;
|
|
||||||
const b = bytes[index];
|
|
||||||
switch (b) {
|
|
||||||
'\\' => {
|
|
||||||
const escape_char_index = index + 1;
|
|
||||||
const result = std.zig.string_literal.parseEscapeSequence(bytes, &index);
|
|
||||||
switch (result) {
|
|
||||||
.success => |codepoint| {
|
|
||||||
if (bytes[escape_char_index] == 'u') {
|
|
||||||
const len = std.unicode.utf8Encode(codepoint, out[offset..]) catch break;
|
|
||||||
offset += len;
|
|
||||||
} else {
|
|
||||||
out[offset] = @as(u8, @intCast(codepoint));
|
|
||||||
offset += 1;
|
|
||||||
}
|
|
||||||
},
|
|
||||||
.failure => break,
|
|
||||||
}
|
|
||||||
},
|
|
||||||
else => {
|
|
||||||
out[offset] = b;
|
|
||||||
offset += 1;
|
|
||||||
index += 1;
|
|
||||||
},
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// No escaping => no copy needed.
|
|
||||||
if (offset == index and index == bytes.len) return bytes;
|
|
||||||
const mut_bytes: []u8 = @as([*]u8, @ptrFromInt(@intFromPtr(bytes.ptr)))[0..offset];
|
|
||||||
@memcpy(mut_bytes, out[0..offset]);
|
|
||||||
return mut_bytes;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Parse an action in the format of "key=value" where key is the
|
/// Parse an action in the format of "key=value" where key is the
|
||||||
/// action name and value is the action parameter. The parameter
|
/// action name and value is the action parameter. The parameter
|
||||||
/// is optional depending on the action.
|
/// is optional depending on the action.
|
||||||
@ -387,10 +346,7 @@ pub const Action = union(enum) {
|
|||||||
|
|
||||||
[]const u8 => {
|
[]const u8 => {
|
||||||
const idx = colonIdx orelse return Error.InvalidFormat;
|
const idx = colonIdx orelse return Error.InvalidFormat;
|
||||||
const param = if (std.mem.eql(u8, field.name, "text"))
|
const param = input[idx + 1 ..];
|
||||||
parseStringLiteralInPlace(input[idx + 1 ..])
|
|
||||||
else
|
|
||||||
input[idx + 1 ..];
|
|
||||||
return @unionInit(Action, field.name, param);
|
return @unionInit(Action, field.name, param);
|
||||||
},
|
},
|
||||||
|
|
||||||
@ -896,12 +852,6 @@ test "parse: action with string" {
|
|||||||
try testing.expect(binding.action == .esc);
|
try testing.expect(binding.action == .esc);
|
||||||
try testing.expectEqualStrings("A", binding.action.esc);
|
try testing.expectEqualStrings("A", binding.action.esc);
|
||||||
}
|
}
|
||||||
// parameter
|
|
||||||
{
|
|
||||||
const binding = try parse("a=text:\\x03\\u{26a1}");
|
|
||||||
try testing.expect(binding.action == .text);
|
|
||||||
try testing.expectEqualStrings(binding.action.text, &[_]u8{ 3, 0xe2, 0x9a, 0xa1 });
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
test "parse: action with enum" {
|
test "parse: action with enum" {
|
||||||
|
Reference in New Issue
Block a user