fix: correctly shadow items for completion (#145)

This commit is contained in:
Myriad-Dreamin 2024-04-01 10:36:47 +08:00 committed by GitHub
parent d6e58ea961
commit b43dfcf11e
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
3 changed files with 265 additions and 10 deletions

View file

@ -0,0 +1,6 @@
#let aa = 1;
#let aa() = 1;
#let aac() = 1;
#aac(/* range -2..0 */);

View file

@ -0,0 +1,239 @@
---
source: crates/tinymist-query/src/completion.rs
description: Completion on c( (48..50)
expression: "JsonRepr::new_pure(results)"
input_file: crates/tinymist-query/src/fixtures/completion/item_shadow.typ
---
[
{
"isIncomplete": true,
"items": [
{
"kind": 7,
"label": "array",
"textEdit": {
"newText": "array",
"range": {
"end": {
"character": 4,
"line": 4
},
"start": {
"character": 1,
"line": 4
}
}
}
},
{
"kind": 3,
"label": "parbreak",
"textEdit": {
"newText": "parbreak()${1:}",
"range": {
"end": {
"character": 4,
"line": 4
},
"start": {
"character": 1,
"line": 4
}
}
}
},
{
"kind": 3,
"label": "smallcaps",
"textEdit": {
"newText": "smallcaps(${1:})",
"range": {
"end": {
"character": 4,
"line": 4
},
"start": {
"character": 1,
"line": 4
}
}
}
},
{
"kind": 3,
"label": "pagebreak",
"textEdit": {
"newText": "pagebreak(${1:})",
"range": {
"end": {
"character": 4,
"line": 4
},
"start": {
"character": 1,
"line": 4
}
}
}
},
{
"kind": 3,
"label": "metadata",
"textEdit": {
"newText": "metadata(${1:})",
"range": {
"end": {
"character": 4,
"line": 4
},
"start": {
"character": 1,
"line": 4
}
}
}
},
{
"kind": 21,
"label": "aqua",
"textEdit": {
"newText": "aqua",
"range": {
"end": {
"character": 4,
"line": 4
},
"start": {
"character": 1,
"line": 4
}
}
}
},
{
"kind": 3,
"label": "aa",
"textEdit": {
"newText": "aa",
"range": {
"end": {
"character": 4,
"line": 4
},
"start": {
"character": 1,
"line": 4
}
}
}
},
{
"kind": 3,
"label": "aac",
"textEdit": {
"newText": "aac",
"range": {
"end": {
"character": 4,
"line": 4
},
"start": {
"character": 1,
"line": 4
}
}
}
},
{
"kind": 15,
"label": "import package",
"textEdit": {
"newText": "import \"@${1:}\": ${2:items}",
"range": {
"end": {
"character": 4,
"line": 4
},
"start": {
"character": 1,
"line": 4
}
}
}
},
{
"kind": 15,
"label": "include (package)",
"textEdit": {
"newText": "include \"@${1:}\"",
"range": {
"end": {
"character": 4,
"line": 4
},
"start": {
"character": 1,
"line": 4
}
}
}
},
{
"kind": 15,
"label": "array literal",
"textEdit": {
"newText": "(${1:1, 2, 3})",
"range": {
"end": {
"character": 4,
"line": 4
},
"start": {
"character": 1,
"line": 4
}
}
}
},
{
"kind": 15,
"label": "dictionary literal",
"textEdit": {
"newText": "(${1:a: 1, b: 2})",
"range": {
"end": {
"character": 4,
"line": 4
},
"start": {
"character": 1,
"line": 4
}
}
}
}
]
},
{
"isIncomplete": true,
"items": [
{
"kind": 3,
"label": "aac",
"textEdit": {
"newText": "aac",
"range": {
"end": {
"character": 4,
"line": 4
},
"start": {
"character": 1,
"line": 4
}
}
}
}
]
}
]

View file

@ -1,6 +1,7 @@
use super::{Completion, CompletionContext, CompletionKind};
use std::collections::BTreeMap;
use ecow::EcoString;
use typst::foundations::Value;
use typst::syntax::{ast, SyntaxKind};
@ -12,6 +13,11 @@ impl<'a> CompletionContext<'a> {
/// Filters the global/math scope with the given filter.
pub fn scope_completions_(&mut self, parens: bool, filter: impl Fn(&Value) -> bool) {
let mut defined = BTreeMap::new();
let mut try_insert = |name: EcoString, kind: CompletionKind| {
if let std::collections::btree_map::Entry::Vacant(entry) = defined.entry(name) {
entry.insert(kind);
}
};
let mut ancestor = Some(self.leaf.clone());
while let Some(node) = &ancestor {
@ -23,7 +29,7 @@ impl<'a> CompletionContext<'a> {
ast::LetBindingKind::Normal(..) => CompletionKind::Variable,
};
for ident in v.kind().bindings() {
defined.insert(ident.get().clone(), kind.clone());
try_insert(ident.get().clone(), kind.clone());
}
}
@ -39,13 +45,9 @@ impl<'a> CompletionContext<'a> {
}
if let Some(value) = analyzed {
if imports.is_none() {
// todo: correct kind
defined.extend(
value
.name()
.map(Into::into)
.map(|e| (e, CompletionKind::Module)),
);
if let Some(name) = value.name() {
try_insert(name.into(), CompletionKind::Module);
}
} else if let Some(scope) = value.scope() {
for (name, v) in scope.iter() {
let kind = match v {
@ -54,7 +56,7 @@ impl<'a> CompletionContext<'a> {
Value::Type(..) => CompletionKind::Type,
_ => CompletionKind::Constant,
};
defined.insert(name.clone(), kind);
try_insert(name.clone(), kind);
}
}
}
@ -68,7 +70,15 @@ impl<'a> CompletionContext<'a> {
if node.prev_sibling_kind() != Some(SyntaxKind::In) {
let pattern = v.pattern();
for ident in pattern.bindings() {
defined.insert(ident.get().clone(), CompletionKind::Variable);
try_insert(ident.get().clone(), CompletionKind::Variable);
}
}
}
if let Some(v) = parent.cast::<ast::ForLoop>() {
if node.prev_sibling_kind() != Some(SyntaxKind::In) {
let pattern = v.pattern();
for ident in pattern.bindings() {
try_insert(ident.get().clone(), CompletionKind::Variable);
}
}
}