diff --git a/src/screen.rs b/src/screen.rs index 4ac00e20d..213d08e92 100644 --- a/src/screen.rs +++ b/src/screen.rs @@ -1117,7 +1117,7 @@ fn update( self.r#move(0, 0); let mut start = 0; let mark_prompt_start = |zelf: &mut Screen| zelf.write_command(Osc133PromptStart); - if left_prompt_layout.line_breaks.is_empty() { + if left_prompt_layout.line_starts.len() <= 1 { mark_prompt_start(self); } if self @@ -1126,16 +1126,16 @@ fn update( .is_none_or(|p| p != left_prompt) || (self.scrolled && is_final_rendering) { - for (i, &line_break) in left_prompt_layout.line_breaks.iter().enumerate() { + for (i, &next_line) in left_prompt_layout.line_starts[1..].iter().enumerate() { self.write_command(ClearToEndOfLine); if i == 0 { mark_prompt_start(self); } - self.write_str(&left_prompt[start..=line_break]); - start = line_break + 1; + self.write_str(&left_prompt[start..next_line]); + start = next_line; } } else { - start = left_prompt_layout.line_breaks.last().map_or(0, |lb| lb + 1); + start = *left_prompt_layout.line_starts.last().unwrap(); } self.write_str(&left_prompt[start..]); self.actual_left_prompt = Some(left_prompt.to_owned()); @@ -1359,9 +1359,9 @@ pub fn screen_force_clear_to_end() { /// Information about the layout of a prompt. #[derive(Clone, Debug, Default, Eq, PartialEq)] pub struct PromptLayout { - /// line breaks when rendering the prompt - pub line_breaks: Vec, - /// width of the last line + /// Start offsets for each line in the truncated prompt. + pub line_starts: Vec, + /// Width of the last line. pub last_line_width: usize, } @@ -1470,6 +1470,7 @@ pub fn calc_prompt_layout( } let mut layout = PromptLayout::default(); + layout.line_starts.push(0); let mut trunc_prompt = WString::new(); let mut run_start = 0; @@ -1490,7 +1491,7 @@ pub fn calc_prompt_layout( let endc = prompt_str.char_at(run_end); if endc != '\0' { if endc == '\n' || endc == '\x0C' { - layout.line_breaks.push(trunc_prompt.len()); + layout.line_starts.push(trunc_prompt.len() + 1); // If the prompt ends in a new line, that's one empty last line. if run_end == prompt_str.len() - 1 { layout.last_line_width = 0; @@ -1857,9 +1858,8 @@ fn calc_prompt_lines(prompt: &wstr) -> usize { .lock() .unwrap() .calc_prompt_layout(prompt, None, usize::MAX) - .line_breaks - .len() - + 1; + .line_starts + .len(); } result } diff --git a/src/tests/screen.rs b/src/tests/screen.rs index 46c93d633..0caed14c3 100644 --- a/src/tests/screen.rs +++ b/src/tests/screen.rs @@ -80,7 +80,7 @@ fn test_layout_cache() { max_line_width: huge, trunc_text: input.clone(), layout: PromptLayout { - line_breaks: vec![], + line_starts: vec![], last_line_width: i, }, }); @@ -101,7 +101,7 @@ fn test_layout_cache() { max_line_width: huge, trunc_text: "whatever".into(), layout: PromptLayout { - line_breaks: vec![], + line_starts: vec![], last_line_width: 100, }, }); @@ -127,7 +127,7 @@ fn test_prompt_truncation() { assert_eq!( layout, PromptLayout { - line_breaks: vec![], + line_starts: vec![0], last_line_width: 4, } ); @@ -147,7 +147,7 @@ fn test_prompt_truncation() { assert_eq!( layout, PromptLayout { - line_breaks: vec![16, 23, 40], + line_starts: vec![0, 17, 24, 41], last_line_width: 3, } ); @@ -157,7 +157,7 @@ fn test_prompt_truncation() { assert_eq!( layout, PromptLayout { - line_breaks: vec![], + line_starts: vec![0], last_line_width: 8, }, ); @@ -177,7 +177,7 @@ fn test_prompt_truncation() { assert_eq!( layout, PromptLayout { - line_breaks: vec![8, 15, 24], + line_starts: vec![0, 9, 16, 25], last_line_width: 3, }, ); @@ -203,7 +203,7 @@ fn test_prompt_truncation() { assert_eq!( layout, PromptLayout { - line_breaks: vec![], + line_starts: vec![0], last_line_width: 4, }, ); @@ -218,7 +218,7 @@ fn test_prompt_truncation() { assert_eq!( layout, PromptLayout { - line_breaks: vec![], + line_starts: vec![0], last_line_width: 4, }, ); @@ -232,7 +232,7 @@ fn test_prompt_truncation() { assert_eq!( layout, PromptLayout { - line_breaks: vec![], + line_starts: vec![0], last_line_width: 1, }, );