fix: more rules to forbidden arg completion (#1493)

* fix: more rules to forbidden arg completion

* fix: fix case

* feat: revert one
This commit is contained in:
Myriad-Dreamin 2025-03-13 09:56:31 +08:00 committed by GitHub
parent a68399c92e
commit 774227d328
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
14 changed files with 145 additions and 15 deletions

View file

@ -1088,6 +1088,18 @@ impl<'a> SyntaxContext<'a> {
| SyntaxContext::Normal(node) => node.clone(),
})
}
/// Gets the argument container node.
pub fn arg_container(&self) -> Option<&LinkedNode<'a>> {
match self {
Self::Arg { args, .. }
| Self::Element {
container: args, ..
} => Some(args),
Self::Paren { container, .. } => Some(container),
_ => None,
}
}
}
/// Kind of argument source.
@ -1342,6 +1354,37 @@ fn arg_context<'a>(
}
}
/// The cursor is on an invalid position.
pub enum BadCompletionCursor {
/// The cursor is outside of the argument list.
ArgListPos,
}
/// Checks if the cursor is on an invalid position for completion.
pub fn bad_completion_cursor(
syntax: Option<&SyntaxClass>,
syntax_context: Option<&SyntaxContext>,
leaf: &LinkedNode,
) -> Option<BadCompletionCursor> {
// The cursor is on `f()|`
if (matches!(syntax, Some(SyntaxClass::Callee(..))) && {
syntax_context
.and_then(SyntaxContext::arg_container)
.is_some_and(|container| {
container.rightmost_leaf().map(|s| s.offset()) == Some(leaf.offset())
})
// The cursor is on `f[]|`
}) || (matches!(
syntax,
Some(SyntaxClass::Normal(SyntaxKind::ContentBlock, _))
) && matches!(leaf.kind(), SyntaxKind::RightBracket))
{
return Some(BadCompletionCursor::ArgListPos);
}
None
}
#[cfg(test)]
mod tests {
use super::*;

View file

@ -10,6 +10,7 @@ use lsp_types::InsertTextFormat;
use once_cell::sync::Lazy;
use regex::{Captures, Regex};
use serde::{Deserialize, Serialize};
use tinymist_analysis::syntax::bad_completion_cursor;
use tinymist_derive::BindTyCtx;
use tinymist_project::LspWorld;
use tinymist_std::path::unix_slash;
@ -174,13 +175,7 @@ impl<'a> CompletionCursor<'a> {
let syntax_context = classify_context(leaf.clone(), Some(cursor));
let surrounding_syntax = surrounding_syntax(&leaf);
// todo: don't match here?
if matches!(syntax, Some(SyntaxClass::Callee(..)))
&& matches!(syntax_context.as_ref(), Some(
SyntaxContext::Element { container, .. } |
SyntaxContext::Arg { args: container, .. } |
SyntaxContext::Paren { container, .. }) if container.rightmost_leaf().map(|s| s.offset()) == Some(leaf.offset()))
{
if bad_completion_cursor(syntax.as_ref(), syntax_context.as_ref(), &leaf).is_some() {
return None;
}

View file

@ -0,0 +1,2 @@
/// contains: alignment
#align()[/* range 0..1 */]

View file

@ -0,0 +1,2 @@
/// contains: alignment
#align()[]/* range 0..1 */

View file

@ -0,0 +1,4 @@
/// contains: alignment
#align()[
]/* range 0..1 */

View file

@ -0,0 +1,4 @@
/// contains: alignment
#align()[/* range 0..1 */
]

View file

@ -1,3 +1,3 @@
/// contains: delta
#strong(/* range after 1..2 */[];
#strong(/* range 0..1 */[];

View file

@ -1,3 +1,3 @@
/// contains: delta
#strong(/* range after 1..2 */[]);
#strong(/* range 0..1 */[]);

View file

@ -0,0 +1,31 @@
---
source: crates/tinymist-query/src/completion.rs
description: Completion on / (33..34)
expression: "JsonRepr::new_pure(results)"
input_file: crates/tinymist-query/src/fixtures/completion/arg_range2.typ
---
[
{
"isIncomplete": false,
"items": [
{
"kind": 15,
"label": "alignment",
"sortText": "000",
"textEdit": {
"newText": "${1:alignment}",
"range": {
"end": {
"character": 9,
"line": 1
},
"start": {
"character": 9,
"line": 1
}
}
}
}
]
}
]

View file

@ -0,0 +1,9 @@
---
source: crates/tinymist-query/src/completion.rs
description: Completion on / (34..35)
expression: "JsonRepr::new_pure(results)"
input_file: crates/tinymist-query/src/fixtures/completion/arg_range3.typ
---
[
null
]

View file

@ -0,0 +1,9 @@
---
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/arg_range4.typ
---
[
null
]

View file

@ -0,0 +1,31 @@
---
source: crates/tinymist-query/src/completion.rs
description: Completion on / (33..34)
expression: "JsonRepr::new_pure(results)"
input_file: crates/tinymist-query/src/fixtures/completion/arg_range5.typ
---
[
{
"isIncomplete": false,
"items": [
{
"kind": 15,
"label": "alignment",
"sortText": "000",
"textEdit": {
"newText": "${1:alignment}",
"range": {
"end": {
"character": 9,
"line": 1
},
"start": {
"character": 9,
"line": 1
}
}
}
}
]
}
]

View file

@ -1,6 +1,6 @@
---
source: crates/tinymist-query/src/completion.rs
description: "Completion on ] (52..53)"
description: Completion on / (29..30)
expression: "JsonRepr::new_pure(results)"
input_file: crates/tinymist-query/src/fixtures/completion/bracket_strong_delta.typ
---
@ -19,11 +19,11 @@ input_file: crates/tinymist-query/src/fixtures/completion/bracket_strong_delta.t
"newText": "delta: ${1:})",
"range": {
"end": {
"character": 31,
"character": 8,
"line": 2
},
"start": {
"character": 31,
"character": 8,
"line": 2
}
}

View file

@ -1,6 +1,6 @@
---
source: crates/tinymist-query/src/completion.rs
description: "Completion on ] (52..53)"
description: Completion on / (29..30)
expression: "JsonRepr::new_pure(results)"
input_file: crates/tinymist-query/src/fixtures/completion/bracket_strong_delta2.typ
---
@ -19,11 +19,11 @@ input_file: crates/tinymist-query/src/fixtures/completion/bracket_strong_delta2.
"newText": "delta: ${1:}",
"range": {
"end": {
"character": 31,
"character": 8,
"line": 2
},
"start": {
"character": 31,
"character": 8,
"line": 2
}
}