Allow searching of outline items

This commit is contained in:
Antonio Scandurra 2022-01-13 15:10:50 +01:00
parent 06ba1c64cf
commit d74658fdb5
3 changed files with 40 additions and 14 deletions

2
Cargo.lock generated
View file

@ -2602,6 +2602,7 @@ dependencies = [
"ctor", "ctor",
"env_logger", "env_logger",
"futures", "futures",
"fuzzy",
"gpui", "gpui",
"lazy_static", "lazy_static",
"log", "log",
@ -3126,6 +3127,7 @@ name = "outline"
version = "0.1.0" version = "0.1.0"
dependencies = [ dependencies = [
"editor", "editor",
"fuzzy",
"gpui", "gpui",
"language", "language",
"postage", "postage",

View file

@ -8,6 +8,7 @@ path = "src/outline.rs"
[dependencies] [dependencies]
editor = { path = "../editor" } editor = { path = "../editor" }
fuzzy = { path = "../fuzzy" }
gpui = { path = "../gpui" } gpui = { path = "../gpui" }
language = { path = "../language" } language = { path = "../language" }
text = { path = "../text" } text = { path = "../text" }

View file

@ -1,12 +1,12 @@
use editor::{display_map::ToDisplayPoint, Autoscroll, Editor, EditorSettings}; use editor::{Editor, EditorSettings};
use fuzzy::StringMatch;
use gpui::{ use gpui::{
action, elements::*, geometry::vector::Vector2F, keymap::Binding, Axis, Entity, action, elements::*, keymap::Binding, Axis, Entity, MutableAppContext, RenderContext, View,
MutableAppContext, RenderContext, View, ViewContext, ViewHandle, WeakViewHandle, ViewContext, ViewHandle, WeakViewHandle,
}; };
use language::{Outline, OutlineItem}; use language::Outline;
use postage::watch; use postage::watch;
use std::{cmp, sync::Arc}; use std::{cmp, sync::Arc};
use text::{Bias, Point, Selection};
use workspace::{Settings, Workspace}; use workspace::{Settings, Workspace};
action!(Toggle); action!(Toggle);
@ -25,7 +25,7 @@ pub fn init(cx: &mut MutableAppContext) {
struct OutlineView { struct OutlineView {
handle: WeakViewHandle<Self>, handle: WeakViewHandle<Self>,
outline: Outline, outline: Outline,
matches: Vec<OutlineItem>, matches: Vec<StringMatch>,
query_editor: ViewHandle<Editor>, query_editor: ViewHandle<Editor>,
list_state: UniformListState, list_state: UniformListState,
settings: watch::Receiver<Settings>, settings: watch::Receiver<Settings>,
@ -40,7 +40,7 @@ impl View for OutlineView {
"OutlineView" "OutlineView"
} }
fn render(&mut self, cx: &mut RenderContext<'_, Self>) -> ElementBox { fn render(&mut self, _: &mut RenderContext<Self>) -> ElementBox {
let settings = self.settings.borrow(); let settings = self.settings.borrow();
Align::new( Align::new(
@ -95,14 +95,16 @@ impl OutlineView {
}); });
cx.subscribe(&query_editor, Self::on_query_editor_event) cx.subscribe(&query_editor, Self::on_query_editor_event)
.detach(); .detach();
Self { let mut this = Self {
handle: cx.weak_handle(), handle: cx.weak_handle(),
matches: outline.0.clone(), matches: Default::default(),
outline, outline,
query_editor, query_editor,
list_state: Default::default(), list_state: Default::default(),
settings, settings,
} };
this.update_matches(cx);
this
} }
fn toggle(workspace: &mut Workspace, _: &Toggle, cx: &mut ViewContext<Workspace>) { fn toggle(workspace: &mut Workspace, _: &Toggle, cx: &mut ViewContext<Workspace>) {
@ -129,13 +131,32 @@ impl OutlineView {
cx: &mut ViewContext<Self>, cx: &mut ViewContext<Self>,
) { ) {
match event { match event {
editor::Event::Edited => { editor::Event::Edited => self.update_matches(cx),
let query = self.query_editor.update(cx, |buffer, cx| buffer.text(cx));
}
_ => {} _ => {}
} }
} }
fn update_matches(&mut self, cx: &mut ViewContext<Self>) {
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 { fn render_matches(&self) -> ElementBox {
if self.matches.is_empty() { if self.matches.is_empty() {
let settings = self.settings.borrow(); let settings = self.settings.borrow();
@ -172,7 +193,7 @@ impl OutlineView {
.named("matches") .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. // TODO: maintain selected index.
let selected_index = 0; let selected_index = 0;
let settings = self.settings.borrow(); let settings = self.settings.borrow();
@ -181,8 +202,10 @@ impl OutlineView {
} else { } else {
&settings.theme.selector.item &settings.theme.selector.item
}; };
let outline_match = &self.outline.items[string_match.candidate_index];
Label::new(outline_match.text.clone(), style.label.clone()) Label::new(outline_match.text.clone(), style.label.clone())
.with_highlights(string_match.positions.clone())
.contained() .contained()
.with_padding_left(20. * outline_match.depth as f32) .with_padding_left(20. * outline_match.depth as f32)
.contained() .contained()