mirror of
https://github.com/wez/wezterm.git
synced 2024-12-23 13:21:38 +03:00
support MarkEndOfPromptAndStartOfInputUntilEndOfLine semantic mode
It's a little ambiguous whether we should cancel the mode when moving the cursor explicitly; I opted to do it when we move it due to newline processing, or when its y position is changed. refs: #1539
This commit is contained in:
parent
c6acd544ed
commit
3ee9270e3c
@ -253,6 +253,8 @@ pub struct TerminalState {
|
||||
/// printed character
|
||||
wrap_next: bool,
|
||||
|
||||
clear_semantic_attribute_on_newline: bool,
|
||||
|
||||
/// If true, writing a character inserts a new cell
|
||||
insert: bool,
|
||||
|
||||
@ -452,6 +454,7 @@ impl TerminalState {
|
||||
left_and_right_margins: 0..size.physical_cols,
|
||||
left_and_right_margin_mode: false,
|
||||
wrap_next: false,
|
||||
clear_semantic_attribute_on_newline: false,
|
||||
// We default auto wrap to true even though the default for
|
||||
// a dec terminal is false, because it is more useful this way.
|
||||
dec_auto_wrap: true,
|
||||
@ -837,8 +840,18 @@ impl TerminalState {
|
||||
&self.user_vars
|
||||
}
|
||||
|
||||
fn clear_semantic_attribute_due_to_movement(&mut self) {
|
||||
if self.clear_semantic_attribute_on_newline {
|
||||
self.clear_semantic_attribute_on_newline = false;
|
||||
self.pen.set_semantic_type(SemanticType::default());
|
||||
}
|
||||
}
|
||||
|
||||
/// Sets the cursor position to precisely the x and values provided
|
||||
fn set_cursor_position_absolute(&mut self, x: usize, y: VisibleRowIndex) {
|
||||
if self.cursor.y != y {
|
||||
self.clear_semantic_attribute_due_to_movement();
|
||||
}
|
||||
self.cursor.y = y;
|
||||
self.cursor.x = x;
|
||||
self.cursor.seqno = self.seqno;
|
||||
|
@ -305,6 +305,7 @@ impl<'a> Performer<'a> {
|
||||
}
|
||||
if self.newline_mode {
|
||||
self.cursor.x = 0;
|
||||
self.clear_semantic_attribute_due_to_movement();
|
||||
}
|
||||
}
|
||||
ControlCode::CarriageReturn => {
|
||||
@ -315,6 +316,7 @@ impl<'a> Performer<'a> {
|
||||
}
|
||||
let y = self.cursor.y;
|
||||
self.wrap_next = false;
|
||||
self.clear_semantic_attribute_due_to_movement();
|
||||
self.screen_mut().dirty_line(y, seqno);
|
||||
}
|
||||
|
||||
@ -503,6 +505,7 @@ impl<'a> Performer<'a> {
|
||||
self.pen = Default::default();
|
||||
self.cursor = Default::default();
|
||||
self.wrap_next = false;
|
||||
self.clear_semantic_attribute_on_newline = false;
|
||||
self.insert = false;
|
||||
self.dec_auto_wrap = true;
|
||||
self.reverse_wraparound_mode = false;
|
||||
@ -657,6 +660,12 @@ impl<'a> Performer<'a> {
|
||||
) => {
|
||||
self.pen.set_semantic_type(SemanticType::Input);
|
||||
}
|
||||
OperatingSystemCommand::FinalTermSemanticPrompt(
|
||||
FinalTermSemanticPrompt::MarkEndOfPromptAndStartOfInputUntilEndOfLine { .. },
|
||||
) => {
|
||||
self.pen.set_semantic_type(SemanticType::Input);
|
||||
self.clear_semantic_attribute_on_newline = true;
|
||||
}
|
||||
OperatingSystemCommand::FinalTermSemanticPrompt(
|
||||
FinalTermSemanticPrompt::MarkEndOfInputAndStartOfOutput { .. },
|
||||
) => {
|
||||
@ -667,10 +676,6 @@ impl<'a> Performer<'a> {
|
||||
FinalTermSemanticPrompt::CommandStatus { .. },
|
||||
) => {}
|
||||
|
||||
OperatingSystemCommand::FinalTermSemanticPrompt(ft) => {
|
||||
log::warn!("unhandled: {:?}", ft);
|
||||
}
|
||||
|
||||
OperatingSystemCommand::SystemNotification(message) => {
|
||||
if let Some(handler) = self.alert_handler.as_mut() {
|
||||
handler.alert(Alert::ToastNotification {
|
||||
|
@ -316,6 +316,53 @@ fn assert_all_contents(term: &Terminal, file: &str, line: u32, expect_lines: &[&
|
||||
assert_lines_equal(file, line, &screen.all_lines(), &expect, Compare::TEXT);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_semantic_1539() {
|
||||
use termwiz::escape::osc::FinalTermSemanticPrompt;
|
||||
let mut term = TestTerm::new(5, 10, 0);
|
||||
term.print(format!(
|
||||
"{}prompt\r\nwoot",
|
||||
OperatingSystemCommand::FinalTermSemanticPrompt(
|
||||
FinalTermSemanticPrompt::MarkEndOfPromptAndStartOfInputUntilEndOfLine
|
||||
)
|
||||
));
|
||||
|
||||
assert_visible_contents(
|
||||
&term,
|
||||
file!(),
|
||||
line!(),
|
||||
&[
|
||||
"prompt ",
|
||||
"woot ",
|
||||
" ",
|
||||
" ",
|
||||
" ",
|
||||
],
|
||||
);
|
||||
|
||||
k9::snapshot!(
|
||||
term.get_semantic_zones().unwrap(),
|
||||
"
|
||||
[
|
||||
SemanticZone {
|
||||
start_y: 0,
|
||||
start_x: 0,
|
||||
end_y: 0,
|
||||
end_x: 5,
|
||||
semantic_type: Input,
|
||||
},
|
||||
SemanticZone {
|
||||
start_y: 1,
|
||||
start_x: 0,
|
||||
end_y: 4,
|
||||
end_x: 9,
|
||||
semantic_type: Output,
|
||||
},
|
||||
]
|
||||
"
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_semantic() {
|
||||
use termwiz::escape::osc::FinalTermSemanticPrompt;
|
||||
|
Loading…
Reference in New Issue
Block a user