diff --git a/crates/editor/src/editor.rs b/crates/editor/src/editor.rs index 97dae71168..7a9af28614 100644 --- a/crates/editor/src/editor.rs +++ b/crates/editor/src/editor.rs @@ -170,7 +170,7 @@ use ui::{ h_flex, prelude::*, ButtonSize, ButtonStyle, Disclosure, IconButton, IconName, IconSize, Key, Tooltip, }; -use util::{defer, maybe, post_inc, RangeExt, ResultExt, TakeUntilExt, TryFutureExt}; +use util::{defer, maybe, post_inc, RangeExt, ResultExt, TryFutureExt}; use workspace::item::{ItemHandle, PreviewTabsSettings}; use workspace::notifications::{DetachAndPromptErr, NotificationId, NotifyTaskExt}; use workspace::{ @@ -5994,52 +5994,23 @@ impl Editor { } => { let first_edit_row = edits.first()?.0.start.text_anchor.to_point(&snapshot).row; - let highlighted_edits = crate::inline_completion_edit_text( + let (highlighted_edits, has_more_lines) = crate::inline_completion_edit_text( &snapshot, &edits, edit_preview.as_ref()?, true, cx, - ); + ) + .first_line_preview(); - let len_total = highlighted_edits.text.len(); - let first_line = &highlighted_edits.text - [..highlighted_edits.text.find('\n').unwrap_or(len_total)]; - let first_line_len = first_line.len(); - - let first_highlight_start = highlighted_edits - .highlights - .first() - .map_or(0, |(range, _)| range.start); - let drop_prefix_len = first_line - .char_indices() - .find(|(_, c)| !c.is_whitespace()) - .map_or(first_highlight_start, |(ix, _)| { - ix.min(first_highlight_start) - }); - - let preview_text = &first_line[drop_prefix_len..]; - let preview_len = preview_text.len(); - let highlights = highlighted_edits - .highlights - .into_iter() - .take_until(|(range, _)| range.start > first_line_len) - .map(|(range, style)| { - ( - range.start - drop_prefix_len - ..(range.end - drop_prefix_len).min(preview_len), - style, - ) - }); - - let styled_text = gpui::StyledText::new(SharedString::new(preview_text)) - .with_highlights(&style.text, highlights); + let styled_text = gpui::StyledText::new(highlighted_edits.text) + .with_highlights(&style.text, highlighted_edits.highlights); let preview = h_flex() .gap_1() .min_w_16() .child(styled_text) - .when(len_total > first_line_len, |parent| parent.child("…")); + .when(has_more_lines, |parent| parent.child("…")); let left = if first_edit_row != cursor_point.row { render_relative_row_jump("", cursor_point.row, first_edit_row) diff --git a/crates/language/src/buffer.rs b/crates/language/src/buffer.rs index 826c627567..e3fbebb9c8 100644 --- a/crates/language/src/buffer.rs +++ b/crates/language/src/buffer.rs @@ -622,6 +622,41 @@ impl HighlightedText { gpui::StyledText::new(self.text.clone()) .with_highlights(default_style, self.highlights.iter().cloned()) } + + /// Returns the first line without leading whitespace unless highlighted + /// and a boolean indicating if there are more lines after + pub fn first_line_preview(self) -> (Self, bool) { + let newline_ix = self.text.find('\n').unwrap_or(self.text.len()); + let first_line = &self.text[..newline_ix]; + + // Trim leading whitespace, unless an edit starts prior to it. + let mut preview_start_ix = first_line.len() - first_line.trim_start().len(); + if let Some((first_highlight_range, _)) = self.highlights.first() { + preview_start_ix = preview_start_ix.min(first_highlight_range.start); + } + + let preview_text = &first_line[preview_start_ix..]; + let preview_highlights = self + .highlights + .into_iter() + .take_while(|(range, _)| range.start < newline_ix) + .filter_map(|(mut range, highlight)| { + range.start = range.start.saturating_sub(preview_start_ix); + range.end = range.end.saturating_sub(preview_start_ix).min(newline_ix); + if range.is_empty() { + None + } else { + Some((range, highlight)) + } + }); + + let preview = Self { + text: SharedString::new(preview_text), + highlights: preview_highlights.collect(), + }; + + (preview, self.text.len() > newline_ix) + } } impl HighlightedTextBuilder {