diff --git a/wezterm-gui/src/overlay/copy.rs b/wezterm-gui/src/overlay/copy.rs index e4a16077d..9c678c37b 100644 --- a/wezterm-gui/src/overlay/copy.rs +++ b/wezterm-gui/src/overlay/copy.rs @@ -825,7 +825,7 @@ impl CopyRenderable { self.select_to_cursor_pos(); } - fn move_forward_one_word(&mut self, end: bool) { + fn move_forward_one_word(&mut self) { let y = self.cursor.y; let (top, lines) = self.delegate.get_lines(y..y + 1); if let Some(line) = lines.get(0) { @@ -835,34 +835,73 @@ impl CopyRenderable { let mut words = s.split_word_bounds(); if let Some(word) = words.next() { - if end { - // Move to the end of the current word - self.cursor.x += unicode_column_width(word, None); - } else { - // Move to the start of the next word - if !is_whitespace_word(word) { - // We were part-way through a word, so look - // at the next word - if let Some(word) = words.next() { - if is_whitespace_word(word) { - self.cursor.x += unicode_column_width(word, None); - // If we advance off the RHS, move to the start of the word on the - // next line, if any! - if self.cursor.x >= width { - let dims = self.delegate.get_dimensions(); - let max_row = dims.scrollback_top + dims.scrollback_rows as isize; - if self.cursor.y + 1 < max_row { - self.cursor.y += 1; - return self.move_to_start_of_line_content(); - } + self.cursor.x += unicode_column_width(word, None); + if !is_whitespace_word(word) { + // We were part-way through a word, so look + // at the next word + if let Some(word) = words.next() { + if is_whitespace_word(word) { + self.cursor.x += unicode_column_width(word, None); + // If we advance off the RHS, move to the start of the word on the + // next line, if any! + if self.cursor.x >= width { + let dims = self.delegate.get_dimensions(); + let max_row = dims.scrollback_top + dims.scrollback_rows as isize; + if self.cursor.y + 1 < max_row { + self.cursor.y += 1; + return self.move_to_start_of_line_content(); } } } - } else { - // We were in whitespace and advancing - // has put us at the start of the next word + } + } else { + // We were in whitespace and advancing + // has put us at the start of the next word + } + } + } + self.select_to_cursor_pos(); + } + + fn move_to_end_of_word(&mut self) { + let y = self.cursor.y; + let (top, lines) = self.delegate.get_lines(y..y + 1); + if let Some(line) = lines.get(0) { + self.cursor.y = top; + let width = line.len(); + let s = line.columns_as_str(self.cursor.x..width + 1); + let mut words = s.split_word_bounds(); + + if self.cursor.x >= width - 1 { + let dims = self.delegate.get_dimensions(); + let max_row = dims.scrollback_top + dims.scrollback_rows as isize; + if self.cursor.y + 1 < max_row { + self.cursor.y += 1; + self.cursor.x = 0; + return self.move_to_end_of_word(); + } + } + + if let Some(word) = words.next() { + let mut word_end = self.cursor.x + unicode_column_width(word, None); + if !is_whitespace_word(word) { + if self.cursor.x == word_end - 1 { + while let Some(next_word) = words.next() { + word_end += unicode_column_width(next_word, None); + if !is_whitespace_word(next_word) { + break; + } + } } } + while let Some(next_word) = words.next() { + if !is_whitespace_word(next_word) { + word_end += unicode_column_width(next_word, None); + } else { + break; + } + } + self.cursor.x = word_end - 1; } } self.select_to_cursor_pos(); @@ -1115,8 +1154,8 @@ impl Pane for CopyOverlay { MoveToSelectionOtherEnd => render.move_to_selection_other_end(), MoveToSelectionOtherEndHoriz => render.move_to_selection_other_end_horiz(), MoveBackwardWord => render.move_backward_one_word(), - MoveForwardWord => render.move_forward_one_word(false), - MoveForwardWordEnd => render.move_forward_one_word(true), + MoveForwardWord => render.move_forward_one_word(), + MoveForwardWordEnd => render.move_to_end_of_word(), MoveRight => render.move_right_single_cell(), MoveLeft => render.move_left_single_cell(), MoveUp => render.move_up_single_row(),