mirror of
https://github.com/Myriad-Dreamin/tinymist.git
synced 2025-07-19 10:45:02 +00:00
feat: complete arguments enhanced by type inference (#186)
* auto complete code in param position * dev: initial path completion in params * fix: compile error * remove two todo * dev: improve get_deref_target * check string during completion * feat: complete path arguments * feat: identify hash before function follows a content parameter * dev: complete text.size, text.dir, stack.dir, stroke dict * dev: add record type * dev: complete stroke dict * fix: correct kind of langauge of code tooltip * dev: add colon trigger character * dev: let type selection complete * dev: complete inset/outset/margin/radius dictionary types * dev: complete raw theme/syntaxes, bib path types * dev: complete all files at the same time * dev: update snapshot
This commit is contained in:
parent
76de22b676
commit
987a7da867
32 changed files with 1958 additions and 775 deletions
|
@ -1,4 +1,4 @@
|
|||
use crate::{prelude::*, SemanticRequest};
|
||||
use crate::{prelude::*, syntax::param_index_at_leaf, SemanticRequest};
|
||||
|
||||
/// The [`textDocument/signatureHelp`] request is sent from the client to the
|
||||
/// server to request signature information at a given cursor position.
|
||||
|
@ -95,65 +95,6 @@ fn surrounding_function_syntax<'b>(
|
|||
Some((callee, grand.find(callee.span())?, args))
|
||||
}
|
||||
|
||||
fn param_index_at_leaf(leaf: &LinkedNode, function: &Func, args: ast::Args) -> Option<usize> {
|
||||
let deciding = deciding_syntax(leaf);
|
||||
let params = function.params()?;
|
||||
let param_index = find_param_index(&deciding, params, args)?;
|
||||
trace!("got param index {param_index}");
|
||||
Some(param_index)
|
||||
}
|
||||
|
||||
/// Find the piece of syntax that decides what we're completing.
|
||||
fn deciding_syntax<'b>(leaf: &'b LinkedNode) -> LinkedNode<'b> {
|
||||
let mut deciding = leaf.clone();
|
||||
while !matches!(
|
||||
deciding.kind(),
|
||||
SyntaxKind::LeftParen | SyntaxKind::Comma | SyntaxKind::Colon
|
||||
) {
|
||||
let Some(prev) = deciding.prev_leaf() else {
|
||||
break;
|
||||
};
|
||||
deciding = prev;
|
||||
}
|
||||
deciding
|
||||
}
|
||||
|
||||
fn find_param_index(deciding: &LinkedNode, params: &[ParamInfo], args: ast::Args) -> Option<usize> {
|
||||
match deciding.kind() {
|
||||
// After colon: "func(param:|)", "func(param: |)".
|
||||
SyntaxKind::Colon => {
|
||||
let prev = deciding.prev_leaf()?;
|
||||
let param_ident = prev.cast::<ast::Ident>()?;
|
||||
params
|
||||
.iter()
|
||||
.position(|param| param.name == param_ident.as_str())
|
||||
}
|
||||
// Before: "func(|)", "func(hi|)", "func(12,|)".
|
||||
SyntaxKind::Comma | SyntaxKind::LeftParen => {
|
||||
let next = deciding.next_leaf();
|
||||
let following_param = next.as_ref().and_then(|next| next.cast::<ast::Ident>());
|
||||
match following_param {
|
||||
Some(next) => params
|
||||
.iter()
|
||||
.position(|param| param.named && param.name.starts_with(next.as_str())),
|
||||
None => {
|
||||
let positional_args_so_far = args
|
||||
.items()
|
||||
.filter(|arg| matches!(arg, ast::Arg::Pos(_)))
|
||||
.count();
|
||||
params
|
||||
.iter()
|
||||
.enumerate()
|
||||
.filter(|(_, param)| param.positional)
|
||||
.map(|(i, _)| i)
|
||||
.nth(positional_args_so_far)
|
||||
}
|
||||
}
|
||||
}
|
||||
_ => None,
|
||||
}
|
||||
}
|
||||
|
||||
fn markdown_docs(docs: &str) -> Documentation {
|
||||
Documentation::MarkupContent(MarkupContent {
|
||||
kind: MarkupKind::Markdown,
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue