mirror of
https://github.com/Myriad-Dreamin/tinymist.git
synced 2025-07-24 13:13:43 +00:00
feat: append rest code completion result after param completed (#208)
* feat: append rest code completion result after param completed * dev: update snapshot
This commit is contained in:
parent
f79a83e616
commit
e54d74812e
7 changed files with 9762 additions and 37 deletions
File diff suppressed because it is too large
Load diff
File diff suppressed because it is too large
Load diff
|
@ -11,6 +11,7 @@ input_file: crates/tinymist-query/src/fixtures/completion/func_args2.typ
|
|||
{
|
||||
"kind": 6,
|
||||
"label": "class",
|
||||
"sortText": "000",
|
||||
"textEdit": {
|
||||
"newText": " class: ${1:}",
|
||||
"range": {
|
||||
|
@ -28,6 +29,7 @@ input_file: crates/tinymist-query/src/fixtures/completion/func_args2.typ
|
|||
{
|
||||
"kind": 6,
|
||||
"label": "font",
|
||||
"sortText": "001",
|
||||
"textEdit": {
|
||||
"newText": " font: ${1:}",
|
||||
"range": {
|
||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -312,6 +312,7 @@ pub mod typst_to_lsp {
|
|||
label: typst_completion.label.to_string(),
|
||||
kind: Some(completion_kind(typst_completion.kind.clone())),
|
||||
detail: typst_completion.detail.as_ref().map(String::from),
|
||||
sort_text: typst_completion.sort_text.as_ref().map(String::from),
|
||||
label_details: typst_completion.label_detail.as_ref().map(|e| {
|
||||
CompletionItemLabelDetails {
|
||||
detail: None,
|
||||
|
|
|
@ -54,7 +54,7 @@ pub fn autocomplete(
|
|||
}
|
||||
|
||||
/// An autocompletion option.
|
||||
#[derive(Debug, Clone, Serialize, Deserialize)]
|
||||
#[derive(Debug, Clone, Serialize, Deserialize, Default)]
|
||||
pub struct Completion {
|
||||
/// The kind of item this completes to.
|
||||
pub kind: CompletionKind,
|
||||
|
@ -62,6 +62,8 @@ pub struct Completion {
|
|||
pub label: EcoString,
|
||||
/// The label the completion is shown with.
|
||||
pub label_detail: Option<EcoString>,
|
||||
/// The label the completion is shown with.
|
||||
pub sort_text: Option<EcoString>,
|
||||
/// The completed version of the input, possibly described with snippet
|
||||
/// syntax like `${lhs} + ${rhs}`.
|
||||
///
|
||||
|
@ -74,7 +76,7 @@ pub struct Completion {
|
|||
}
|
||||
|
||||
/// A kind of item that can be completed.
|
||||
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
|
||||
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq, Default)]
|
||||
#[serde(rename_all = "kebab-case")]
|
||||
pub enum CompletionKind {
|
||||
/// A syntactical structure.
|
||||
|
@ -88,6 +90,7 @@ pub enum CompletionKind {
|
|||
/// A field.
|
||||
Field,
|
||||
/// A constant.
|
||||
#[default]
|
||||
Constant,
|
||||
/// A symbol.
|
||||
Symbol(char),
|
||||
|
@ -408,9 +411,7 @@ fn field_access_completions(ctx: &mut CompletionContext, value: &Value, styles:
|
|||
} else {
|
||||
eco_format!("{method}()${{}}")
|
||||
}),
|
||||
detail: None,
|
||||
label_detail: None,
|
||||
command: None,
|
||||
..Completion::default()
|
||||
})
|
||||
}
|
||||
|
||||
|
@ -435,10 +436,7 @@ fn field_access_completions(ctx: &mut CompletionContext, value: &Value, styles:
|
|||
ctx.completions.push(Completion {
|
||||
kind: CompletionKind::Symbol(modified.get()),
|
||||
label: modifier.into(),
|
||||
apply: None,
|
||||
detail: None,
|
||||
label_detail: None,
|
||||
command: None,
|
||||
..Completion::default()
|
||||
});
|
||||
}
|
||||
}
|
||||
|
@ -471,10 +469,7 @@ fn field_access_completions(ctx: &mut CompletionContext, value: &Value, styles:
|
|||
ctx.completions.push(Completion {
|
||||
kind: CompletionKind::Func,
|
||||
label: name.clone(),
|
||||
apply: None,
|
||||
detail: None,
|
||||
label_detail: None,
|
||||
command: None,
|
||||
..Completion::default()
|
||||
})
|
||||
}
|
||||
}
|
||||
|
@ -1034,6 +1029,7 @@ impl<'a, 'w> CompletionContext<'a, 'w> {
|
|||
//
|
||||
// todo: only vscode and neovim (0.9.1) support this
|
||||
command: Some("editor.action.triggerSuggest"),
|
||||
..Completion::default()
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -1088,8 +1084,7 @@ impl<'a, 'w> CompletionContext<'a, 'w> {
|
|||
label: name.into(),
|
||||
apply: Some(tags[0].into()),
|
||||
detail: Some(repr::separated_list(&tags, " or ").into()),
|
||||
label_detail: None,
|
||||
command: None,
|
||||
..Completion::default()
|
||||
});
|
||||
}
|
||||
}
|
||||
|
@ -1128,8 +1123,7 @@ impl<'a, 'w> CompletionContext<'a, 'w> {
|
|||
}),
|
||||
label: label.as_str().into(),
|
||||
detail,
|
||||
label_detail: None,
|
||||
command: None,
|
||||
..Completion::default()
|
||||
});
|
||||
}
|
||||
}
|
||||
|
@ -1189,6 +1183,7 @@ impl<'a, 'w> CompletionContext<'a, 'w> {
|
|||
detail,
|
||||
label_detail: None,
|
||||
command,
|
||||
..Completion::default()
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -1264,8 +1259,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}.")),
|
||||
label_detail: None,
|
||||
command: None,
|
||||
..Completion::default()
|
||||
});
|
||||
self.scope_completions(false, |value| value.ty() == *ty);
|
||||
}
|
||||
|
|
|
@ -17,6 +17,7 @@ use crate::analysis::{
|
|||
FLOW_RADIUS_DICT, FLOW_STROKE_DICT,
|
||||
};
|
||||
use crate::syntax::{get_non_strict_def_target, param_index_at_leaf, DefTarget};
|
||||
use crate::upstream::complete::complete_code;
|
||||
use crate::upstream::plain_docs_sentence;
|
||||
|
||||
use crate::{prelude::*, typst_to_lsp::completion_kind, LspCompletion};
|
||||
|
@ -157,20 +158,18 @@ impl<'a, 'w> CompletionContext<'a, 'w> {
|
|||
kind: kind.clone(),
|
||||
label: eco_format!("{}.with", name),
|
||||
apply: Some(apply),
|
||||
detail: None,
|
||||
label_detail: None,
|
||||
// todo: only vscode and neovim (0.9.1) support this
|
||||
command: Some("editor.action.triggerSuggest"),
|
||||
..Default::default()
|
||||
});
|
||||
let apply = eco_format!("{}.where(${{}})", name);
|
||||
self.completions.push(Completion {
|
||||
kind: kind.clone(),
|
||||
label: eco_format!("{}.where", name),
|
||||
apply: Some(apply),
|
||||
detail: None,
|
||||
label_detail: None,
|
||||
// todo: only vscode and neovim (0.9.1) support this
|
||||
command: Some("editor.action.triggerSuggest"),
|
||||
..Default::default()
|
||||
});
|
||||
// todo: check arguments, if empty, jump to after the parens
|
||||
let apply = eco_format!("{}(${{}})", name);
|
||||
|
@ -178,19 +177,15 @@ impl<'a, 'w> CompletionContext<'a, 'w> {
|
|||
kind: kind.clone(),
|
||||
label: name,
|
||||
apply: Some(apply),
|
||||
detail: None,
|
||||
label_detail: None,
|
||||
// todo: only vscode and neovim (0.9.1) support this
|
||||
command: Some("editor.action.triggerSuggest"),
|
||||
..Completion::default()
|
||||
});
|
||||
} else {
|
||||
self.completions.push(Completion {
|
||||
kind,
|
||||
label: name,
|
||||
apply: None,
|
||||
detail: None,
|
||||
label_detail: None,
|
||||
command: None,
|
||||
..Completion::default()
|
||||
});
|
||||
}
|
||||
}
|
||||
|
@ -198,6 +193,58 @@ impl<'a, 'w> CompletionContext<'a, 'w> {
|
|||
}
|
||||
}
|
||||
|
||||
fn sort_and_explicit_code_completion(ctx: &mut CompletionContext) {
|
||||
let mut completions = std::mem::take(&mut ctx.completions);
|
||||
let explict = ctx.explicit;
|
||||
ctx.explicit = true;
|
||||
complete_code(ctx);
|
||||
ctx.explicit = explict;
|
||||
|
||||
log::info!(
|
||||
"sort_and_explicit_code_completion: {:#?} {:#?}",
|
||||
completions,
|
||||
ctx.completions
|
||||
);
|
||||
|
||||
completions.sort_by(|a, b| {
|
||||
a.sort_text
|
||||
.as_ref()
|
||||
.cmp(&b.sort_text.as_ref())
|
||||
.then_with(|| a.label.cmp(&b.label))
|
||||
});
|
||||
ctx.completions.sort_by(|a, b| {
|
||||
a.sort_text
|
||||
.as_ref()
|
||||
.cmp(&b.sort_text.as_ref())
|
||||
.then_with(|| a.label.cmp(&b.label))
|
||||
});
|
||||
|
||||
// todo: this is a bit messy, we can refactor for improving maintainability
|
||||
// The messy code will finally gone, but to help us go over the mess stage, I
|
||||
// drop some comment here.
|
||||
//
|
||||
// currently, there are only path completions in ctx.completions2
|
||||
// and type/named param/positional param completions in completions
|
||||
// and all rest less relevant completions inctx.completions
|
||||
for (i, compl) in ctx.completions2.iter_mut().enumerate() {
|
||||
compl.sort_text = Some(format!("{i:03}"));
|
||||
}
|
||||
let sort_base = ctx.completions2.len();
|
||||
for (i, compl) in (completions.iter_mut().chain(ctx.completions.iter_mut())).enumerate() {
|
||||
compl.sort_text = Some(eco_format!("{i:03}", i = i + sort_base));
|
||||
}
|
||||
|
||||
log::info!(
|
||||
"sort_and_explicit_code_completion after: {:#?} {:#?}",
|
||||
completions,
|
||||
ctx.completions
|
||||
);
|
||||
|
||||
ctx.completions.append(&mut completions);
|
||||
|
||||
log::debug!("sort_and_explicit_code_completion: {:?}", ctx.completions);
|
||||
}
|
||||
|
||||
/// Add completions for the parameters of a function.
|
||||
pub fn param_completions<'a>(
|
||||
ctx: &mut CompletionContext<'a, '_>,
|
||||
|
@ -314,6 +361,7 @@ pub fn param_completions<'a>(
|
|||
// editor.action.triggerSuggest as command on a suggestion to
|
||||
// "manually" retrigger suggest after inserting one
|
||||
command: Some("editor.action.triggerSuggest"),
|
||||
..Completion::default()
|
||||
};
|
||||
match param.infer_type {
|
||||
Some(FlowType::Builtin(FlowBuiltinType::TextSize)) => {
|
||||
|
@ -356,6 +404,7 @@ pub fn param_completions<'a>(
|
|||
}
|
||||
}
|
||||
|
||||
sort_and_explicit_code_completion(ctx);
|
||||
if ctx.before.ends_with(',') {
|
||||
ctx.enrich(" ", "");
|
||||
}
|
||||
|
@ -465,7 +514,7 @@ fn type_completion(
|
|||
apply: Some(eco_format!("\"{}\"", key.to_lowercase())),
|
||||
detail: Some(detail),
|
||||
label_detail: Some(desc.name.into()),
|
||||
command: None,
|
||||
..Completion::default()
|
||||
});
|
||||
}
|
||||
}
|
||||
|
@ -478,7 +527,7 @@ fn type_completion(
|
|||
apply: Some(eco_format!("\"{}\"", key.to_lowercase())),
|
||||
detail: Some(detail),
|
||||
label_detail: Some(desc.name.into()),
|
||||
command: None,
|
||||
..Completion::default()
|
||||
});
|
||||
}
|
||||
}
|
||||
|
@ -570,8 +619,7 @@ fn type_completion(
|
|||
label: ty.long_name().into(),
|
||||
apply: Some(eco_format!("${{{ty}}}")),
|
||||
detail: Some(eco_format!("A value of type {ty}.")),
|
||||
label_detail: None,
|
||||
command: None,
|
||||
..Completion::default()
|
||||
});
|
||||
ctx.strict_scope_completions(false, |value| value.ty() == *ty);
|
||||
}
|
||||
|
@ -687,8 +735,7 @@ pub fn named_param_value_completions<'a>(
|
|||
label: expr.clone(),
|
||||
apply: None,
|
||||
detail: doc.map(Into::into),
|
||||
label_detail: None,
|
||||
command: None,
|
||||
..Completion::default()
|
||||
});
|
||||
}
|
||||
}
|
||||
|
@ -703,6 +750,7 @@ pub fn named_param_value_completions<'a>(
|
|||
ctx.cast_completions(¶m.input);
|
||||
}
|
||||
|
||||
sort_and_explicit_code_completion(ctx);
|
||||
if ctx.before.ends_with(':') {
|
||||
ctx.enrich(" ", "");
|
||||
}
|
||||
|
@ -805,10 +853,9 @@ pub fn complete_literal(ctx: &mut CompletionContext) -> Option<()> {
|
|||
kind: CompletionKind::Field,
|
||||
label: key.clone(),
|
||||
apply: Some(eco_format!("{}: ${{}}", key)),
|
||||
detail: None,
|
||||
label_detail: None,
|
||||
// todo: only vscode and neovim (0.9.1) support this
|
||||
command: Some("editor.action.triggerSuggest"),
|
||||
..Completion::default()
|
||||
});
|
||||
}
|
||||
}
|
||||
|
@ -862,6 +909,7 @@ pub fn complete_literal(ctx: &mut CompletionContext) -> Option<()> {
|
|||
}
|
||||
ctx.incomplete = false;
|
||||
|
||||
sort_and_explicit_code_completion(ctx);
|
||||
Some(())
|
||||
}
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue