diff --git a/crates/tinymist-query/src/analysis/def_use.rs b/crates/tinymist-query/src/analysis/def_use.rs index 55c114ea..5a156a92 100644 --- a/crates/tinymist-query/src/analysis/def_use.rs +++ b/crates/tinymist-query/src/analysis/def_use.rs @@ -200,6 +200,7 @@ impl<'a, 'b, 'w> DefUseCollector<'a, 'b, 'w> { for e in e { match &e.info.kind { LexicalKind::Heading(..) => unreachable!(), + LexicalKind::Mod(LexicalModKind::PathInclude) => {} LexicalKind::Var(LexicalVarKind::Label) => { self.insert(Ns::Label, e); } diff --git a/crates/tinymist-query/src/completion.rs b/crates/tinymist-query/src/completion.rs index f40f1d03..55250960 100644 --- a/crates/tinymist-query/src/completion.rs +++ b/crates/tinymist-query/src/completion.rs @@ -102,7 +102,7 @@ impl StatefulRequest for CompletionRequest { match_ident = Some(v); } } - Some(DerefTarget::ImportPath(v)) => { + Some(DerefTarget::ImportPath(v) | DerefTarget::IncludePath(v)) => { if !v.text().starts_with(r#""@"#) { completion_result = complete_path(ctx, v, &source, cursor); } diff --git a/crates/tinymist-query/src/goto_definition.rs b/crates/tinymist-query/src/goto_definition.rs index f16adee5..6f02bccb 100644 --- a/crates/tinymist-query/src/goto_definition.rs +++ b/crates/tinymist-query/src/goto_definition.rs @@ -7,8 +7,8 @@ use typst::syntax::FileId as TypstFileId; use crate::{ prelude::*, syntax::{ - find_source_by_import, get_deref_target, DerefTarget, IdentRef, LexicalKind, - LexicalModKind, LexicalVarKind, + find_source_by_expr, get_deref_target, DerefTarget, IdentRef, LexicalKind, LexicalModKind, + LexicalVarKind, }, SemanticRequest, }; @@ -95,8 +95,8 @@ pub(crate) fn find_definition( DerefTarget::ImportPath(path) => { let parent = path.parent()?; let def_fid = parent.span().id()?; - let e = parent.cast::()?; - let source = find_source_by_import(ctx.world(), def_fid, e)?; + let import_node = parent.cast::()?; + let source = find_source_by_expr(ctx.world(), def_fid, import_node.source())?; return Some(DefinitionLink { kind: LexicalKind::Mod(LexicalModKind::PathVar), name: String::new(), @@ -106,6 +106,20 @@ pub(crate) fn find_definition( name_range: None, }); } + DerefTarget::IncludePath(path) => { + let parent = path.parent()?; + let def_fid = parent.span().id()?; + let include_node = parent.cast::()?; + let source = find_source_by_expr(ctx.world(), def_fid, include_node.source())?; + return Some(DefinitionLink { + kind: LexicalKind::Mod(LexicalModKind::PathInclude), + name: String::new(), + value: None, + fid: source.id(), + def_range: (LinkedNode::new(source.root())).range(), + name_range: None, + }); + } }; // syntatic definition @@ -177,6 +191,7 @@ pub(crate) fn find_definition( | LexicalKind::Mod( LexicalModKind::Module(..) | LexicalModKind::PathVar + | LexicalModKind::PathInclude | LexicalModKind::ModuleAlias | LexicalModKind::Alias { .. } | LexicalModKind::Ident, diff --git a/crates/tinymist-query/src/references.rs b/crates/tinymist-query/src/references.rs index d406a468..60b4ea87 100644 --- a/crates/tinymist-query/src/references.rs +++ b/crates/tinymist-query/src/references.rs @@ -48,7 +48,7 @@ pub(crate) fn find_references( let node = match deref_target { DerefTarget::VarAccess(node) => node, DerefTarget::Callee(node) => node, - DerefTarget::ImportPath(..) => { + DerefTarget::ImportPath(..) | DerefTarget::IncludePath(..) => { return None; } }; diff --git a/crates/tinymist-query/src/syntax/import.rs b/crates/tinymist-query/src/syntax/import.rs index 68c51000..f2b76011 100644 --- a/crates/tinymist-query/src/syntax/import.rs +++ b/crates/tinymist-query/src/syntax/import.rs @@ -40,14 +40,13 @@ pub fn find_source_by_import_path( } /// Find a source instance by its import node. -pub fn find_source_by_import( +pub fn find_source_by_expr( world: &dyn World, current: TypstFileId, - import_node: ast::ModuleImport, + e: ast::Expr, ) -> Option { // todo: this could be vaild: import("path.typ"), where v is parenthesized - let v = import_node.source(); - match v { + match e { ast::Expr::Str(s) => find_source_by_import_path(world, current, s.get().as_str()), _ => None, } diff --git a/crates/tinymist-query/src/syntax/lexical_hierarchy.rs b/crates/tinymist-query/src/syntax/lexical_hierarchy.rs index 2c64e431..3889693e 100644 --- a/crates/tinymist-query/src/syntax/lexical_hierarchy.rs +++ b/crates/tinymist-query/src/syntax/lexical_hierarchy.rs @@ -75,6 +75,9 @@ pub enum LexicalModKind { /// `import "foo.typ"` /// ^^^ PathVar, + /// `include "foo.typ"` + /// ^^^ + PathInclude, /// `import "foo": bar` /// ^^^ Ident, diff --git a/crates/tinymist-query/src/syntax/matcher.rs b/crates/tinymist-query/src/syntax/matcher.rs index 54053cba..3582eccb 100644 --- a/crates/tinymist-query/src/syntax/matcher.rs +++ b/crates/tinymist-query/src/syntax/matcher.rs @@ -16,6 +16,7 @@ pub enum DerefTarget<'a> { VarAccess(LinkedNode<'a>), Callee(LinkedNode<'a>), ImportPath(LinkedNode<'a>), + IncludePath(LinkedNode<'a>), } impl<'a> DerefTarget<'a> { @@ -24,6 +25,7 @@ impl<'a> DerefTarget<'a> { DerefTarget::VarAccess(node) => node, DerefTarget::Callee(node) => node, DerefTarget::ImportPath(node) => node, + DerefTarget::IncludePath(node) => node, } } } @@ -113,11 +115,14 @@ pub fn get_deref_target(node: LinkedNode, cursor: usize) -> Option } ast::Expr::Str(..) => { let parent = ancestor.parent()?; - if parent.kind() != SyntaxKind::ModuleImport { - return None; + if parent.kind() == SyntaxKind::ModuleImport { + return Some(DerefTarget::ImportPath(ancestor.find(may_ident.span())?)); + } + if parent.kind() == SyntaxKind::ModuleInclude { + return Some(DerefTarget::IncludePath(ancestor.find(may_ident.span())?)); } - return Some(DerefTarget::ImportPath(ancestor.find(may_ident.span())?)); + return None; } ast::Expr::Import(..) => { return None;