mirror of
https://github.com/Myriad-Dreamin/tinymist.git
synced 2025-07-23 12:45:04 +00:00
dev: complete labels with tolerating syntax error (#974)
This commit is contained in:
parent
00195884de
commit
2f882378bc
7 changed files with 42 additions and 31 deletions
|
@ -82,7 +82,7 @@ pub fn definition(
|
|||
find_bib_definition(ctx, introspector, name)
|
||||
.or_else(|| find_ref_definition(introspector, name, ref_expr))
|
||||
}
|
||||
DerefTarget::Normal(..) => None,
|
||||
DerefTarget::LabelError(..) | DerefTarget::Normal(..) => None,
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -9,6 +9,7 @@ use super::{
|
|||
TypeScheme, TypeVar,
|
||||
};
|
||||
use crate::syntax::{get_check_target, get_check_target_by_context, CheckTarget, ParamTarget};
|
||||
use crate::ty::BuiltinTy;
|
||||
|
||||
/// With given type information, check the type of a literal expression again by
|
||||
/// touching the possible related nodes.
|
||||
|
@ -306,11 +307,12 @@ impl<'a> PostTypeChecker<'a> {
|
|||
Some(resp.finalize())
|
||||
}
|
||||
CheckTarget::ImportPath(..) | CheckTarget::IncludePath(..) => Some(Ty::Builtin(
|
||||
crate::ty::BuiltinTy::Path(crate::ty::PathPreference::Source {
|
||||
BuiltinTy::Path(crate::ty::PathPreference::Source {
|
||||
allow_package: true,
|
||||
}),
|
||||
)),
|
||||
CheckTarget::Normal(target) => {
|
||||
CheckTarget::LabelError(..) => Some(Ty::Builtin(BuiltinTy::Label)),
|
||||
CheckTarget::Label(target) | CheckTarget::Normal(target) => {
|
||||
let ty = self.check_context_or(&target, context_ty)?;
|
||||
crate::log_debug_ct!("post check target normal: {ty:?}");
|
||||
Some(ty)
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
---
|
||||
source: crates/tinymist-query/src/completion.rs
|
||||
description: Completion on t (43..44)
|
||||
description: Completion on t (44..45)
|
||||
expression: "JsonRepr::new_pure(results)"
|
||||
input_file: crates/tinymist-query/src/fixtures/completion/complete_half_label.typ
|
||||
snapshot_kind: text
|
||||
|
@ -15,6 +15,7 @@ snapshot_kind: text
|
|||
"labelDetails": {
|
||||
"description": "H2"
|
||||
},
|
||||
"sortText": "001",
|
||||
"textEdit": {
|
||||
"newText": "test>",
|
||||
"range": {
|
||||
|
|
|
@ -48,7 +48,7 @@ pub(crate) fn find_references(
|
|||
) -> Option<Vec<LspLocation>> {
|
||||
let finding_label = match target {
|
||||
DerefTarget::VarAccess(..) | DerefTarget::Callee(..) => false,
|
||||
DerefTarget::Label(..) | DerefTarget::Ref(..) => true,
|
||||
DerefTarget::Label(..) | DerefTarget::LabelError(..) | DerefTarget::Ref(..) => true,
|
||||
DerefTarget::ImportPath(..) | DerefTarget::IncludePath(..) | DerefTarget::Normal(..) => {
|
||||
return None;
|
||||
}
|
||||
|
|
|
@ -291,6 +291,7 @@ pub(crate) fn interpret_mode_at(mut leaf: Option<&LinkedNode>) -> InterpretMode
|
|||
#[derive(Debug, Clone)]
|
||||
pub enum DerefTarget<'a> {
|
||||
Label(LinkedNode<'a>),
|
||||
LabelError(LinkedNode<'a>),
|
||||
Ref(LinkedNode<'a>),
|
||||
VarAccess(LinkedNode<'a>),
|
||||
Callee(LinkedNode<'a>),
|
||||
|
@ -302,18 +303,23 @@ pub enum DerefTarget<'a> {
|
|||
impl<'a> DerefTarget<'a> {
|
||||
pub fn node(&self) -> &LinkedNode<'a> {
|
||||
match self {
|
||||
DerefTarget::Label(node) => node,
|
||||
DerefTarget::Ref(node) => node,
|
||||
DerefTarget::VarAccess(node) => node,
|
||||
DerefTarget::Callee(node) => node,
|
||||
DerefTarget::ImportPath(node) => node,
|
||||
DerefTarget::IncludePath(node) => node,
|
||||
DerefTarget::Normal(_, node) => node,
|
||||
DerefTarget::Label(node)
|
||||
| DerefTarget::LabelError(node)
|
||||
| DerefTarget::Ref(node)
|
||||
| DerefTarget::VarAccess(node)
|
||||
| DerefTarget::Callee(node)
|
||||
| DerefTarget::ImportPath(node)
|
||||
| DerefTarget::IncludePath(node)
|
||||
| DerefTarget::Normal(_, node) => node,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn get_deref_target(node: LinkedNode, cursor: usize) -> Option<DerefTarget<'_>> {
|
||||
if matches!(node.kind(), SyntaxKind::Error) && node.text().starts_with('<') {
|
||||
return Some(DerefTarget::LabelError(node));
|
||||
}
|
||||
|
||||
/// Skips trivia nodes that are on the same line as the cursor.
|
||||
fn can_skip_trivia(node: &LinkedNode, cursor: usize) -> bool {
|
||||
// A non-trivia node is our target so we stop at it.
|
||||
|
@ -521,6 +527,8 @@ pub enum CheckTarget<'a> {
|
|||
},
|
||||
ImportPath(LinkedNode<'a>),
|
||||
IncludePath(LinkedNode<'a>),
|
||||
Label(LinkedNode<'a>),
|
||||
LabelError(LinkedNode<'a>),
|
||||
Normal(LinkedNode<'a>),
|
||||
}
|
||||
|
||||
|
@ -533,7 +541,9 @@ impl<'a> CheckTarget<'a> {
|
|||
ParamTarget::Named(node) => node.clone(),
|
||||
},
|
||||
CheckTarget::Paren { container, .. } => container.clone(),
|
||||
CheckTarget::ImportPath(node)
|
||||
CheckTarget::Label(node)
|
||||
| CheckTarget::LabelError(node)
|
||||
| CheckTarget::ImportPath(node)
|
||||
| CheckTarget::IncludePath(node)
|
||||
| CheckTarget::Normal(node) => node.clone(),
|
||||
})
|
||||
|
@ -607,6 +617,12 @@ pub fn get_check_target(node: LinkedNode) -> Option<CheckTarget<'_>> {
|
|||
DerefTarget::Callee(callee) => {
|
||||
return get_callee_target(callee, node);
|
||||
}
|
||||
DerefTarget::Label(node) => {
|
||||
return Some(CheckTarget::Label(node));
|
||||
}
|
||||
DerefTarget::LabelError(node) => {
|
||||
return Some(CheckTarget::LabelError(node));
|
||||
}
|
||||
DerefTarget::ImportPath(node) => {
|
||||
return Some(CheckTarget::ImportPath(node));
|
||||
}
|
||||
|
@ -868,7 +884,7 @@ mod tests {
|
|||
match kind {
|
||||
Some(DerefTarget::VarAccess(..)) => 'v',
|
||||
Some(DerefTarget::Normal(..)) => 'n',
|
||||
Some(DerefTarget::Label(..)) => 'l',
|
||||
Some(DerefTarget::Label(..) | DerefTarget::LabelError(..)) => 'l',
|
||||
Some(DerefTarget::Ref(..)) => 'r',
|
||||
Some(DerefTarget::Callee(..)) => 'c',
|
||||
Some(DerefTarget::ImportPath(..)) => 'i',
|
||||
|
@ -888,6 +904,7 @@ mod tests {
|
|||
Some(CheckTarget::Paren { .. }) => 'P',
|
||||
Some(CheckTarget::ImportPath(..)) => 'i',
|
||||
Some(CheckTarget::IncludePath(..)) => 'I',
|
||||
Some(CheckTarget::Label(..) | CheckTarget::LabelError(..)) => 'l',
|
||||
Some(CheckTarget::Normal(..)) => 'n',
|
||||
None => ' ',
|
||||
}
|
||||
|
|
|
@ -40,8 +40,7 @@ pub fn autocomplete(
|
|||
let _ = complete_comments(&mut ctx)
|
||||
|| complete_type_and_syntax(&mut ctx).is_none() && {
|
||||
crate::log_debug_ct!("continue after completing type and syntax");
|
||||
complete_labels(&mut ctx)
|
||||
|| complete_imports(&mut ctx)
|
||||
complete_imports(&mut ctx)
|
||||
|| complete_field_accesses(&mut ctx)
|
||||
|| complete_markup(&mut ctx)
|
||||
|| complete_math(&mut ctx)
|
||||
|
@ -495,20 +494,6 @@ fn field_access_completions(
|
|||
}
|
||||
}
|
||||
|
||||
/// Complete labels.
|
||||
fn complete_labels(ctx: &mut CompletionContext) -> bool {
|
||||
// A label anywhere in code: "(<la|".
|
||||
if (ctx.leaf.kind().is_error() && ctx.leaf.text().starts_with('<'))
|
||||
|| ctx.leaf.kind() == SyntaxKind::Label
|
||||
{
|
||||
ctx.from = ctx.leaf.offset() + 1;
|
||||
ctx.label_completions(false);
|
||||
return true;
|
||||
}
|
||||
|
||||
false
|
||||
}
|
||||
|
||||
/// Complete imports.
|
||||
fn complete_imports(ctx: &mut CompletionContext) -> bool {
|
||||
// On the colon marker of an import list:
|
||||
|
|
|
@ -1475,7 +1475,13 @@ pub(crate) fn complete_type_and_syntax(ctx: &mut CompletionContext) -> Option<()
|
|||
Some(CheckTarget::Normal(e)) if matches!(e.kind(), SyntaxKind::FieldAccess) => {
|
||||
return None;
|
||||
}
|
||||
Some(CheckTarget::Paren { .. } | CheckTarget::Normal(..)) | None => {}
|
||||
Some(
|
||||
CheckTarget::Paren { .. }
|
||||
| CheckTarget::Label(..)
|
||||
| CheckTarget::LabelError(..)
|
||||
| CheckTarget::Normal(..),
|
||||
)
|
||||
| None => {}
|
||||
}
|
||||
|
||||
crate::log_debug_ct!("ctx.leaf {:?}", ctx.leaf.clone());
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue