+4
src/Loop.zig
+4
src/Loop.zig
···
362
log.info("color_scheme_updates capability detected", .{});
363
vx.caps.color_scheme_updates = true;
364
},
365
+
.cap_multi_cursor => {
366
+
log.info("multi cursor capability detected", .{});
367
+
vx.caps.multi_cursor = true;
368
+
},
369
.cap_da1 => {
370
std.Thread.Futex.wake(&vx.query_futex, 10);
371
vx.queries_done.store(true, .unordered);
+37
src/Parser.zig
+37
src/Parser.zig
···
646
else => return null_event,
647
}
648
},
649
else => return null_event,
650
}
651
}
···
1075
const actual = result.event.?.key_press;
1076
try testing.expectEqualStrings(expected_key.text.?, actual.text.?);
1077
try testing.expectEqual(expected_key.codepoint, actual.codepoint);
1078
}
1079
1080
test "parse(csi): decrpm" {
···
646
else => return null_event,
647
}
648
},
649
+
'q' => {
650
+
// kitty multi cursor cap (CSI > 1;2;3;29;30;40;100;101 TRAILER) (TRAILER is " q")
651
+
const second_final = sequence[sequence.len - 2];
652
+
if (second_final != ' ') return null_event;
653
+
// check for any digits. we're not too picky about checking the supported cursor types here
654
+
for (sequence[0 .. sequence.len - 2]) |c| switch (c) {
655
+
'0'...'9' => return .{ .event = .cap_multi_cursor, .n = sequence.len },
656
+
else => continue,
657
+
};
658
+
return null_event;
659
+
},
660
else => return null_event,
661
}
662
}
···
1086
const actual = result.event.?.key_press;
1087
try testing.expectEqualStrings(expected_key.text.?, actual.text.?);
1088
try testing.expectEqual(expected_key.codepoint, actual.codepoint);
1089
+
}
1090
+
1091
+
test "parse(csi): kitty multi cursor" {
1092
+
var buf: [1]u8 = undefined;
1093
+
{
1094
+
const input = "\x1b[>1;2;3;29;30;40;100;101 q";
1095
+
const result = parseCsi(input, &buf);
1096
+
const expected: Result = .{
1097
+
.event = .cap_multi_cursor,
1098
+
.n = input.len,
1099
+
};
1100
+
1101
+
try testing.expectEqual(expected.n, result.n);
1102
+
try testing.expectEqual(expected.event, result.event);
1103
+
}
1104
+
{
1105
+
const input = "\x1b[> q";
1106
+
const result = parseCsi(input, &buf);
1107
+
const expected: Result = .{
1108
+
.event = null,
1109
+
.n = input.len,
1110
+
};
1111
+
1112
+
try testing.expectEqual(expected.n, result.n);
1113
+
try testing.expectEqual(expected.event, result.event);
1114
+
}
1115
}
1116
1117
test "parse(csi): decrpm" {
+2
src/Vaxis.zig
+2
src/Vaxis.zig
···
38
color_scheme_updates: bool = false,
39
explicit_width: bool = false,
40
scaled_text: bool = false,
41
};
42
43
pub const Options = struct {
···
300
// why we see a Shift modifier
301
ctlseqs.home ++
302
ctlseqs.scaled_text_query ++
303
ctlseqs.cursor_position_request ++
304
ctlseqs.xtversion ++
305
ctlseqs.csi_u_query ++
···
38
color_scheme_updates: bool = false,
39
explicit_width: bool = false,
40
scaled_text: bool = false,
41
+
multi_cursor: bool = false,
42
};
43
44
pub const Options = struct {
···
301
// why we see a Shift modifier
302
ctlseqs.home ++
303
ctlseqs.scaled_text_query ++
304
+
ctlseqs.multi_cursor_query ++
305
ctlseqs.cursor_position_request ++
306
ctlseqs.xtversion ++
307
ctlseqs.csi_u_query ++
+1
src/ctlseqs.zig
+1
src/ctlseqs.zig
···
14
pub const cursor_position_request = "\x1b[6n";
15
pub const explicit_width_query = "\x1b]66;w=1; \x1b\\";
16
pub const scaled_text_query = "\x1b]66;s=2; \x1b\\";
17
18
// mouse. We try for button motion and any motion. terminals will enable the
19
// last one we tried (any motion). This was added because zellij doesn't
···
14
pub const cursor_position_request = "\x1b[6n";
15
pub const explicit_width_query = "\x1b]66;w=1; \x1b\\";
16
pub const scaled_text_query = "\x1b]66;s=2; \x1b\\";
17
+
pub const multi_cursor_query = "\x1b[> q";
18
19
// mouse. We try for button motion and any motion. terminals will enable the
20
// last one we tried (any motion). This was added because zellij doesn't