dev: process overlapping cases in line folding only mode

This commit is contained in:
Myriad-Dreamin 2024-09-06 23:34:55 +08:00
parent a92d477d88
commit 3ab4fa625f
15 changed files with 476 additions and 177 deletions

View file

@ -58,7 +58,7 @@ insta.workspace = true
serde.workspace = true serde.workspace = true
serde_json.workspace = true serde_json.workspace = true
typst-assets = { workspace = true, features = ["fonts"] } typst-assets = { workspace = true, features = ["fonts"] }
reflexo-typst.workspace = true reflexo-typst = { workspace = true, features = ["no-content-hint"] }
sha2 = { version = "0.10" } sha2 = { version = "0.10" }
hex = { version = "0.4" } hex = { version = "0.4" }

View file

@ -0,0 +1,6 @@
#let slides(..args) = args
#slides()[
= Heading
][
]

View file

@ -0,0 +1,6 @@
#let slides(..args) = args
#slides[
][
]

View file

@ -0,0 +1,6 @@
#let slides(..args) = args
#slides()[
][
]

View file

@ -1,9 +1,10 @@
--- ---
source: crates/tinymist-query/src/folding_range.rs source: crates/tinymist-query/src/folding_range.rs
expression: "JsonRepr::new_pure(result.unwrap())" expression: "JsonRepr::new_pure(json!({ \"false\": result_false, \"true\": result_true, }))"
input_file: crates/tinymist-query/src/fixtures/folding_range/array_folding.typ input_file: crates/tinymist-query/src/fixtures/folding_range/array_folding.typ
--- ---
[ {
"false": [
{ {
"collapsedText": "", "collapsedText": "",
"endCharacter": 1, "endCharacter": 1,
@ -11,4 +12,12 @@ input_file: crates/tinymist-query/src/fixtures/folding_range/array_folding.typ
"startCharacter": 1, "startCharacter": 1,
"startLine": 0 "startLine": 0
} }
] ],
"true": [
{
"collapsedText": "",
"endLine": 4,
"startLine": 0
}
]
}

View file

@ -1,9 +1,10 @@
--- ---
source: crates/tinymist-query/src/folding_range.rs source: crates/tinymist-query/src/folding_range.rs
expression: "JsonRepr::new_pure(result.unwrap())" expression: "JsonRepr::new_pure(json!({ \"false\": result_false, \"true\": result_true, }))"
input_file: crates/tinymist-query/src/fixtures/folding_range/base.typ input_file: crates/tinymist-query/src/fixtures/folding_range/base.typ
--- ---
[ {
"false": [
{ {
"collapsedText": "Heading 2", "collapsedText": "Heading 2",
"endCharacter": 12, "endCharacter": 12,
@ -32,4 +33,22 @@ input_file: crates/tinymist-query/src/fixtures/folding_range/base.typ
"startCharacter": 2, "startCharacter": 2,
"startLine": 4 "startLine": 4
} }
] ],
"true": [
{
"collapsedText": "Heading 1",
"endLine": 3,
"startLine": 0
},
{
"collapsedText": "",
"endLine": 9,
"startLine": 6
},
{
"collapsedText": "Heading 3",
"endLine": 9,
"startLine": 4
}
]
}

View file

@ -0,0 +1,49 @@
---
source: crates/tinymist-query/src/folding_range.rs
expression: "JsonRepr::new_pure(json!({ \"false\": result_false, \"true\": result_true, }))"
input_file: crates/tinymist-query/src/fixtures/folding_range/heading-in-multiple-content.typ
---
{
"false": [
{
"collapsedText": "Heading",
"endCharacter": 11,
"endLine": 3,
"startCharacter": 4,
"startLine": 2
},
{
"collapsedText": "",
"endCharacter": 1,
"endLine": 3,
"startCharacter": 9,
"startLine": 1
},
{
"collapsedText": "",
"endCharacter": 1,
"endLine": 5,
"startCharacter": 1,
"startLine": 3
},
{
"collapsedText": "",
"endCharacter": 1,
"endLine": 5,
"startCharacter": 7,
"startLine": 1
}
],
"true": [
{
"collapsedText": "",
"endLine": 5,
"startLine": 3
},
{
"collapsedText": "",
"endLine": 5,
"startLine": 1
}
]
}

View file

@ -1,9 +1,10 @@
--- ---
source: crates/tinymist-query/src/folding_range.rs source: crates/tinymist-query/src/folding_range.rs
expression: "JsonRepr::new_pure(result.unwrap())" expression: "JsonRepr::new_pure(json!({ \"false\": result_false, \"true\": result_true, }))"
input_file: crates/tinymist-query/src/fixtures/folding_range/headings-in-blocks.typ input_file: crates/tinymist-query/src/fixtures/folding_range/headings-in-blocks.typ
--- ---
[ {
"false": [
{ {
"collapsedText": "", "collapsedText": "",
"endCharacter": 11, "endCharacter": 11,
@ -46,4 +47,27 @@ input_file: crates/tinymist-query/src/fixtures/folding_range/headings-in-blocks.
"startCharacter": 9, "startCharacter": 9,
"startLine": 0 "startLine": 0
} }
] ],
"true": [
{
"collapsedText": "Heading 2",
"endLine": 8,
"startLine": 5
},
{
"collapsedText": "",
"endLine": 7,
"startLine": 3
},
{
"collapsedText": "Heading 1",
"endLine": 8,
"startLine": 1
},
{
"collapsedText": "",
"endLine": 8,
"startLine": 0
}
]
}

View file

@ -0,0 +1,42 @@
---
source: crates/tinymist-query/src/folding_range.rs
expression: "JsonRepr::new_pure(json!({ \"false\": result_false, \"true\": result_true, }))"
input_file: crates/tinymist-query/src/fixtures/folding_range/multiple-content-2.typ
---
{
"false": [
{
"collapsedText": "",
"endCharacter": 1,
"endLine": 3,
"startCharacter": 7,
"startLine": 1
},
{
"collapsedText": "",
"endCharacter": 1,
"endLine": 5,
"startCharacter": 1,
"startLine": 3
},
{
"collapsedText": "",
"endCharacter": 1,
"endLine": 5,
"startCharacter": 7,
"startLine": 1
}
],
"true": [
{
"collapsedText": "",
"endLine": 5,
"startLine": 3
},
{
"collapsedText": "",
"endLine": 5,
"startLine": 1
}
]
}

View file

@ -0,0 +1,42 @@
---
source: crates/tinymist-query/src/folding_range.rs
expression: "JsonRepr::new_pure(json!({ \"false\": result_false, \"true\": result_true, }))"
input_file: crates/tinymist-query/src/fixtures/folding_range/multiple-content.typ
---
{
"false": [
{
"collapsedText": "",
"endCharacter": 1,
"endLine": 3,
"startCharacter": 9,
"startLine": 1
},
{
"collapsedText": "",
"endCharacter": 1,
"endLine": 5,
"startCharacter": 1,
"startLine": 3
},
{
"collapsedText": "",
"endCharacter": 1,
"endLine": 5,
"startCharacter": 7,
"startLine": 1
}
],
"true": [
{
"collapsedText": "",
"endLine": 5,
"startLine": 3
},
{
"collapsedText": "",
"endLine": 5,
"startLine": 1
}
]
}

View file

@ -1,9 +1,10 @@
--- ---
source: crates/tinymist-query/src/folding_range.rs source: crates/tinymist-query/src/folding_range.rs
expression: "JsonRepr::new_pure(result.unwrap())" expression: "JsonRepr::new_pure(json!({ \"false\": result_false, \"true\": result_true, }))"
input_file: crates/tinymist-query/src/fixtures/folding_range/nested-blocks.typ input_file: crates/tinymist-query/src/fixtures/folding_range/nested-blocks.typ
--- ---
[ {
"false": [
{ {
"collapsedText": "", "collapsedText": "",
"endCharacter": 5, "endCharacter": 5,
@ -67,4 +68,47 @@ input_file: crates/tinymist-query/src/fixtures/folding_range/nested-blocks.typ
"startCharacter": 9, "startCharacter": 9,
"startLine": 0 "startLine": 0
} }
] ],
"true": [
{
"collapsedText": "",
"endLine": 4,
"startLine": 2
},
{
"collapsedText": "",
"endLine": 5,
"startLine": 1
},
{
"collapsedText": "",
"endLine": 8,
"startLine": 6
},
{
"collapsedText": "",
"endLine": 11,
"startLine": 10
},
{
"collapsedText": "",
"endLine": 14,
"startLine": 12
},
{
"collapsedText": "",
"endLine": 15,
"startLine": 9
},
{
"collapsedText": "",
"endLine": 17,
"startLine": 16
},
{
"collapsedText": "",
"endLine": 18,
"startLine": 0
}
]
}

View file

@ -1,9 +1,10 @@
--- ---
source: crates/tinymist-query/src/folding_range.rs source: crates/tinymist-query/src/folding_range.rs
expression: "JsonRepr::new_pure(result.unwrap())" expression: "JsonRepr::new_pure(json!({ \"false\": result_false, \"true\": result_true, }))"
input_file: crates/tinymist-query/src/fixtures/folding_range/paren_folding.typ input_file: crates/tinymist-query/src/fixtures/folding_range/paren_folding.typ
--- ---
[ {
"false": [
{ {
"collapsedText": "", "collapsedText": "",
"endCharacter": 1, "endCharacter": 1,
@ -11,4 +12,12 @@ input_file: crates/tinymist-query/src/fixtures/folding_range/paren_folding.typ
"startCharacter": 1, "startCharacter": 1,
"startLine": 0 "startLine": 0
} }
] ],
"true": [
{
"collapsedText": "",
"endLine": 2,
"startLine": 0
}
]
}

View file

@ -1,3 +1,5 @@
use hashbrown::HashSet;
use crate::{ use crate::{
prelude::*, prelude::*,
syntax::{get_lexical_hierarchy, LexicalHierarchy, LexicalKind, LexicalScopeKind}, syntax::{get_lexical_hierarchy, LexicalHierarchy, LexicalKind, LexicalScopeKind},
@ -42,12 +44,45 @@ impl SyntaxRequest for FoldingRangeRequest {
&symbols, &symbols,
source, source,
position_encoding, position_encoding,
line_folding_only,
loc, loc,
loc, loc,
true, true,
&mut results, &mut results,
); );
// Generally process of folding ranges with line_folding_only
if line_folding_only {
let mut max_line = 0;
for r in &mut results {
r.start_character = None;
r.end_character = None;
max_line = max_line.max(r.end_line);
}
let mut line_coverage = vec![false; max_line as usize + 1];
let mut pair_coverage = HashSet::new();
results.reverse();
results.retain_mut(|r| {
if pair_coverage.contains(&(r.start_line, r.end_line)) {
return false;
}
if line_coverage[r.start_line as usize] {
r.start_line += 1;
}
if line_coverage[r.end_line as usize] {
r.end_line = r.end_line.saturating_sub(1);
}
if r.start_line >= r.end_line {
return false;
}
line_coverage[r.start_line as usize] = true;
pair_coverage.insert((r.start_line, r.end_line));
true
});
results.reverse();
}
if false { if false {
trace!("FoldingRangeRequest(line_folding_only={line_folding_only}) symbols: {symbols:#?} results: {results:#?}"); trace!("FoldingRangeRequest(line_folding_only={line_folding_only}) symbols: {symbols:#?} results: {results:#?}");
} }
@ -58,13 +93,10 @@ impl SyntaxRequest for FoldingRangeRequest {
type LoC = (u32, Option<u32>); type LoC = (u32, Option<u32>);
#[allow(clippy::too_many_arguments)]
#[allow(deprecated)]
fn calc_folding_range( fn calc_folding_range(
symbols: &[LexicalHierarchy], symbols: &[LexicalHierarchy],
source: &Source, source: &Source,
position_encoding: PositionEncoding, position_encoding: PositionEncoding,
line_folding_only: bool,
parent_last_loc: LoC, parent_last_loc: LoC,
last_loc: LoC, last_loc: LoC,
is_last_range: bool, is_last_range: bool,
@ -79,7 +111,7 @@ fn calc_folding_range(
start_line: rng.start.line, start_line: rng.start.line,
start_character: Some(rng.start.character), start_character: Some(rng.start.character),
end_line: rng.end.line, end_line: rng.end.line,
end_character: line_folding_only.then_some(rng.end.character), end_character: Some(rng.end.character),
kind: None, kind: None,
collapsed_text: Some(e.info.name.clone()), collapsed_text: Some(e.info.name.clone()),
}; };
@ -113,7 +145,6 @@ fn calc_folding_range(
ch, ch,
source, source,
position_encoding, position_encoding,
line_folding_only,
parent_last_loc, parent_last_loc,
last_loc, last_loc,
!is_not_final_last_range, !is_not_final_last_range,
@ -133,15 +164,23 @@ mod tests {
#[test] #[test]
fn test() { fn test() {
snapshot_testing("folding_range", &|world, path| { snapshot_testing("folding_range", &|world, path| {
let mut r = |line_folding_only| {
let request = FoldingRangeRequest { let request = FoldingRangeRequest {
path: path.clone(), path: path.clone(),
line_folding_only: true, line_folding_only,
}; };
let source = world.source_by_path(&path).unwrap(); let source = world.source_by_path(&path).unwrap();
let result = request.request(&source, PositionEncoding::Utf16); request.request(&source, PositionEncoding::Utf16)
assert_snapshot!(JsonRepr::new_pure(result.unwrap())); };
let result_false = r(false);
let result_true = r(true);
assert_snapshot!(JsonRepr::new_pure(json!({
"false": result_false,
"true": result_true,
})));
}); });
} }
} }

View file

@ -23,6 +23,7 @@ use typst::{diag::PackageError, foundations::Bytes};
pub use insta::assert_snapshot; pub use insta::assert_snapshot;
pub use reflexo_typst::TypstSystemWorld; pub use reflexo_typst::TypstSystemWorld;
pub use serde::Serialize; pub use serde::Serialize;
pub use serde_json::json;
use crate::{ use crate::{
analysis::{Analysis, AnalysisResources}, analysis::{Analysis, AnalysisResources},

View file

@ -100,7 +100,10 @@ embed-fonts = ["typst-assets/fonts"]
# Disable the default content hint. # Disable the default content hint.
# This requires modifying typst. # This requires modifying typst.
no-content-hint = ["reflexo-typst/no-content-hint"] no-content-hint = [
"reflexo-typst/no-content-hint",
"reflexo-vec2svg/no-content-hint",
]
preview = [ preview = [
"typst-preview", "typst-preview",