mirror of
https://github.com/Myriad-Dreamin/tinymist.git
synced 2025-08-03 01:42:14 +00:00
fix: correct field access dot target (#1489)
* fix: correct field access dot target * test: add cases about #1267
This commit is contained in:
parent
db1ff20a6d
commit
4bf6cdb9ed
9 changed files with 182 additions and 2 deletions
|
@ -71,7 +71,37 @@ pub fn node_ancestors<'a, 'b>(
|
|||
|
||||
/// Finds the first ancestor node that is an expression.
|
||||
pub fn first_ancestor_expr(node: LinkedNode) -> Option<LinkedNode> {
|
||||
node_ancestors(&node).find(|n| n.is::<ast::Expr>()).cloned()
|
||||
node_ancestors(&node)
|
||||
.find(|n| n.is::<ast::Expr>())
|
||||
.map(|mut node| {
|
||||
while matches!(node.kind(), SyntaxKind::Ident | SyntaxKind::MathIdent) {
|
||||
let Some(parent) = node.parent() else {
|
||||
return node;
|
||||
};
|
||||
|
||||
let Some(field_access) = parent.cast::<ast::FieldAccess>() else {
|
||||
return node;
|
||||
};
|
||||
|
||||
let dot = parent
|
||||
.children()
|
||||
.find(|n| matches!(n.kind(), SyntaxKind::Dot));
|
||||
|
||||
// Since typst matches `field()` by `case_last_match`, when the field access
|
||||
// `x.` (`Ident(x).Error("")`), it will match the `x` as the
|
||||
// field. We need to check dot position to filter out such cases.
|
||||
if dot.is_some_and(|dot| {
|
||||
dot.offset() <= node.offset() && field_access.field().span() == node.span()
|
||||
}) {
|
||||
node = parent;
|
||||
} else {
|
||||
return node;
|
||||
}
|
||||
}
|
||||
|
||||
node
|
||||
})
|
||||
.cloned()
|
||||
}
|
||||
|
||||
/// A node that is an ancestor of the given node or the previous sibling
|
||||
|
@ -715,7 +745,10 @@ pub fn classify_syntax(node: LinkedNode, cursor: usize) -> Option<SyntaxClass<'_
|
|||
matches!(mode, InterpretMode::Markup)
|
||||
&& (matches!(
|
||||
dot_target.kind(),
|
||||
SyntaxKind::Ident | SyntaxKind::MathIdent | SyntaxKind::FuncCall
|
||||
SyntaxKind::Ident
|
||||
| SyntaxKind::MathIdent
|
||||
| SyntaxKind::FieldAccess
|
||||
| SyntaxKind::FuncCall
|
||||
) || (matches!(
|
||||
dot_target.prev_leaf().as_deref().map(SyntaxNode::kind),
|
||||
Some(SyntaxKind::Hash)
|
||||
|
@ -1534,13 +1567,24 @@ Text
|
|||
|
||||
#[test]
|
||||
fn test_markup_chain_access() {
|
||||
assert_snapshot!(access_node("#a.b.", 5), @"a.b");
|
||||
assert_snapshot!(access_field("#a.b.", 5), @"DotSuffix: 5");
|
||||
assert_snapshot!(access_node("#a.b.c.", 7), @"a.b.c");
|
||||
assert_snapshot!(access_field("#a.b.c.", 7), @"DotSuffix: 7");
|
||||
assert_snapshot!(access_node("#context a.", 11), @"a");
|
||||
assert_snapshot!(access_field("#context a.", 11), @"DotSuffix: 11");
|
||||
assert_snapshot!(access_node("#context a.b.", 13), @"a.b");
|
||||
assert_snapshot!(access_field("#context a.b.", 13), @"DotSuffix: 13");
|
||||
|
||||
assert_snapshot!(access_node("#a.at(1).", 9), @"a.at(1)");
|
||||
assert_snapshot!(access_field("#a.at(1).", 9), @"DotSuffix: 9");
|
||||
assert_snapshot!(access_node("#context a.at(1).", 17), @"a.at(1)");
|
||||
assert_snapshot!(access_field("#context a.at(1).", 17), @"DotSuffix: 17");
|
||||
|
||||
assert_snapshot!(access_node("#a.at(1).c.", 11), @"a.at(1).c");
|
||||
assert_snapshot!(access_field("#a.at(1).c.", 11), @"DotSuffix: 11");
|
||||
assert_snapshot!(access_node("#context a.at(1).c.", 19), @"a.at(1).c");
|
||||
assert_snapshot!(access_field("#context a.at(1).c.", 19), @"DotSuffix: 19");
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
|
|
@ -0,0 +1,4 @@
|
|||
/// contains: first
|
||||
|
||||
#let dict = (first: (second: "value"))
|
||||
#dict.fi/* range 0..1 */
|
|
@ -0,0 +1,4 @@
|
|||
/// contains: second
|
||||
|
||||
#let dict = (first: (second: "value"))
|
||||
#dict.first.sec/* range 0..1 */
|
|
@ -0,0 +1,3 @@
|
|||
/// contains: sin
|
||||
|
||||
#if std.calc./* range 0..1 */
|
|
@ -0,0 +1,5 @@
|
|||
/// contains: sin
|
||||
|
||||
#{
|
||||
if std.calc./* range 0..1 */
|
||||
}
|
|
@ -0,0 +1,30 @@
|
|||
---
|
||||
source: crates/tinymist-query/src/completion.rs
|
||||
description: Completion on / (68..69)
|
||||
expression: "JsonRepr::new_pure(results)"
|
||||
input_file: crates/tinymist-query/src/fixtures/completion/dict_chain_access.typ
|
||||
---
|
||||
[
|
||||
{
|
||||
"isIncomplete": false,
|
||||
"items": [
|
||||
{
|
||||
"kind": 6,
|
||||
"label": "first",
|
||||
"textEdit": {
|
||||
"newText": "first",
|
||||
"range": {
|
||||
"end": {
|
||||
"character": 8,
|
||||
"line": 3
|
||||
},
|
||||
"start": {
|
||||
"character": 6,
|
||||
"line": 3
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
|
@ -0,0 +1,30 @@
|
|||
---
|
||||
source: crates/tinymist-query/src/completion.rs
|
||||
description: Completion on / (76..77)
|
||||
expression: "JsonRepr::new_pure(results)"
|
||||
input_file: crates/tinymist-query/src/fixtures/completion/dict_chain_access2.typ
|
||||
---
|
||||
[
|
||||
{
|
||||
"isIncomplete": false,
|
||||
"items": [
|
||||
{
|
||||
"kind": 6,
|
||||
"label": "second",
|
||||
"textEdit": {
|
||||
"newText": "second",
|
||||
"range": {
|
||||
"end": {
|
||||
"character": 15,
|
||||
"line": 3
|
||||
},
|
||||
"start": {
|
||||
"character": 12,
|
||||
"line": 3
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
|
@ -0,0 +1,30 @@
|
|||
---
|
||||
source: crates/tinymist-query/src/completion.rs
|
||||
description: Completion on / (32..33)
|
||||
expression: "JsonRepr::new_pure(results)"
|
||||
input_file: crates/tinymist-query/src/fixtures/completion/markup_chain.typ
|
||||
---
|
||||
[
|
||||
{
|
||||
"isIncomplete": false,
|
||||
"items": [
|
||||
{
|
||||
"kind": 3,
|
||||
"label": "sin",
|
||||
"textEdit": {
|
||||
"newText": "sin(${1:})",
|
||||
"range": {
|
||||
"end": {
|
||||
"character": 13,
|
||||
"line": 2
|
||||
},
|
||||
"start": {
|
||||
"character": 13,
|
||||
"line": 2
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
|
@ -0,0 +1,30 @@
|
|||
---
|
||||
source: crates/tinymist-query/src/completion.rs
|
||||
description: Completion on / (36..37)
|
||||
expression: "JsonRepr::new_pure(results)"
|
||||
input_file: crates/tinymist-query/src/fixtures/completion/markup_chain2.typ
|
||||
---
|
||||
[
|
||||
{
|
||||
"isIncomplete": false,
|
||||
"items": [
|
||||
{
|
||||
"kind": 3,
|
||||
"label": "sin",
|
||||
"textEdit": {
|
||||
"newText": "sin(${1:})",
|
||||
"range": {
|
||||
"end": {
|
||||
"character": 14,
|
||||
"line": 3
|
||||
},
|
||||
"start": {
|
||||
"character": 14,
|
||||
"line": 3
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
Loading…
Add table
Add a link
Reference in a new issue