fix: correct parent_last_loc for heading children in folding ranges (#2123)

This PR fixes #1796 by correcting the parent_last_loc parameter passed
to child elements when processing heading folding ranges.

This is because heading's `lsp_range` only covers the line it is on, but
it has children. This causes the `parent_last_loc` passed when
recursively calling the `calc_folding_range` function to be incorrect:
it is expected to be the end of the line before the next sibling
heading, but actually it is the end of the current heading's line. This
further prevents the correction of the heading's `folding_range` from
working properly, ultimately causing the returned `folding_range` to
retain the original `lsp_range`, which is just the heading line itself.

The fix uses the already-calculated `folding_range.end_line` for
headings when determining the `parent_last_loc` for child elements,
ensuring consistency between the parent's actual folding boundary and
the boundary passed to its children.
This commit is contained in:
ParaN3xus 2025-09-24 00:24:31 +08:00 committed by GitHub
parent 5ac358ef6a
commit 3b6de80a2f
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
5 changed files with 91 additions and 6 deletions

View file

@ -69,6 +69,7 @@ hex = { version = "0.4" }
[features]
local-registry = ["tinymist-world/system"]
system = ["tinymist-project/system"]
[lints]
workspace = true

View file

@ -0,0 +1,8 @@
// https://github.com/myriad-Dreamin/tinymist/issues/1796
= Heading 1
== Heading 1.a
== Heading 1.b
= Heading 2

View file

@ -2,14 +2,13 @@
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/base.typ
snapshot_kind: text
---
{
"false": [
{
"collapsedText": "Heading 2",
"endCharacter": 12,
"endLine": 2,
"endLine": 3,
"startCharacter": 3,
"startLine": 2
},
@ -36,6 +35,11 @@ snapshot_kind: text
}
],
"true": [
{
"collapsedText": "Heading 2",
"endLine": 3,
"startLine": 2
},
{
"collapsedText": "Heading 1",
"endLine": 3,

View file

@ -0,0 +1,67 @@
---
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/fold-heading-with-siblings.typ
---
{
"false": [
{
"collapsedText": "",
"endCharacter": 57,
"endLine": 0,
"kind": "comment",
"startCharacter": 0,
"startLine": 0
},
{
"collapsedText": "Heading 1.a",
"endCharacter": 14,
"endLine": 4,
"startCharacter": 3,
"startLine": 3
},
{
"collapsedText": "Heading 1.b",
"endCharacter": 14,
"endLine": 6,
"startCharacter": 3,
"startLine": 5
},
{
"collapsedText": "Heading 1",
"endCharacter": 11,
"endLine": 6,
"startCharacter": 2,
"startLine": 1
},
{
"collapsedText": "Heading 2",
"endCharacter": 11,
"endLine": 8,
"startCharacter": 2,
"startLine": 7
}
],
"true": [
{
"collapsedText": "Heading 1.a",
"endLine": 4,
"startLine": 3
},
{
"collapsedText": "Heading 1.b",
"endLine": 6,
"startLine": 5
},
{
"collapsedText": "Heading 1",
"endLine": 6,
"startLine": 1
},
{
"collapsedText": "Heading 2",
"endLine": 8,
"startLine": 7
}
]
}

View file

@ -139,10 +139,15 @@ fn calc_folding_range(
}
if let Some(ch) = &child.children {
let parent_last_loc = if is_not_last_range {
let parent_last_loc = match child.info.kind {
LexicalKind::Heading(_) => (folding_range.end_line, folding_range.end_character),
_ => {
if is_not_last_range {
(range.end.line, Some(range.end.character))
} else {
parent_last_loc
}
}
};
calc_folding_range(