Allow matching of context items in outline view
This commit is contained in:
parent
e7f1398f3a
commit
a64ba8b687
4 changed files with 44 additions and 64 deletions
|
@ -1712,7 +1712,6 @@ impl MultiBufferSnapshot {
|
||||||
..self.anchor_in_excerpt(excerpt_id.clone(), item.range.end),
|
..self.anchor_in_excerpt(excerpt_id.clone(), item.range.end),
|
||||||
text: item.text,
|
text: item.text,
|
||||||
highlight_ranges: item.highlight_ranges,
|
highlight_ranges: item.highlight_ranges,
|
||||||
name_ranges: item.name_ranges,
|
|
||||||
})
|
})
|
||||||
.collect(),
|
.collect(),
|
||||||
))
|
))
|
||||||
|
|
|
@ -1864,15 +1864,11 @@ impl BufferSnapshot {
|
||||||
let item_node = mat.nodes_for_capture_index(item_capture_ix).next()?;
|
let item_node = mat.nodes_for_capture_index(item_capture_ix).next()?;
|
||||||
let range = item_node.start_byte()..item_node.end_byte();
|
let range = item_node.start_byte()..item_node.end_byte();
|
||||||
let mut text = String::new();
|
let mut text = String::new();
|
||||||
let mut name_ranges = Vec::new();
|
|
||||||
let mut highlight_ranges = Vec::new();
|
let mut highlight_ranges = Vec::new();
|
||||||
|
|
||||||
for capture in mat.captures {
|
for capture in mat.captures {
|
||||||
let node_is_name;
|
|
||||||
if capture.index == name_capture_ix {
|
if capture.index == name_capture_ix {
|
||||||
node_is_name = true;
|
|
||||||
} else if capture.index == context_capture_ix {
|
} else if capture.index == context_capture_ix {
|
||||||
node_is_name = false;
|
|
||||||
} else {
|
} else {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
@ -1881,18 +1877,6 @@ impl BufferSnapshot {
|
||||||
if !text.is_empty() {
|
if !text.is_empty() {
|
||||||
text.push(' ');
|
text.push(' ');
|
||||||
}
|
}
|
||||||
if node_is_name {
|
|
||||||
let mut start = text.len() as u32;
|
|
||||||
let end = start + range.len() as u32;
|
|
||||||
|
|
||||||
// When multiple names are captured, then the matcheable text
|
|
||||||
// includes the whitespace in between the names.
|
|
||||||
if !name_ranges.is_empty() {
|
|
||||||
start -= 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
name_ranges.push(start..end);
|
|
||||||
}
|
|
||||||
|
|
||||||
let mut offset = range.start;
|
let mut offset = range.start;
|
||||||
chunks.seek(offset);
|
chunks.seek(offset);
|
||||||
|
@ -1926,7 +1910,6 @@ impl BufferSnapshot {
|
||||||
depth: stack.len() - 1,
|
depth: stack.len() - 1,
|
||||||
range: self.anchor_after(range.start)..self.anchor_before(range.end),
|
range: self.anchor_after(range.start)..self.anchor_before(range.end),
|
||||||
text,
|
text,
|
||||||
name_ranges,
|
|
||||||
highlight_ranges,
|
highlight_ranges,
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
|
@ -13,7 +13,6 @@ pub struct OutlineItem<T> {
|
||||||
pub depth: usize,
|
pub depth: usize,
|
||||||
pub range: Range<T>,
|
pub range: Range<T>,
|
||||||
pub text: String,
|
pub text: String,
|
||||||
pub name_ranges: Vec<Range<u32>>,
|
|
||||||
pub highlight_ranges: Vec<(Range<usize>, HighlightStyle)>,
|
pub highlight_ranges: Vec<(Range<usize>, HighlightStyle)>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -22,16 +21,9 @@ impl<T> Outline<T> {
|
||||||
Self {
|
Self {
|
||||||
candidates: items
|
candidates: items
|
||||||
.iter()
|
.iter()
|
||||||
.map(|item| {
|
.map(|item| StringMatchCandidate {
|
||||||
let text = item
|
char_bag: item.text.as_str().into(),
|
||||||
.name_ranges
|
string: item.text.clone(),
|
||||||
.iter()
|
|
||||||
.map(|range| &item.text[range.start as usize..range.end as usize])
|
|
||||||
.collect::<String>();
|
|
||||||
StringMatchCandidate {
|
|
||||||
char_bag: text.as_str().into(),
|
|
||||||
string: text,
|
|
||||||
}
|
|
||||||
})
|
})
|
||||||
.collect(),
|
.collect(),
|
||||||
items,
|
items,
|
||||||
|
@ -53,20 +45,8 @@ impl<T> Outline<T> {
|
||||||
let mut tree_matches = Vec::new();
|
let mut tree_matches = Vec::new();
|
||||||
|
|
||||||
let mut prev_item_ix = 0;
|
let mut prev_item_ix = 0;
|
||||||
for mut string_match in matches {
|
for string_match in matches {
|
||||||
let outline_match = &self.items[string_match.candidate_index];
|
let outline_match = &self.items[string_match.candidate_index];
|
||||||
|
|
||||||
let mut name_ranges = outline_match.name_ranges.iter();
|
|
||||||
let mut name_range = name_ranges.next().unwrap();
|
|
||||||
let mut preceding_ranges_len = 0;
|
|
||||||
for position in &mut string_match.positions {
|
|
||||||
while *position >= preceding_ranges_len + name_range.len() as usize {
|
|
||||||
preceding_ranges_len += name_range.len();
|
|
||||||
name_range = name_ranges.next().unwrap();
|
|
||||||
}
|
|
||||||
*position = name_range.start as usize + (*position - preceding_ranges_len);
|
|
||||||
}
|
|
||||||
|
|
||||||
let insertion_ix = tree_matches.len();
|
let insertion_ix = tree_matches.len();
|
||||||
let mut cur_depth = outline_match.depth;
|
let mut cur_depth = outline_match.depth;
|
||||||
for (ix, item) in self.items[prev_item_ix..string_match.candidate_index]
|
for (ix, item) in self.items[prev_item_ix..string_match.candidate_index]
|
||||||
|
|
|
@ -302,6 +302,9 @@ async fn test_outline(mut cx: gpui::TestAppContext) {
|
||||||
(function_item
|
(function_item
|
||||||
"fn" @context
|
"fn" @context
|
||||||
name: (_) @name) @item
|
name: (_) @name) @item
|
||||||
|
(mod_item
|
||||||
|
"mod" @context
|
||||||
|
name: (_) @name) @item
|
||||||
"#,
|
"#,
|
||||||
)
|
)
|
||||||
.unwrap(),
|
.unwrap(),
|
||||||
|
@ -313,15 +316,19 @@ async fn test_outline(mut cx: gpui::TestAppContext) {
|
||||||
age: usize,
|
age: usize,
|
||||||
}
|
}
|
||||||
|
|
||||||
enum LoginState {
|
mod module {
|
||||||
LoggedOut,
|
enum LoginState {
|
||||||
LoggingOn,
|
LoggedOut,
|
||||||
LoggedIn {
|
LoggingOn,
|
||||||
person: Person,
|
LoggedIn {
|
||||||
time: Instant,
|
person: Person,
|
||||||
|
time: Instant,
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl Eq for Person {}
|
||||||
|
|
||||||
impl Drop for Person {
|
impl Drop for Person {
|
||||||
fn drop(&mut self) {
|
fn drop(&mut self) {
|
||||||
println!("bye");
|
println!("bye");
|
||||||
|
@ -339,39 +346,50 @@ async fn test_outline(mut cx: gpui::TestAppContext) {
|
||||||
outline
|
outline
|
||||||
.items
|
.items
|
||||||
.iter()
|
.iter()
|
||||||
.map(|item| (item.text.as_str(), item.name_ranges.as_ref(), item.depth))
|
.map(|item| (item.text.as_str(), item.depth))
|
||||||
.collect::<Vec<_>>(),
|
.collect::<Vec<_>>(),
|
||||||
&[
|
&[
|
||||||
("struct Person", [7..13].as_slice(), 0),
|
("struct Person", 0),
|
||||||
("name", &[0..4], 1),
|
("name", 1),
|
||||||
("age", &[0..3], 1),
|
("age", 1),
|
||||||
("enum LoginState", &[5..15], 0),
|
("mod module", 0),
|
||||||
("LoggedOut", &[0..9], 1),
|
("enum LoginState", 1),
|
||||||
("LoggingOn", &[0..9], 1),
|
("LoggedOut", 2),
|
||||||
("LoggedIn", &[0..8], 1),
|
("LoggingOn", 2),
|
||||||
("person", &[0..6], 2),
|
("LoggedIn", 2),
|
||||||
("time", &[0..4], 2),
|
("person", 3),
|
||||||
("impl Drop for Person", &[5..9, 13..20], 0),
|
("time", 3),
|
||||||
("fn drop", &[3..7], 1),
|
("impl Eq for Person", 0),
|
||||||
|
("impl Drop for Person", 0),
|
||||||
|
("fn drop", 1),
|
||||||
]
|
]
|
||||||
);
|
);
|
||||||
|
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
search(&outline, "oon", &cx).await,
|
search(&outline, "oon", &cx).await,
|
||||||
&[
|
&[
|
||||||
("enum LoginState", vec![]), // included as the parent of a match
|
("mod module", vec![]), // included as the parent of a match
|
||||||
("LoggingOn", vec![1, 7, 8]), // matches
|
("enum LoginState", vec![]), // included as the parent of a match
|
||||||
("impl Drop for Person", vec![7, 18, 19]), // matches in two disjoint names
|
("LoggingOn", vec![1, 7, 8]), // matches
|
||||||
|
("impl Eq for Person", vec![9, 16, 17]), // matches part of the context
|
||||||
|
("impl Drop for Person", vec![11, 18, 19]), // matches in two disjoint names
|
||||||
]
|
]
|
||||||
);
|
);
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
search(&outline, "dp p", &cx).await,
|
search(&outline, "dp p", &cx).await,
|
||||||
&[("impl Drop for Person", vec![5, 8, 13, 14])]
|
&[("impl Drop for Person", vec![5, 8, 9, 14])]
|
||||||
);
|
);
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
search(&outline, "dpn", &cx).await,
|
search(&outline, "dpn", &cx).await,
|
||||||
&[("impl Drop for Person", vec![5, 8, 19])]
|
&[("impl Drop for Person", vec![5, 8, 19])]
|
||||||
);
|
);
|
||||||
|
assert_eq!(
|
||||||
|
search(&outline, "impl", &cx).await,
|
||||||
|
&[
|
||||||
|
("impl Eq for Person", vec![0, 1, 2, 3]),
|
||||||
|
("impl Drop for Person", vec![0, 1, 2, 3])
|
||||||
|
]
|
||||||
|
);
|
||||||
|
|
||||||
async fn search<'a>(
|
async fn search<'a>(
|
||||||
outline: &'a Outline<Anchor>,
|
outline: &'a Outline<Anchor>,
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue