From d74658fdb5369a979df45682f341e1850b6ce867 Mon Sep 17 00:00:00 2001 From: Antonio Scandurra Date: Thu, 13 Jan 2022 15:10:50 +0100 Subject: [PATCH] Allow searching of outline items --- Cargo.lock | 2 ++ crates/outline/Cargo.toml | 1 + crates/outline/src/outline.rs | 51 +++++++++++++++++++++++++---------- 3 files changed, 40 insertions(+), 14 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 289ed1957ebc494ca7a8770b08ba31c64d29538e..ef2be46b9d3883a6732452901b70b3c713f72a05 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2602,6 +2602,7 @@ dependencies = [ "ctor", "env_logger", "futures", + "fuzzy", "gpui", "lazy_static", "log", @@ -3126,6 +3127,7 @@ name = "outline" version = "0.1.0" dependencies = [ "editor", + "fuzzy", "gpui", "language", "postage", diff --git a/crates/outline/Cargo.toml b/crates/outline/Cargo.toml index 4a6d4630888bac6a7171d0574da3de10c6873ea0..5383e676610b47d7d5dffcfbe197cc0590fdd422 100644 --- a/crates/outline/Cargo.toml +++ b/crates/outline/Cargo.toml @@ -8,6 +8,7 @@ path = "src/outline.rs" [dependencies] editor = { path = "../editor" } +fuzzy = { path = "../fuzzy" } gpui = { path = "../gpui" } language = { path = "../language" } text = { path = "../text" } diff --git a/crates/outline/src/outline.rs b/crates/outline/src/outline.rs index 7ac63f1382d4b095d5a5d4dd52976ddba2553d00..d692358faeffbe4e70b7ad58f7bd1659b0b97d61 100644 --- a/crates/outline/src/outline.rs +++ b/crates/outline/src/outline.rs @@ -1,12 +1,12 @@ -use editor::{display_map::ToDisplayPoint, Autoscroll, Editor, EditorSettings}; +use editor::{Editor, EditorSettings}; +use fuzzy::StringMatch; use gpui::{ - action, elements::*, geometry::vector::Vector2F, keymap::Binding, Axis, Entity, - MutableAppContext, RenderContext, View, ViewContext, ViewHandle, WeakViewHandle, + action, elements::*, keymap::Binding, Axis, Entity, MutableAppContext, RenderContext, View, + ViewContext, ViewHandle, WeakViewHandle, }; -use language::{Outline, OutlineItem}; +use language::Outline; use postage::watch; use std::{cmp, sync::Arc}; -use text::{Bias, Point, Selection}; use workspace::{Settings, Workspace}; action!(Toggle); @@ -25,7 +25,7 @@ pub fn init(cx: &mut MutableAppContext) { struct OutlineView { handle: WeakViewHandle, outline: Outline, - matches: Vec, + matches: Vec, query_editor: ViewHandle, list_state: UniformListState, settings: watch::Receiver, @@ -40,7 +40,7 @@ impl View for OutlineView { "OutlineView" } - fn render(&mut self, cx: &mut RenderContext<'_, Self>) -> ElementBox { + fn render(&mut self, _: &mut RenderContext) -> ElementBox { let settings = self.settings.borrow(); Align::new( @@ -95,14 +95,16 @@ impl OutlineView { }); cx.subscribe(&query_editor, Self::on_query_editor_event) .detach(); - Self { + let mut this = Self { handle: cx.weak_handle(), - matches: outline.0.clone(), + matches: Default::default(), outline, query_editor, list_state: Default::default(), settings, - } + }; + this.update_matches(cx); + this } fn toggle(workspace: &mut Workspace, _: &Toggle, cx: &mut ViewContext) { @@ -129,13 +131,32 @@ impl OutlineView { cx: &mut ViewContext, ) { match event { - editor::Event::Edited => { - let query = self.query_editor.update(cx, |buffer, cx| buffer.text(cx)); - } + editor::Event::Edited => self.update_matches(cx), _ => {} } } + fn update_matches(&mut self, cx: &mut ViewContext) { + let query = self.query_editor.update(cx, |buffer, cx| buffer.text(cx)); + if query.is_empty() { + self.matches = self + .outline + .items + .iter() + .enumerate() + .map(|(index, _)| StringMatch { + candidate_index: index, + score: Default::default(), + positions: Default::default(), + string: Default::default(), + }) + .collect(); + } else { + self.matches = self.outline.search(&query, cx); + } + cx.notify(); + } + fn render_matches(&self) -> ElementBox { if self.matches.is_empty() { let settings = self.settings.borrow(); @@ -172,7 +193,7 @@ impl OutlineView { .named("matches") } - fn render_match(&self, outline_match: &OutlineItem, index: usize) -> ElementBox { + fn render_match(&self, string_match: &StringMatch, index: usize) -> ElementBox { // TODO: maintain selected index. let selected_index = 0; let settings = self.settings.borrow(); @@ -181,8 +202,10 @@ impl OutlineView { } else { &settings.theme.selector.item }; + let outline_match = &self.outline.items[string_match.candidate_index]; Label::new(outline_match.text.clone(), style.label.clone()) + .with_highlights(string_match.positions.clone()) .contained() .with_padding_left(20. * outline_match.depth as f32) .contained()