Unnamed repository; edit this file 'description' to name the repository.
Diffstat (limited to 'helix-term/src/ui/prompt.rs')
| -rw-r--r-- | helix-term/src/ui/prompt.rs | 65 |
1 files changed, 15 insertions, 50 deletions
diff --git a/helix-term/src/ui/prompt.rs b/helix-term/src/ui/prompt.rs index d2448335..ee5c46e7 100644 --- a/helix-term/src/ui/prompt.rs +++ b/helix-term/src/ui/prompt.rs @@ -12,9 +12,7 @@ use tui::text::Span; use tui::widgets::{Block, Widget}; use helix_core::{ - unicode::segmentation::{GraphemeCursor, UnicodeSegmentation}, - unicode::width::UnicodeWidthStr, - Position, + unicode::segmentation::GraphemeCursor, unicode::width::UnicodeWidthStr, Position, }; use helix_view::{ graphics::{CursorKind, Margin, Rect}, @@ -537,51 +535,21 @@ impl Prompt { .into(); text.render(self.line_area, surface, cx); } else { - let line_width = self.line_area.width as usize; - - if self.line.width() < line_width { + if self.line.len() < self.line_area.width as usize { self.anchor = 0; - } else if self.cursor <= self.anchor { - // Ensure the grapheme under the cursor is in view. - self.anchor = self.line[..self.cursor] - .grapheme_indices(true) - .next_back() - .map(|(i, _)| i) - .unwrap_or_default(); - } else if self.line[self.anchor..self.cursor].width() > line_width { - // Set the anchor to the last grapheme cluster before the width is exceeded. - let mut width = 0; - self.anchor = self.line[..self.cursor] - .grapheme_indices(true) - .rev() - .find_map(|(idx, g)| { - width += g.width(); - if width > line_width { - Some(idx + g.len()) - } else { - None - } - }) - .unwrap(); + } else if self.cursor < self.anchor { + self.anchor = self.cursor; + } else if self.cursor - self.anchor > self.line_area.width as usize { + self.anchor = self.cursor - self.line_area.width as usize; } self.truncate_start = self.anchor > 0; - self.truncate_end = self.line[self.anchor..].width() > line_width; + self.truncate_end = self.line.len() - self.anchor > self.line_area.width as usize; // if we keep inserting characters just before the end elipsis, we move the anchor // so that those new characters are displayed - if self.truncate_end && self.line[self.anchor..self.cursor].width() >= line_width { - // Move the anchor forward by one non-zero-width grapheme. - self.anchor += self.line[self.anchor..] - .grapheme_indices(true) - .find_map(|(idx, g)| { - if g.width() > 0 { - Some(idx + g.len()) - } else { - None - } - }) - .unwrap(); + if self.truncate_end && self.cursor - self.anchor >= self.line_area.width as usize { + self.anchor += 1; } surface.set_string_anchored( @@ -590,7 +558,7 @@ impl Prompt { self.truncate_start, self.truncate_end, &self.line.as_str()[self.anchor..], - line_width, + self.line_area.width as usize - self.truncate_end as usize, |_| prompt_color, ); } @@ -766,20 +734,17 @@ impl Component for Prompt { .clip_left(self.prompt.len() as u16) .clip_right(if self.prompt.is_empty() { 2 } else { 0 }); - let mut col = area.left() as usize + self.line[self.anchor..self.cursor].width(); + let anchor = self.anchor.min(self.line.len().saturating_sub(1)); + let mut col = area.left() as usize + + UnicodeWidthStr::width(&self.line[anchor..self.cursor.max(anchor)]); // ensure the cursor does not go beyond elipses - if self.truncate_end - && self.line[self.anchor..self.cursor].width() >= self.line_area.width as usize - { + if self.truncate_end && self.cursor - self.anchor >= self.line_area.width as usize { col -= 1; } if self.truncate_start && self.cursor == self.anchor { - col += self.line[self.cursor..] - .graphemes(true) - .next() - .map_or(0, |g| g.width()); + col += 1; } let line = area.height as usize - 1; |