terminal: OSC 133 P

This commit is contained in:
Mitchell Hashimoto
2026-01-24 14:10:57 -08:00
parent acd7a448e1
commit af12241d88
2 changed files with 43 additions and 1 deletions

View File

@@ -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 => {},
}
}

View File

@@ -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);
}