feat: auto complete parameters after completing a function (#150)

* feat: auto complete parameters after completing a function

* dev: update snapshot

* dev: update completion snapshot
This commit is contained in:
Myriad-Dreamin 2024-04-02 18:50:02 +08:00 committed by GitHub
parent d71dd38b98
commit bd610b2323
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
9 changed files with 69 additions and 24 deletions

View file

@ -250,6 +250,7 @@ fn complete_path(
kind: CompletionKind::Folder,
apply: None,
detail: None,
command: None,
});
} else {
module_completions.push(Completion {
@ -257,6 +258,7 @@ fn complete_path(
kind: CompletionKind::Module,
apply: None,
detail: None,
command: None,
});
}
}

View file

@ -114,7 +114,7 @@ input_file: crates/tinymist-query/src/fixtures/completion/base.typ
"kind": 3,
"label": "aa",
"textEdit": {
"newText": "aa",
"newText": "aa(${1:})",
"range": {
"end": {
"character": 4,
@ -131,7 +131,7 @@ input_file: crates/tinymist-query/src/fixtures/completion/base.typ
"kind": 3,
"label": "aab",
"textEdit": {
"newText": "aab",
"newText": "aab(${1:})",
"range": {
"end": {
"character": 4,
@ -148,7 +148,7 @@ input_file: crates/tinymist-query/src/fixtures/completion/base.typ
"kind": 3,
"label": "aabc",
"textEdit": {
"newText": "aabc",
"newText": "aabc(${1:})",
"range": {
"end": {
"character": 4,
@ -165,7 +165,7 @@ input_file: crates/tinymist-query/src/fixtures/completion/base.typ
"kind": 3,
"label": "aac",
"textEdit": {
"newText": "aac",
"newText": "aac(${1:})",
"range": {
"end": {
"character": 4,
@ -255,7 +255,7 @@ input_file: crates/tinymist-query/src/fixtures/completion/base.typ
"kind": 3,
"label": "aabc",
"textEdit": {
"newText": "aabc",
"newText": "aabc(${1:})",
"range": {
"end": {
"character": 4,
@ -272,7 +272,7 @@ input_file: crates/tinymist-query/src/fixtures/completion/base.typ
"kind": 3,
"label": "aac",
"textEdit": {
"newText": "aac",
"newText": "aac(${1:})",
"range": {
"end": {
"character": 4,

View file

@ -114,7 +114,7 @@ input_file: crates/tinymist-query/src/fixtures/completion/func_params.typ
"kind": 3,
"label": "aa",
"textEdit": {
"newText": "aa",
"newText": "aa(${1:})",
"range": {
"end": {
"character": 5,

View file

@ -114,7 +114,7 @@ input_file: crates/tinymist-query/src/fixtures/completion/item_shadow.typ
"kind": 3,
"label": "aa",
"textEdit": {
"newText": "aa",
"newText": "aa(${1:})",
"range": {
"end": {
"character": 4,
@ -131,7 +131,7 @@ input_file: crates/tinymist-query/src/fixtures/completion/item_shadow.typ
"kind": 3,
"label": "aac",
"textEdit": {
"newText": "aac",
"newText": "aac(${1:})",
"range": {
"end": {
"character": 4,
@ -221,7 +221,7 @@ input_file: crates/tinymist-query/src/fixtures/completion/item_shadow.typ
"kind": 3,
"label": "aac",
"textEdit": {
"newText": "aac",
"newText": "aac(${1:})",
"range": {
"end": {
"character": 4,

View file

@ -114,7 +114,7 @@ input_file: crates/tinymist-query/src/fixtures/completion/let.typ
"kind": 3,
"label": "aa",
"textEdit": {
"newText": "aa",
"newText": "aa(${1:})",
"range": {
"end": {
"character": 4,
@ -165,7 +165,7 @@ input_file: crates/tinymist-query/src/fixtures/completion/let.typ
"kind": 3,
"label": "aac",
"textEdit": {
"newText": "aac",
"newText": "aac(${1:})",
"range": {
"end": {
"character": 4,
@ -272,7 +272,7 @@ input_file: crates/tinymist-query/src/fixtures/completion/let.typ
"kind": 3,
"label": "aac",
"textEdit": {
"newText": "aac",
"newText": "aac(${1:})",
"range": {
"end": {
"character": 4,

View file

@ -211,7 +211,7 @@ pub mod typst_to_lsp {
use itertools::Itertools;
use lazy_static::lazy_static;
use lsp_types::{
CompletionTextEdit, Documentation, InsertTextFormat, LanguageString, MarkedString,
Command, CompletionTextEdit, Documentation, InsertTextFormat, LanguageString, MarkedString,
MarkupContent, MarkupKind, TextEdit,
};
use regex::{Captures, Regex};
@ -312,6 +312,10 @@ pub mod typst_to_lsp {
detail: typst_completion.detail.as_ref().map(String::from),
text_edit: Some(text_edit),
insert_text_format: Some(InsertTextFormat::SNIPPET),
command: typst_completion.command.as_ref().map(|c| Command {
command: c.to_string(),
..Default::default()
}),
..Default::default()
}
}

View file

@ -60,10 +60,12 @@ pub struct Completion {
pub apply: Option<EcoString>,
/// An optional short description, at most one sentence.
pub detail: Option<EcoString>,
/// An optional command to run when the completion is selected.
pub command: Option<&'static str>,
}
/// A kind of item that can be completed.
#[derive(Debug, Clone, Serialize, Deserialize)]
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
#[serde(rename_all = "kebab-case")]
pub enum CompletionKind {
/// A syntactical structure.
@ -394,6 +396,7 @@ fn field_access_completions(ctx: &mut CompletionContext, value: &Value, styles:
eco_format!("{method}()${{}}")
}),
detail: None,
command: None,
})
}
@ -420,6 +423,7 @@ fn field_access_completions(ctx: &mut CompletionContext, value: &Value, styles:
label: modifier.into(),
apply: None,
detail: None,
command: None,
});
}
}
@ -454,6 +458,7 @@ fn field_access_completions(ctx: &mut CompletionContext, value: &Value, styles:
label: name.clone(),
apply: None,
detail: None,
command: None,
})
}
}
@ -987,6 +992,12 @@ impl<'a, 'w> CompletionContext<'a, 'w> {
label: label.into(),
apply: Some(snippet.into()),
detail: Some(docs.into()),
// VS Code doesn't do that... Auto triggering suggestion only happens on typing (word
// starts or trigger characters). However, you can use editor.action.triggerSuggest as
// command on a suggestion to "manually" retrigger suggest after inserting one
//
// todo: only vscode and neovim (0.9.1) support this
command: Some("editor.action.triggerSuggest"),
});
}
@ -1041,6 +1052,7 @@ impl<'a, 'w> CompletionContext<'a, 'w> {
label: name.into(),
apply: Some(tags[0].into()),
detail: Some(repr::separated_list(&tags, " or ").into()),
command: None,
});
}
}
@ -1079,6 +1091,7 @@ impl<'a, 'w> CompletionContext<'a, 'w> {
}),
label: label.as_str().into(),
detail,
command: None,
});
}
}
@ -1105,8 +1118,10 @@ impl<'a, 'w> CompletionContext<'a, 'w> {
});
let mut apply = None;
let mut command = None;
if parens && matches!(value, Value::Func(_)) {
if let Value::Func(func) = value {
command = Some("editor.action.triggerSuggest");
if func
.params()
.is_some_and(|params| params.iter().all(|param| param.name == "self"))
@ -1134,6 +1149,7 @@ impl<'a, 'w> CompletionContext<'a, 'w> {
label,
apply,
detail,
command,
});
}
@ -1209,6 +1225,7 @@ impl<'a, 'w> CompletionContext<'a, 'w> {
label: ty.long_name().into(),
apply: Some(eco_format!("${{{ty}}}")),
detail: Some(eco_format!("A value of type {ty}.")),
command: None,
});
self.scope_completions_(false, |value| value.ty() == *ty);
}

View file

@ -134,15 +134,29 @@ impl<'a, 'w> CompletionContext<'a, 'w> {
for (name, kind) in defined {
if !name.is_empty() {
if kind == CompletionKind::Func {
// todo: check arguments, if empty, jump to after the parens
let apply = eco_format!("{}(${{}})", name);
self.completions.push(Completion {
kind,
label: name,
apply: Some(apply),
detail: None,
// todo: only vscode and neovim (0.9.1) support this
command: Some("editor.action.triggerSuggest"),
});
} else {
self.completions.push(Completion {
kind,
label: name,
apply: None,
detail: None,
command: None,
});
}
}
}
}
}
/// Add completions for the parameters of a function.
@ -190,6 +204,13 @@ pub fn param_completions<'a>(
label: param.name.clone().into(),
apply: Some(eco_format!("{}: ${{}}", param.name)),
detail: Some(plain_docs_sentence(&param.docs)),
// todo: only vscode and neovim (0.9.1) support this
//
// VS Code doesn't do that... Auto triggering suggestion only happens on typing
// (word starts or trigger characters). However, you can use
// editor.action.triggerSuggest as command on a suggestion to
// "manually" retrigger suggest after inserting one
command: Some("editor.action.triggerSuggest"),
});
}
@ -230,12 +251,13 @@ pub fn named_param_value_completions<'a>(
return;
}
if let Some(expr) = &param.type_repr {
if let Some(expr) = &param.expr {
ctx.completions.push(Completion {
kind: CompletionKind::Constant,
label: expr.clone(),
apply: None,
detail: Some(plain_docs_sentence(&param.docs)),
command: None,
});
}

View file

@ -375,7 +375,7 @@ fn e2e() {
});
let hash = replay_log(&tinymist_binary, &root.join("neovim"));
insta::assert_snapshot!(hash, @"siphash128_13:db5f6b70fa2cff5f0a58b4d11de387f9");
insta::assert_snapshot!(hash, @"siphash128_13:3a5dda1ab162b4cb843916a23f05ac0");
}
{
@ -386,7 +386,7 @@ fn e2e() {
});
let hash = replay_log(&tinymist_binary, &root.join("vscode"));
insta::assert_snapshot!(hash, @"siphash128_13:a4bb5a2f5705857f8fbd7f8f71ac86c9");
insta::assert_snapshot!(hash, @"siphash128_13:75e8e25d2b63fc959c024b5a509466d7");
}
}