config: fix binding parsing to allow values containing `=` (#8675)
Fixes #8667 The binding `a=text:=` didn't parse properly. This is a band-aid solution. It works and we have test coverage for it thankfully. Longer term we should move the parser to a fully state-machine based parser that parses the trigger first then the action, to avoid these kind of things.pull/8680/head
commit
abec922d91
|
|
@ -64,11 +64,35 @@ pub const Parser = struct {
|
||||||
const flags, const start_idx = try parseFlags(raw_input);
|
const flags, const start_idx = try parseFlags(raw_input);
|
||||||
const input = raw_input[start_idx..];
|
const input = raw_input[start_idx..];
|
||||||
|
|
||||||
// Find the last = which splits are mapping into the trigger
|
// Find the equal sign. This is more complicated than it seems on
|
||||||
// and action, respectively.
|
// the surface because we need to ignore equal signs that are
|
||||||
// We use the last = because the keybind itself could contain
|
// part of the trigger.
|
||||||
// raw equal signs (for the = codepoint)
|
const eql_idx: usize = eql: {
|
||||||
const eql_idx = std.mem.lastIndexOf(u8, input, "=") orelse return Error.InvalidFormat;
|
// TODO: We should change this parser into a real state machine
|
||||||
|
// based parser that parses the trigger fully, then yields the
|
||||||
|
// action after. The loop below is a total mess.
|
||||||
|
var offset: usize = 0;
|
||||||
|
while (std.mem.indexOfScalar(
|
||||||
|
u8,
|
||||||
|
input[offset..],
|
||||||
|
'=',
|
||||||
|
)) |offset_idx| {
|
||||||
|
// Find: '=+ctrl' or '==action'
|
||||||
|
const idx = offset + offset_idx;
|
||||||
|
if (idx < input.len - 1 and
|
||||||
|
(input[idx + 1] == '+' or
|
||||||
|
input[idx + 1] == '='))
|
||||||
|
{
|
||||||
|
offset += offset_idx + 1;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Looks like the real equal sign.
|
||||||
|
break :eql idx;
|
||||||
|
}
|
||||||
|
|
||||||
|
return Error.InvalidFormat;
|
||||||
|
};
|
||||||
|
|
||||||
// Sequence iterator goes up to the equal, action is after. We can
|
// Sequence iterator goes up to the equal, action is after. We can
|
||||||
// parse the action now.
|
// parse the action now.
|
||||||
|
|
@ -2298,6 +2322,39 @@ test "parse: equals sign" {
|
||||||
try testing.expectError(Error.InvalidFormat, parseSingle("=ignore"));
|
try testing.expectError(Error.InvalidFormat, parseSingle("=ignore"));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
test "parse: text action equals sign" {
|
||||||
|
const testing = std.testing;
|
||||||
|
{
|
||||||
|
const binding = try parseSingle("==text:=");
|
||||||
|
try testing.expectEqual(Trigger{ .key = .{ .unicode = '=' } }, binding.trigger);
|
||||||
|
try testing.expectEqualStrings("=", binding.action.text);
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
const binding = try parseSingle("==text:=hello");
|
||||||
|
try testing.expectEqual(Trigger{ .key = .{ .unicode = '=' } }, binding.trigger);
|
||||||
|
try testing.expectEqualStrings("=hello", binding.action.text);
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
const binding = try parseSingle("ctrl+==text:=hello");
|
||||||
|
try testing.expectEqual(Trigger{
|
||||||
|
.key = .{ .unicode = '=' },
|
||||||
|
.mods = .{ .ctrl = true },
|
||||||
|
}, binding.trigger);
|
||||||
|
try testing.expectEqualStrings("=hello", binding.action.text);
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
const binding = try parseSingle("=+ctrl=text:=hello");
|
||||||
|
try testing.expectEqual(Trigger{
|
||||||
|
.key = .{ .unicode = '=' },
|
||||||
|
.mods = .{ .ctrl = true },
|
||||||
|
}, binding.trigger);
|
||||||
|
try testing.expectEqualStrings("=hello", binding.action.text);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// For Ghostty 1.2+ we changed our key names to match the W3C and removed
|
// For Ghostty 1.2+ we changed our key names to match the W3C and removed
|
||||||
// `physical:`. This tests the backwards compatibility with the old format.
|
// `physical:`. This tests the backwards compatibility with the old format.
|
||||||
// Note that our backwards compatibility isn't 100% perfect since triggers
|
// Note that our backwards compatibility isn't 100% perfect since triggers
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue