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_json.workspace = true
typst-assets = { workspace = true, features = ["fonts"] }
reflexo-typst.workspace = true
reflexo-typst = { workspace = true, features = ["no-content-hint"] }
sha2 = { version = "0.10" }
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,14 +1,23 @@
---
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
---
[
{
"collapsedText": "",
"endCharacter": 1,
"endLine": 4,
"startCharacter": 1,
"startLine": 0
}
]
{
"false": [
{
"collapsedText": "",
"endCharacter": 1,
"endLine": 4,
"startCharacter": 1,
"startLine": 0
}
],
"true": [
{
"collapsedText": "",
"endLine": 4,
"startLine": 0
}
]
}

View file

@ -1,35 +1,54 @@
---
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
---
[
{
"collapsedText": "Heading 2",
"endCharacter": 12,
"endLine": 2,
"startCharacter": 3,
"startLine": 2
},
{
"collapsedText": "Heading 1",
"endCharacter": 11,
"endLine": 3,
"startCharacter": 2,
"startLine": 0
},
{
"collapsedText": "",
"endCharacter": 1,
"endLine": 9,
"startCharacter": 9,
"startLine": 6
},
{
"collapsedText": "Heading 3",
"endCharacter": 11,
"endLine": 9,
"startCharacter": 2,
"startLine": 4
}
]
{
"false": [
{
"collapsedText": "Heading 2",
"endCharacter": 12,
"endLine": 2,
"startCharacter": 3,
"startLine": 2
},
{
"collapsedText": "Heading 1",
"endCharacter": 11,
"endLine": 3,
"startCharacter": 2,
"startLine": 0
},
{
"collapsedText": "",
"endCharacter": 1,
"endLine": 9,
"startCharacter": 9,
"startLine": 6
},
{
"collapsedText": "Heading 3",
"endCharacter": 11,
"endLine": 9,
"startCharacter": 2,
"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,49 +1,73 @@
---
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
---
[
{
"collapsedText": "",
"endCharacter": 11,
"endLine": 2,
"startCharacter": 8,
"startLine": 2
},
{
"collapsedText": "",
"endCharacter": 13,
"endLine": 6,
"startCharacter": 10,
"startLine": 6
},
{
"collapsedText": "Heading 2",
"endCharacter": 16,
"endLine": 8,
"startCharacter": 7,
"startLine": 5
},
{
"collapsedText": "",
"endCharacter": 3,
"endLine": 7,
"startCharacter": 11,
"startLine": 3
},
{
"collapsedText": "Heading 1",
"endCharacter": 14,
"endLine": 8,
"startCharacter": 5,
"startLine": 1
},
{
"collapsedText": "",
"endCharacter": 1,
"endLine": 8,
"startCharacter": 9,
"startLine": 0
}
]
{
"false": [
{
"collapsedText": "",
"endCharacter": 11,
"endLine": 2,
"startCharacter": 8,
"startLine": 2
},
{
"collapsedText": "",
"endCharacter": 13,
"endLine": 6,
"startCharacter": 10,
"startLine": 6
},
{
"collapsedText": "Heading 2",
"endCharacter": 16,
"endLine": 8,
"startCharacter": 7,
"startLine": 5
},
{
"collapsedText": "",
"endCharacter": 3,
"endLine": 7,
"startCharacter": 11,
"startLine": 3
},
{
"collapsedText": "Heading 1",
"endCharacter": 14,
"endLine": 8,
"startCharacter": 5,
"startLine": 1
},
{
"collapsedText": "",
"endCharacter": 1,
"endLine": 8,
"startCharacter": 9,
"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,70 +1,114 @@
---
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
---
[
{
"collapsedText": "",
"endCharacter": 5,
"endLine": 4,
"startCharacter": 12,
"startLine": 2
},
{
"collapsedText": "",
"endCharacter": 3,
"endLine": 5,
"startCharacter": 10,
"startLine": 1
},
{
"collapsedText": "",
"endCharacter": 3,
"endLine": 8,
"startCharacter": 11,
"startLine": 6
},
{
"collapsedText": "",
"endCharacter": 4,
"endLine": 8,
"startCharacter": 10,
"startLine": 6
},
{
"collapsedText": "",
"endCharacter": 5,
"endLine": 12,
"startCharacter": 12,
"startLine": 10
},
{
"collapsedText": "",
"endCharacter": 5,
"endLine": 14,
"startCharacter": 8,
"startLine": 12
},
{
"collapsedText": "",
"endCharacter": 3,
"endLine": 15,
"startCharacter": 10,
"startLine": 9
},
{
"collapsedText": "",
"endCharacter": 3,
"endLine": 17,
"startCharacter": 10,
"startLine": 16
},
{
"collapsedText": "",
"endCharacter": 1,
"endLine": 18,
"startCharacter": 9,
"startLine": 0
}
]
{
"false": [
{
"collapsedText": "",
"endCharacter": 5,
"endLine": 4,
"startCharacter": 12,
"startLine": 2
},
{
"collapsedText": "",
"endCharacter": 3,
"endLine": 5,
"startCharacter": 10,
"startLine": 1
},
{
"collapsedText": "",
"endCharacter": 3,
"endLine": 8,
"startCharacter": 11,
"startLine": 6
},
{
"collapsedText": "",
"endCharacter": 4,
"endLine": 8,
"startCharacter": 10,
"startLine": 6
},
{
"collapsedText": "",
"endCharacter": 5,
"endLine": 12,
"startCharacter": 12,
"startLine": 10
},
{
"collapsedText": "",
"endCharacter": 5,
"endLine": 14,
"startCharacter": 8,
"startLine": 12
},
{
"collapsedText": "",
"endCharacter": 3,
"endLine": 15,
"startCharacter": 10,
"startLine": 9
},
{
"collapsedText": "",
"endCharacter": 3,
"endLine": 17,
"startCharacter": 10,
"startLine": 16
},
{
"collapsedText": "",
"endCharacter": 1,
"endLine": 18,
"startCharacter": 9,
"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,14 +1,23 @@
---
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
---
[
{
"collapsedText": "",
"endCharacter": 1,
"endLine": 2,
"startCharacter": 1,
"startLine": 0
}
]
{
"false": [
{
"collapsedText": "",
"endCharacter": 1,
"endLine": 2,
"startCharacter": 1,
"startLine": 0
}
],
"true": [
{
"collapsedText": "",
"endLine": 2,
"startLine": 0
}
]
}

View file

@ -1,3 +1,5 @@
use hashbrown::HashSet;
use crate::{
prelude::*,
syntax::{get_lexical_hierarchy, LexicalHierarchy, LexicalKind, LexicalScopeKind},
@ -42,12 +44,45 @@ impl SyntaxRequest for FoldingRangeRequest {
&symbols,
source,
position_encoding,
line_folding_only,
loc,
loc,
true,
&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 {
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>);
#[allow(clippy::too_many_arguments)]
#[allow(deprecated)]
fn calc_folding_range(
symbols: &[LexicalHierarchy],
source: &Source,
position_encoding: PositionEncoding,
line_folding_only: bool,
parent_last_loc: LoC,
last_loc: LoC,
is_last_range: bool,
@ -79,7 +111,7 @@ fn calc_folding_range(
start_line: rng.start.line,
start_character: Some(rng.start.character),
end_line: rng.end.line,
end_character: line_folding_only.then_some(rng.end.character),
end_character: Some(rng.end.character),
kind: None,
collapsed_text: Some(e.info.name.clone()),
};
@ -113,7 +145,6 @@ fn calc_folding_range(
ch,
source,
position_encoding,
line_folding_only,
parent_last_loc,
last_loc,
!is_not_final_last_range,
@ -133,15 +164,23 @@ mod tests {
#[test]
fn test() {
snapshot_testing("folding_range", &|world, path| {
let request = FoldingRangeRequest {
path: path.clone(),
line_folding_only: true,
let mut r = |line_folding_only| {
let request = FoldingRangeRequest {
path: path.clone(),
line_folding_only,
};
let source = world.source_by_path(&path).unwrap();
request.request(&source, PositionEncoding::Utf16)
};
let source = world.source_by_path(&path).unwrap();
let result = 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 reflexo_typst::TypstSystemWorld;
pub use serde::Serialize;
pub use serde_json::json;
use crate::{
analysis::{Analysis, AnalysisResources},

View file

@ -100,7 +100,10 @@ embed-fonts = ["typst-assets/fonts"]
# Disable the default content hint.
# 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 = [
"typst-preview",