diff --git a/src/terminal/Terminal.zig b/src/terminal/Terminal.zig index 29f80c6f7..48d59835c 100644 --- a/src/terminal/Terminal.zig +++ b/src/terminal/Terminal.zig @@ -1093,12 +1093,35 @@ pub fn semanticPrompt( // command but we don't yet handle these in any meaningful way. }, + .prompt_start => { + // Explicit start of prompt. Optional after an A or N command. + // The k (kind) option specifies the type of prompt: + // regular primary prompt (k=i or default), + // right-side prompts (k=r), or prompts for continuation lines (k=c or k=s). + + // As noted above, we don't currently utilize the prompt type. + self.screens.active.cursor.semantic_content = .prompt; + }, + .end_prompt_start_input => { // End of prompt and start of user input, terminated by a OSC // "133;C" or another prompt (OSC "133;P"). self.screens.active.cursor.semantic_content = .input; }, + .end_input_start_output => { + // "End of input, and start of output." + self.screens.active.cursor.semantic_content = .output; + }, + + .end_command => { + // From a terminal state perspective, this doesn't really do + // anything. Other terminals appear to do nothing here. I think + // its reasonable at this point to reset our semantic content + // state but the spec doesn't really say what to do. + self.screens.active.cursor.semantic_content = .output; + }, + else => {}, } } diff --git a/src/terminal/stream_readonly.zig b/src/terminal/stream_readonly.zig index fcb6d123f..af4048973 100644 --- a/src/terminal/stream_readonly.zig +++ b/src/terminal/stream_readonly.zig @@ -934,7 +934,7 @@ test "semantic prompt fresh line new prompt" { try testing.expect(t.flags.shell_redraws_prompt); } -test "semantic prompt end prompt start input" { +test "semantic prompt end of input, then start output" { var t: Terminal = try .init(testing.allocator, .{ .cols = 10, .rows = 10 }); defer t.deinit(testing.allocator); @@ -947,4 +947,23 @@ test "semantic prompt end prompt start input" { try s.nextSlice("prompt$ "); try s.nextSlice("\x1b]133;B\x07"); try testing.expectEqual(.input, t.screens.active.cursor.semantic_content); + try s.nextSlice("\x1b]133;C\x07"); + try testing.expectEqual(.output, t.screens.active.cursor.semantic_content); +} + +test "semantic prompt prompt_start" { + var t: Terminal = try .init(testing.allocator, .{ .cols = 10, .rows = 10 }); + defer t.deinit(testing.allocator); + + var s: Stream = .initAlloc(testing.allocator, .init(&t)); + defer s.deinit(); + + // Write some text + try s.nextSlice("Hello"); + + // OSC 133;P marks the start of a prompt (without fresh line behavior) + try s.nextSlice("\x1b]133;P\x07"); + try testing.expectEqual(.prompt, t.screens.active.cursor.semantic_content); + try testing.expectEqual(@as(usize, 5), t.screens.active.cursor.x); + try testing.expectEqual(@as(usize, 0), t.screens.active.cursor.y); }