mirror of
https://github.com/Myriad-Dreamin/tinymist.git
synced 2025-08-03 09:52:27 +00:00
feat: go to definition of include paths (#156)
This commit is contained in:
parent
36eea552ac
commit
1c5c6bd929
7 changed files with 36 additions and 13 deletions
|
@ -200,6 +200,7 @@ impl<'a, 'b, 'w> DefUseCollector<'a, 'b, 'w> {
|
||||||
for e in e {
|
for e in e {
|
||||||
match &e.info.kind {
|
match &e.info.kind {
|
||||||
LexicalKind::Heading(..) => unreachable!(),
|
LexicalKind::Heading(..) => unreachable!(),
|
||||||
|
LexicalKind::Mod(LexicalModKind::PathInclude) => {}
|
||||||
LexicalKind::Var(LexicalVarKind::Label) => {
|
LexicalKind::Var(LexicalVarKind::Label) => {
|
||||||
self.insert(Ns::Label, e);
|
self.insert(Ns::Label, e);
|
||||||
}
|
}
|
||||||
|
|
|
@ -102,7 +102,7 @@ impl StatefulRequest for CompletionRequest {
|
||||||
match_ident = Some(v);
|
match_ident = Some(v);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Some(DerefTarget::ImportPath(v)) => {
|
Some(DerefTarget::ImportPath(v) | DerefTarget::IncludePath(v)) => {
|
||||||
if !v.text().starts_with(r#""@"#) {
|
if !v.text().starts_with(r#""@"#) {
|
||||||
completion_result = complete_path(ctx, v, &source, cursor);
|
completion_result = complete_path(ctx, v, &source, cursor);
|
||||||
}
|
}
|
||||||
|
|
|
@ -7,8 +7,8 @@ use typst::syntax::FileId as TypstFileId;
|
||||||
use crate::{
|
use crate::{
|
||||||
prelude::*,
|
prelude::*,
|
||||||
syntax::{
|
syntax::{
|
||||||
find_source_by_import, get_deref_target, DerefTarget, IdentRef, LexicalKind,
|
find_source_by_expr, get_deref_target, DerefTarget, IdentRef, LexicalKind, LexicalModKind,
|
||||||
LexicalModKind, LexicalVarKind,
|
LexicalVarKind,
|
||||||
},
|
},
|
||||||
SemanticRequest,
|
SemanticRequest,
|
||||||
};
|
};
|
||||||
|
@ -95,8 +95,8 @@ pub(crate) fn find_definition(
|
||||||
DerefTarget::ImportPath(path) => {
|
DerefTarget::ImportPath(path) => {
|
||||||
let parent = path.parent()?;
|
let parent = path.parent()?;
|
||||||
let def_fid = parent.span().id()?;
|
let def_fid = parent.span().id()?;
|
||||||
let e = parent.cast::<ast::ModuleImport>()?;
|
let import_node = parent.cast::<ast::ModuleImport>()?;
|
||||||
let source = find_source_by_import(ctx.world(), def_fid, e)?;
|
let source = find_source_by_expr(ctx.world(), def_fid, import_node.source())?;
|
||||||
return Some(DefinitionLink {
|
return Some(DefinitionLink {
|
||||||
kind: LexicalKind::Mod(LexicalModKind::PathVar),
|
kind: LexicalKind::Mod(LexicalModKind::PathVar),
|
||||||
name: String::new(),
|
name: String::new(),
|
||||||
|
@ -106,6 +106,20 @@ pub(crate) fn find_definition(
|
||||||
name_range: None,
|
name_range: None,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
DerefTarget::IncludePath(path) => {
|
||||||
|
let parent = path.parent()?;
|
||||||
|
let def_fid = parent.span().id()?;
|
||||||
|
let include_node = parent.cast::<ast::ModuleInclude>()?;
|
||||||
|
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
|
// syntatic definition
|
||||||
|
@ -177,6 +191,7 @@ pub(crate) fn find_definition(
|
||||||
| LexicalKind::Mod(
|
| LexicalKind::Mod(
|
||||||
LexicalModKind::Module(..)
|
LexicalModKind::Module(..)
|
||||||
| LexicalModKind::PathVar
|
| LexicalModKind::PathVar
|
||||||
|
| LexicalModKind::PathInclude
|
||||||
| LexicalModKind::ModuleAlias
|
| LexicalModKind::ModuleAlias
|
||||||
| LexicalModKind::Alias { .. }
|
| LexicalModKind::Alias { .. }
|
||||||
| LexicalModKind::Ident,
|
| LexicalModKind::Ident,
|
||||||
|
|
|
@ -48,7 +48,7 @@ pub(crate) fn find_references(
|
||||||
let node = match deref_target {
|
let node = match deref_target {
|
||||||
DerefTarget::VarAccess(node) => node,
|
DerefTarget::VarAccess(node) => node,
|
||||||
DerefTarget::Callee(node) => node,
|
DerefTarget::Callee(node) => node,
|
||||||
DerefTarget::ImportPath(..) => {
|
DerefTarget::ImportPath(..) | DerefTarget::IncludePath(..) => {
|
||||||
return None;
|
return None;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
|
@ -40,14 +40,13 @@ pub fn find_source_by_import_path(
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Find a source instance by its import node.
|
/// Find a source instance by its import node.
|
||||||
pub fn find_source_by_import(
|
pub fn find_source_by_expr(
|
||||||
world: &dyn World,
|
world: &dyn World,
|
||||||
current: TypstFileId,
|
current: TypstFileId,
|
||||||
import_node: ast::ModuleImport,
|
e: ast::Expr,
|
||||||
) -> Option<Source> {
|
) -> Option<Source> {
|
||||||
// todo: this could be vaild: import("path.typ"), where v is parenthesized
|
// todo: this could be vaild: import("path.typ"), where v is parenthesized
|
||||||
let v = import_node.source();
|
match e {
|
||||||
match v {
|
|
||||||
ast::Expr::Str(s) => find_source_by_import_path(world, current, s.get().as_str()),
|
ast::Expr::Str(s) => find_source_by_import_path(world, current, s.get().as_str()),
|
||||||
_ => None,
|
_ => None,
|
||||||
}
|
}
|
||||||
|
|
|
@ -75,6 +75,9 @@ pub enum LexicalModKind {
|
||||||
/// `import "foo.typ"`
|
/// `import "foo.typ"`
|
||||||
/// ^^^
|
/// ^^^
|
||||||
PathVar,
|
PathVar,
|
||||||
|
/// `include "foo.typ"`
|
||||||
|
/// ^^^
|
||||||
|
PathInclude,
|
||||||
/// `import "foo": bar`
|
/// `import "foo": bar`
|
||||||
/// ^^^
|
/// ^^^
|
||||||
Ident,
|
Ident,
|
||||||
|
|
|
@ -16,6 +16,7 @@ pub enum DerefTarget<'a> {
|
||||||
VarAccess(LinkedNode<'a>),
|
VarAccess(LinkedNode<'a>),
|
||||||
Callee(LinkedNode<'a>),
|
Callee(LinkedNode<'a>),
|
||||||
ImportPath(LinkedNode<'a>),
|
ImportPath(LinkedNode<'a>),
|
||||||
|
IncludePath(LinkedNode<'a>),
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a> DerefTarget<'a> {
|
impl<'a> DerefTarget<'a> {
|
||||||
|
@ -24,6 +25,7 @@ impl<'a> DerefTarget<'a> {
|
||||||
DerefTarget::VarAccess(node) => node,
|
DerefTarget::VarAccess(node) => node,
|
||||||
DerefTarget::Callee(node) => node,
|
DerefTarget::Callee(node) => node,
|
||||||
DerefTarget::ImportPath(node) => node,
|
DerefTarget::ImportPath(node) => node,
|
||||||
|
DerefTarget::IncludePath(node) => node,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -113,11 +115,14 @@ pub fn get_deref_target(node: LinkedNode, cursor: usize) -> Option<DerefTarget>
|
||||||
}
|
}
|
||||||
ast::Expr::Str(..) => {
|
ast::Expr::Str(..) => {
|
||||||
let parent = ancestor.parent()?;
|
let parent = ancestor.parent()?;
|
||||||
if parent.kind() != SyntaxKind::ModuleImport {
|
if parent.kind() == SyntaxKind::ModuleImport {
|
||||||
return None;
|
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(..) => {
|
ast::Expr::Import(..) => {
|
||||||
return None;
|
return None;
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue