From 3fe61971b57e6a4fcfe59975fbfeb62a064a7082 Mon Sep 17 00:00:00 2001 From: Myriad-Dreamin <35292584+Myriad-Dreamin@users.noreply.github.com> Date: Mon, 11 Mar 2024 23:47:13 +0800 Subject: [PATCH] feat: support more ast nodes to folding (#11) --- .../src/analysis/lexical_hierarchy.rs | 48 ++++++++++++++----- .../fixtures/folding_range/array_folding.typ | 5 ++ .../fixtures/folding_range/paren_folding.typ | 3 ++ .../folding_range/test@array_folding.typ.snap | 14 ++++++ .../test@headings-in-blocks.typ.snap | 14 ++++++ .../folding_range/test@paren_folding.typ.snap | 6 +++ crates/tinymist-query/src/folding_range.rs | 2 +- 7 files changed, 78 insertions(+), 14 deletions(-) create mode 100644 crates/tinymist-query/src/fixtures/folding_range/array_folding.typ create mode 100644 crates/tinymist-query/src/fixtures/folding_range/paren_folding.typ create mode 100644 crates/tinymist-query/src/fixtures/folding_range/test@array_folding.typ.snap create mode 100644 crates/tinymist-query/src/fixtures/folding_range/test@paren_folding.typ.snap diff --git a/crates/tinymist-query/src/analysis/lexical_hierarchy.rs b/crates/tinymist-query/src/analysis/lexical_hierarchy.rs index f516aeefb..42b66af05 100644 --- a/crates/tinymist-query/src/analysis/lexical_hierarchy.rs +++ b/crates/tinymist-query/src/analysis/lexical_hierarchy.rs @@ -33,7 +33,21 @@ impl TryFrom for SymbolKind { pub(crate) enum LexicalScopeKind { #[default] Symbol, - Block, + Braced, +} + +impl LexicalScopeKind { + fn affect_symbol(&self) -> bool { + matches!(self, LexicalScopeKind::Symbol) + } + + fn affect_block(&self) -> bool { + matches!(self, LexicalScopeKind::Braced) + } + + fn affect_expr(&self) -> bool { + matches!(self, LexicalScopeKind::Braced) + } } #[derive(Debug, Clone, Hash)] @@ -75,13 +89,6 @@ pub(crate) fn get_lexical_hierarchy( let (symbol, children) = self.stack.pop().unwrap(); let current = &mut self.stack.last_mut().unwrap().1; - // symbol.wide_range = children - // .iter() - // .map(|c| c.info.wide_range.clone()) - // .fold(symbol.range.clone(), |acc, r| { - // acc.start.min(r.start)..acc.end.max(r.end) - // }); - current.push(symbreak(symbol, children)); } @@ -135,7 +142,7 @@ pub(crate) fn get_lexical_hierarchy( #[allow(deprecated)] fn get_ident(node: &LinkedNode, g: LexicalScopeKind) -> anyhow::Result> { let (name, kind) = match node.kind() { - SyntaxKind::Label if LexicalScopeKind::Block != g => { + SyntaxKind::Label if g.affect_symbol() => { let ast_node = node .cast::() .ok_or_else(|| anyhow!("cast to ast node failed: {:?}", node))?; @@ -143,10 +150,7 @@ pub(crate) fn get_lexical_hierarchy( (name, LexicalKind::Constant) } - SyntaxKind::CodeBlock | SyntaxKind::ContentBlock if LexicalScopeKind::Symbol != g => { - (String::new(), LexicalKind::Block) - } - SyntaxKind::Ident if LexicalScopeKind::Block != g => { + SyntaxKind::Ident if g.affect_symbol() => { let ast_node = node .cast::() .ok_or_else(|| anyhow!("cast to ast node failed: {:?}", node))?; @@ -173,6 +177,24 @@ pub(crate) fn get_lexical_hierarchy( (name, kind) } + SyntaxKind::Equation + | SyntaxKind::Raw + | SyntaxKind::CodeBlock + | SyntaxKind::ContentBlock + | SyntaxKind::BlockComment + if g.affect_block() => + { + (String::new(), LexicalKind::Block) + } + SyntaxKind::Parenthesized + | SyntaxKind::Destructuring + | SyntaxKind::Args + | SyntaxKind::Array + | SyntaxKind::Dict + if g.affect_expr() => + { + (String::new(), LexicalKind::Block) + } SyntaxKind::Markup => { let name = node.get().to_owned().into_text().to_string(); if name.is_empty() { diff --git a/crates/tinymist-query/src/fixtures/folding_range/array_folding.typ b/crates/tinymist-query/src/fixtures/folding_range/array_folding.typ new file mode 100644 index 000000000..668bd2de7 --- /dev/null +++ b/crates/tinymist-query/src/fixtures/folding_range/array_folding.typ @@ -0,0 +1,5 @@ +#( + 1, + 2, + 3, +) \ No newline at end of file diff --git a/crates/tinymist-query/src/fixtures/folding_range/paren_folding.typ b/crates/tinymist-query/src/fixtures/folding_range/paren_folding.typ new file mode 100644 index 000000000..84e3057bc --- /dev/null +++ b/crates/tinymist-query/src/fixtures/folding_range/paren_folding.typ @@ -0,0 +1,3 @@ +#( +1 +) \ No newline at end of file diff --git a/crates/tinymist-query/src/fixtures/folding_range/test@array_folding.typ.snap b/crates/tinymist-query/src/fixtures/folding_range/test@array_folding.typ.snap new file mode 100644 index 000000000..fc89e5a41 --- /dev/null +++ b/crates/tinymist-query/src/fixtures/folding_range/test@array_folding.typ.snap @@ -0,0 +1,14 @@ +--- +source: crates/tinymist-query/src/folding_range.rs +expression: "JsonRepr::new_pure(result.unwrap())" +input_file: crates/tinymist-query/src/fixtures/folding_range/array_folding.typ +--- +[ + { + "collapsedText": "", + "endCharacter": 1, + "endLine": 4, + "startCharacter": 1, + "startLine": 0 + } +] diff --git a/crates/tinymist-query/src/fixtures/folding_range/test@headings-in-blocks.typ.snap b/crates/tinymist-query/src/fixtures/folding_range/test@headings-in-blocks.typ.snap index f799d8e07..e0aa111cb 100644 --- a/crates/tinymist-query/src/fixtures/folding_range/test@headings-in-blocks.typ.snap +++ b/crates/tinymist-query/src/fixtures/folding_range/test@headings-in-blocks.typ.snap @@ -4,6 +4,20 @@ expression: "JsonRepr::new_pure(result.unwrap())" input_file: crates/tinymist-query/src/fixtures/folding_range/headings-in-blocks.typ --- [ + { + "collapsedText": "", + "endCharacter": 11, + "endLine": 2, + "startCharacter": 8, + "startLine": 2 + }, + { + "collapsedText": "", + "endCharacter": 13, + "endLine": 6, + "startCharacter": 10, + "startLine": 6 + }, { "collapsedText": "Heading 2", "endCharacter": 16, diff --git a/crates/tinymist-query/src/fixtures/folding_range/test@paren_folding.typ.snap b/crates/tinymist-query/src/fixtures/folding_range/test@paren_folding.typ.snap new file mode 100644 index 000000000..df324b33a --- /dev/null +++ b/crates/tinymist-query/src/fixtures/folding_range/test@paren_folding.typ.snap @@ -0,0 +1,6 @@ +--- +source: crates/tinymist-query/src/folding_range.rs +expression: "JsonRepr::new_pure(result.unwrap())" +input_file: crates/tinymist-query/src/fixtures/folding_range/paren_folding.typ +--- +[] diff --git a/crates/tinymist-query/src/folding_range.rs b/crates/tinymist-query/src/folding_range.rs index 8697504ea..7d07e5b27 100644 --- a/crates/tinymist-query/src/folding_range.rs +++ b/crates/tinymist-query/src/folding_range.rs @@ -17,7 +17,7 @@ impl FoldingRangeRequest { ) -> Option> { let line_folding_only = self.line_folding_only; - let symbols = get_lexical_hierarchy(source.clone(), LexicalScopeKind::Block)?; + let symbols = get_lexical_hierarchy(source.clone(), LexicalScopeKind::Braced)?; let mut results = vec![]; let LspPosition { line, character } =