this repo has no description
13
fork

Configure Feed

Select the types of activity you want to include in your feed.

parser: fix handling of function keys with kitty encoding

+88 -42
+88 -42
src/Parser.zig
··· 303 303 'A', 'B', 'C', 'D', 'E', 'F', 'H', 'P', 'Q', 'R', 'S' => { 304 304 // Legacy keys 305 305 // CSI {ABCDEFHPQS} 306 - // CSI 1 ; modifier {ABCDEFHPQS} 306 + // CSI 1 ; modifier:event_type {ABCDEFHPQS} 307 + 308 + // Split first into fields delimited by ';' 309 + var field_iter = std.mem.splitScalar(u8, sequence[2 .. sequence.len - 1], ';'); 307 310 308 - const modifiers: Key.Modifiers = if (sequence.len > 3) mods: { 309 - // ESC [ 1 ; <modifier_buf> {ABCDEFHPQS} 310 - const modifier_buf = sequence[4 .. sequence.len - 1]; 311 - const modifiers = parseParam(u8, modifier_buf, 1) orelse return null_event; 312 - break :mods @bitCast(modifiers -| 1); 313 - } else .{}; 311 + // skip the first field 312 + _ = field_iter.next(); // 314 313 315 - const key: Key = .{ 316 - .mods = modifiers, 314 + var is_release: bool = false; 315 + var key: Key = .{ 317 316 .codepoint = switch (final) { 318 317 'A' => Key.up, 319 318 'B' => Key.down, ··· 329 328 else => return null_event, 330 329 }, 331 330 }; 331 + 332 + field2: { 333 + // modifier_mask:event_type 334 + const field_buf = field_iter.next() orelse break :field2; 335 + var param_iter = std.mem.splitScalar(u8, field_buf, ':'); 336 + const modifier_buf = param_iter.next() orelse unreachable; 337 + const modifier_mask = parseParam(u8, modifier_buf, 1) orelse return null_event; 338 + key.mods = @bitCast(modifier_mask -| 1); 339 + 340 + if (param_iter.next()) |event_type_buf| { 341 + is_release = std.mem.eql(u8, event_type_buf, "3"); 342 + } 343 + } 344 + 345 + field3: { 346 + // text_as_codepoint[:text_as_codepoint] 347 + const field_buf = field_iter.next() orelse break :field3; 348 + var param_iter = std.mem.splitScalar(u8, field_buf, ':'); 349 + var total: usize = 0; 350 + while (param_iter.next()) |cp_buf| { 351 + const cp = parseParam(u21, cp_buf, null) orelse return null_event; 352 + total += std.unicode.utf8Encode(cp, text_buf[total..]) catch return null_event; 353 + } 354 + key.text = text_buf[0..total]; 355 + } 356 + 357 + const event: Event = if (is_release) .{ .key_release = key } else .{ .key_press = key }; 332 358 return .{ 333 - .event = .{ .key_press = key }, 359 + .event = event, 334 360 .n = sequence.len, 335 361 }; 336 362 }, ··· 338 364 // Legacy keys 339 365 // CSI number ~ 340 366 // CSI number ; modifier ~ 367 + // CSI number ; modifier:event_type ; text_as_codepoint ~ 341 368 var field_iter = std.mem.splitScalar(u8, sequence[2 .. sequence.len - 1], ';'); 342 369 const number_buf = field_iter.next() orelse unreachable; // always will have one field 343 370 const number = parseParam(u16, number_buf, null) orelse return null_event; 344 371 345 - const key_code = switch (number) { 346 - 2 => Key.insert, 347 - 3 => Key.delete, 348 - 5 => Key.page_up, 349 - 6 => Key.page_down, 350 - 7 => Key.home, 351 - 8 => Key.end, 352 - 11 => Key.f1, 353 - 12 => Key.f2, 354 - 13 => Key.f3, 355 - 14 => Key.f4, 356 - 15 => Key.f5, 357 - 17 => Key.f6, 358 - 18 => Key.f7, 359 - 19 => Key.f8, 360 - 20 => Key.f9, 361 - 21 => Key.f10, 362 - 23 => Key.f11, 363 - 24 => Key.f12, 364 - 200 => return .{ .event = .paste_start, .n = sequence.len }, 365 - 201 => return .{ .event = .paste_end, .n = sequence.len }, 366 - 57427 => Key.kp_begin, 367 - else => return null_event, 372 + var key: Key = .{ 373 + .codepoint = switch (number) { 374 + 2 => Key.insert, 375 + 3 => Key.delete, 376 + 5 => Key.page_up, 377 + 6 => Key.page_down, 378 + 7 => Key.home, 379 + 8 => Key.end, 380 + 11 => Key.f1, 381 + 12 => Key.f2, 382 + 13 => Key.f3, 383 + 14 => Key.f4, 384 + 15 => Key.f5, 385 + 17 => Key.f6, 386 + 18 => Key.f7, 387 + 19 => Key.f8, 388 + 20 => Key.f9, 389 + 21 => Key.f10, 390 + 23 => Key.f11, 391 + 24 => Key.f12, 392 + 200 => return .{ .event = .paste_start, .n = sequence.len }, 393 + 201 => return .{ .event = .paste_end, .n = sequence.len }, 394 + 57427 => Key.kp_begin, 395 + else => return null_event, 396 + }, 368 397 }; 369 398 370 - const modifiers: Key.Modifiers = if (field_iter.next()) |modifier_buf| mods: { 371 - const modifiers = parseParam(u8, modifier_buf, 1) orelse return null_event; 372 - break :mods @bitCast(modifiers -| 1); 373 - } else .{}; 399 + var is_release: bool = false; 400 + field2: { 401 + // modifier_mask:event_type 402 + const field_buf = field_iter.next() orelse break :field2; 403 + var param_iter = std.mem.splitScalar(u8, field_buf, ':'); 404 + const modifier_buf = param_iter.next() orelse unreachable; 405 + const modifier_mask = parseParam(u8, modifier_buf, 1) orelse return null_event; 406 + key.mods = @bitCast(modifier_mask -| 1); 374 407 375 - const key: Key = .{ 376 - .codepoint = key_code, 377 - .mods = modifiers, 378 - }; 408 + if (param_iter.next()) |event_type_buf| { 409 + is_release = std.mem.eql(u8, event_type_buf, "3"); 410 + } 411 + } 379 412 413 + field3: { 414 + // text_as_codepoint[:text_as_codepoint] 415 + const field_buf = field_iter.next() orelse break :field3; 416 + var param_iter = std.mem.splitScalar(u8, field_buf, ':'); 417 + var total: usize = 0; 418 + while (param_iter.next()) |cp_buf| { 419 + const cp = parseParam(u21, cp_buf, null) orelse return null_event; 420 + total += std.unicode.utf8Encode(cp, text_buf[total..]) catch return null_event; 421 + } 422 + key.text = text_buf[0..total]; 423 + } 424 + 425 + const event: Event = if (is_release) .{ .key_release = key } else .{ .key_press = key }; 380 426 return .{ 381 - .event = .{ .key_press = key }, 427 + .event = event, 382 428 .n = sequence.len, 383 429 }; 384 430 },