Fix missing TypeScript outline entries and breadcrumbs
This commit is contained in:
parent
ddc45eb24e
commit
bfec9e1ec2
5 changed files with 72 additions and 8 deletions
|
@ -57,6 +57,6 @@ util = { path = "../util", features = ["test-support"] }
|
||||||
ctor = "0.1"
|
ctor = "0.1"
|
||||||
env_logger = "0.8"
|
env_logger = "0.8"
|
||||||
rand = "0.8.3"
|
rand = "0.8.3"
|
||||||
tree-sitter-json = "0.19.0"
|
tree-sitter-json = "*"
|
||||||
tree-sitter-rust = "0.20.0"
|
tree-sitter-rust = "*"
|
||||||
unindent = "0.1.7"
|
unindent = "0.1.7"
|
||||||
|
|
|
@ -1730,7 +1730,7 @@ impl BufferSnapshot {
|
||||||
.and_then(|language| language.grammar.as_ref())?;
|
.and_then(|language| language.grammar.as_ref())?;
|
||||||
|
|
||||||
let mut cursor = QueryCursorHandle::new();
|
let mut cursor = QueryCursorHandle::new();
|
||||||
cursor.set_byte_range(range);
|
cursor.set_byte_range(range.clone());
|
||||||
let matches = cursor.matches(
|
let matches = cursor.matches(
|
||||||
&grammar.outline_query,
|
&grammar.outline_query,
|
||||||
tree.root_node(),
|
tree.root_node(),
|
||||||
|
@ -1750,7 +1750,10 @@ impl BufferSnapshot {
|
||||||
let items = matches
|
let items = matches
|
||||||
.filter_map(|mat| {
|
.filter_map(|mat| {
|
||||||
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 item_range = item_node.start_byte()..item_node.end_byte();
|
||||||
|
if item_range.end < range.start || item_range.start > range.end {
|
||||||
|
return None;
|
||||||
|
}
|
||||||
let mut text = String::new();
|
let mut text = String::new();
|
||||||
let mut name_ranges = Vec::new();
|
let mut name_ranges = Vec::new();
|
||||||
let mut highlight_ranges = Vec::new();
|
let mut highlight_ranges = Vec::new();
|
||||||
|
@ -1808,15 +1811,15 @@ impl BufferSnapshot {
|
||||||
}
|
}
|
||||||
|
|
||||||
while stack.last().map_or(false, |prev_range| {
|
while stack.last().map_or(false, |prev_range| {
|
||||||
!prev_range.contains(&range.start) || !prev_range.contains(&range.end)
|
!prev_range.contains(&item_range.start) || !prev_range.contains(&item_range.end)
|
||||||
}) {
|
}) {
|
||||||
stack.pop();
|
stack.pop();
|
||||||
}
|
}
|
||||||
stack.push(range.clone());
|
stack.push(item_range.clone());
|
||||||
|
|
||||||
Some(OutlineItem {
|
Some(OutlineItem {
|
||||||
depth: stack.len() - 1,
|
depth: stack.len() - 1,
|
||||||
range: self.anchor_after(range.start)..self.anchor_before(range.end),
|
range: self.anchor_after(item_range.start)..self.anchor_before(item_range.end),
|
||||||
text,
|
text,
|
||||||
highlight_ranges,
|
highlight_ranges,
|
||||||
name_ranges,
|
name_ranges,
|
||||||
|
|
|
@ -63,7 +63,7 @@ pub fn build_language_registry(login_shell_env_loaded: Task<()>) -> LanguageRegi
|
||||||
languages
|
languages
|
||||||
}
|
}
|
||||||
|
|
||||||
fn language(
|
pub(crate) fn language(
|
||||||
name: &str,
|
name: &str,
|
||||||
grammar: tree_sitter::Language,
|
grammar: tree_sitter::Language,
|
||||||
lsp_adapter: Option<Arc<dyn LspAdapter>>,
|
lsp_adapter: Option<Arc<dyn LspAdapter>>,
|
||||||
|
|
|
@ -144,3 +144,54 @@ impl LspAdapter for TypeScriptLspAdapter {
|
||||||
}))
|
}))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[cfg(test)]
|
||||||
|
mod tests {
|
||||||
|
use std::sync::Arc;
|
||||||
|
|
||||||
|
use gpui::MutableAppContext;
|
||||||
|
use unindent::Unindent;
|
||||||
|
|
||||||
|
#[gpui::test]
|
||||||
|
fn test_outline(cx: &mut MutableAppContext) {
|
||||||
|
let language = crate::languages::language(
|
||||||
|
"typescript",
|
||||||
|
tree_sitter_typescript::language_typescript(),
|
||||||
|
None,
|
||||||
|
);
|
||||||
|
|
||||||
|
let text = r#"
|
||||||
|
function a() {
|
||||||
|
// local variables are omitted
|
||||||
|
let a1 = 1;
|
||||||
|
// all functions are included
|
||||||
|
async function a2() {}
|
||||||
|
}
|
||||||
|
// top-level variables are included
|
||||||
|
let b: C
|
||||||
|
function getB() {}
|
||||||
|
// exported variables are included
|
||||||
|
export const d = e;
|
||||||
|
"#
|
||||||
|
.unindent();
|
||||||
|
|
||||||
|
let buffer = cx.add_model(|cx| {
|
||||||
|
language::Buffer::new(0, text, cx).with_language(Arc::new(language), cx)
|
||||||
|
});
|
||||||
|
let outline = buffer.read(cx).snapshot().outline(None).unwrap();
|
||||||
|
assert_eq!(
|
||||||
|
outline
|
||||||
|
.items
|
||||||
|
.iter()
|
||||||
|
.map(|item| (item.text.as_str(), item.depth))
|
||||||
|
.collect::<Vec<_>>(),
|
||||||
|
&[
|
||||||
|
("function a ( )", 0),
|
||||||
|
("async function a2 ( )", 1),
|
||||||
|
("let b", 0),
|
||||||
|
("function getB ( )", 0),
|
||||||
|
("const d", 0),
|
||||||
|
]
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -6,6 +6,10 @@
|
||||||
"enum" @context
|
"enum" @context
|
||||||
name: (_) @name) @item
|
name: (_) @name) @item
|
||||||
|
|
||||||
|
(type_alias_declaration
|
||||||
|
"type" @context
|
||||||
|
name: (_) @name) @item
|
||||||
|
|
||||||
(function_declaration
|
(function_declaration
|
||||||
"async"? @context
|
"async"? @context
|
||||||
"function" @context
|
"function" @context
|
||||||
|
@ -18,6 +22,12 @@
|
||||||
"interface" @context
|
"interface" @context
|
||||||
name: (_) @name) @item
|
name: (_) @name) @item
|
||||||
|
|
||||||
|
(export_statement
|
||||||
|
(lexical_declaration
|
||||||
|
["let" "const"] @context
|
||||||
|
(variable_declarator
|
||||||
|
name: (_) @name) @item))
|
||||||
|
|
||||||
(program
|
(program
|
||||||
(lexical_declaration
|
(lexical_declaration
|
||||||
["let" "const"] @context
|
["let" "const"] @context
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue