diff --git a/Cargo.lock b/Cargo.lock index 1094fced2c..3775ab6b3a 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -12560,6 +12560,7 @@ dependencies = [ "lsp", "menu", "picker", + "picker_preview", "project", "rope", "serde_json", diff --git a/crates/outline/Cargo.toml b/crates/outline/Cargo.toml index 8b49b5a287..ba661b36f9 100644 --- a/crates/outline/Cargo.toml +++ b/crates/outline/Cargo.toml @@ -18,6 +18,7 @@ fuzzy_nucleo.workspace = true gpui.workspace = true language.workspace = true picker.workspace = true +picker_preview.workspace = true settings.workspace = true theme.workspace = true theme_settings.workspace = true diff --git a/crates/outline/src/outline.rs b/crates/outline/src/outline.rs index ffd11e3197..0f22226f89 100644 --- a/crates/outline/src/outline.rs +++ b/crates/outline/src/outline.rs @@ -10,8 +10,8 @@ use gpui::{ ParentElement, Point, Rems, Render, Styled, StyledText, Task, TextStyle, WeakEntity, Window, div, rems, }; -use language::{Outline, OutlineItem, OutlineSearchEntry}; -use picker::{Picker, PickerDelegate}; +use language::{OffsetRangeExt, Outline, OutlineItem, OutlineSearchEntry}; +use picker::{MatchLocation, Picker, PickerDelegate, PreviewUpdate}; use settings::Settings; use theme::ActiveTheme; use theme_settings::ThemeSettings; @@ -176,9 +176,16 @@ impl OutlineView { window: &mut Window, cx: &mut Context, ) -> OutlineView { + let project = editor.read(cx).project().cloned(); let delegate = OutlineViewDelegate::new(cx.entity().downgrade(), outline, editor, cx); let picker = cx.new(|cx| { - Picker::uniform_list(delegate, window, cx) + let picker = if let Some(project) = project { + let preview = picker_preview::editor_preview(project, window, cx); + Picker::uniform_list_with_preview(delegate, preview, window, cx) + } else { + Picker::uniform_list(delegate, window, cx) + }; + picker .max_height(Rems::from_pixels( window.viewport_size().height * 0.75, window, @@ -293,6 +300,30 @@ impl PickerDelegate for OutlineViewDelegate { self.set_selected_index(ix, true, cx); } + fn try_get_preview_data_for_match(&self, cx: &App) -> Option { + let selected_match = self.matches.get(self.selected_match_index)?; + let outline_item = self.outline.items.get(selected_match.candidate_id())?; + let multi_buffer = self.active_editor.read(cx).buffer().clone(); + let (buffer, start) = multi_buffer + .read(cx) + .text_anchor_for_position(outline_item.selection_range.start, cx)?; + let (end_buffer, end) = multi_buffer + .read(cx) + .text_anchor_for_position(outline_item.selection_range.end, cx)?; + if buffer != end_buffer { + return None; + } + + let range = (start..end).to_offset(&buffer.read(cx).text_snapshot()); + Some(PreviewUpdate::from_buffer( + buffer, + MatchLocation { + anchor_range: start..end, + range, + }, + )) + } + fn update_matches( &mut self, query: String,