mirror of
https://github.com/typst/typst
synced 2025-05-14 04:56:26 +08:00
Scope completions for imports
This commit is contained in:
parent
71a21b7ec1
commit
72f4c543cc
@ -1743,21 +1743,17 @@ impl Eval for ast::ModuleImport<'_> {
|
||||
let new_name = self.new_name();
|
||||
let imports = self.imports();
|
||||
|
||||
let name = match &source {
|
||||
match &source {
|
||||
Value::Func(func) => {
|
||||
func.scope()
|
||||
.ok_or("cannot import from user-defined functions")
|
||||
.at(source_span)?;
|
||||
func.name().unwrap_or_default().into()
|
||||
if func.scope().is_none() {
|
||||
bail!(source_span, "cannot import from user-defined functions");
|
||||
}
|
||||
}
|
||||
Value::Type(ty) => ty.short_name().into(),
|
||||
Value::Type(_) => {}
|
||||
other => {
|
||||
let module = import(vm, other.clone(), source_span, true)?;
|
||||
let name = module.name().clone();
|
||||
source = Value::Module(module);
|
||||
name
|
||||
source = Value::Module(import(vm, other.clone(), source_span, true)?);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
if let Some(new_name) = &new_name {
|
||||
if let ast::Expr::Ident(ident) = self.source() {
|
||||
@ -1779,6 +1775,7 @@ impl Eval for ast::ModuleImport<'_> {
|
||||
None => {
|
||||
// Only import here if there is no rename.
|
||||
if new_name.is_none() {
|
||||
let name: EcoString = source.name().unwrap().into();
|
||||
vm.scopes.top.define(name, source);
|
||||
}
|
||||
}
|
||||
|
@ -168,6 +168,16 @@ impl Value {
|
||||
}
|
||||
}
|
||||
|
||||
/// The name, if this is a function, type, or module.
|
||||
pub fn name(&self) -> Option<&str> {
|
||||
match self {
|
||||
Self::Func(func) => func.name(),
|
||||
Self::Type(ty) => Some(ty.short_name()),
|
||||
Self::Module(module) => Some(module.name()),
|
||||
_ => None,
|
||||
}
|
||||
}
|
||||
|
||||
/// Try to extract documentation for the value.
|
||||
pub fn docs(&self) -> Option<&'static str> {
|
||||
match self {
|
||||
|
@ -1195,6 +1195,7 @@ impl<'a> CompletionContext<'a> {
|
||||
}
|
||||
|
||||
/// Add completions for definitions that are available at the cursor.
|
||||
///
|
||||
/// Filters the global/math scope with the given filter.
|
||||
fn scope_completions(&mut self, parens: bool, filter: impl Fn(&Value) -> bool) {
|
||||
let mut defined = BTreeSet::new();
|
||||
@ -1203,20 +1204,47 @@ impl<'a> CompletionContext<'a> {
|
||||
while let Some(node) = &ancestor {
|
||||
let mut sibling = Some(node.clone());
|
||||
while let Some(node) = &sibling {
|
||||
if let Some(v) = node.get().cast::<ast::LetBinding>() {
|
||||
if let Some(v) = node.cast::<ast::LetBinding>() {
|
||||
for ident in v.kind().idents() {
|
||||
defined.insert(ident.get());
|
||||
defined.insert(ident.get().clone());
|
||||
}
|
||||
}
|
||||
|
||||
if let Some(v) = node.cast::<ast::ModuleImport>() {
|
||||
let imports = v.imports();
|
||||
match imports {
|
||||
None | Some(ast::Imports::Wildcard) => {
|
||||
if let Some(value) = node
|
||||
.children()
|
||||
.find(|child| child.is::<ast::Expr>())
|
||||
.and_then(|source| analyze_import(self.world, &source))
|
||||
{
|
||||
if imports.is_none() {
|
||||
defined.extend(value.name().map(Into::into));
|
||||
} else if let Some(scope) = value.scope() {
|
||||
for (name, _) in scope.iter() {
|
||||
defined.insert(name.clone());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Some(ast::Imports::Items(items)) => {
|
||||
for item in items.iter() {
|
||||
defined.insert(item.bound_name().get().clone());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
sibling = node.prev_sibling();
|
||||
}
|
||||
|
||||
if let Some(parent) = node.parent() {
|
||||
if let Some(v) = parent.get().cast::<ast::ForLoop>() {
|
||||
if let Some(v) = parent.cast::<ast::ForLoop>() {
|
||||
if node.prev_sibling_kind() != Some(SyntaxKind::In) {
|
||||
let pattern = v.pattern();
|
||||
for ident in pattern.idents() {
|
||||
defined.insert(ident.get());
|
||||
defined.insert(ident.get().clone());
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1247,7 +1275,7 @@ impl<'a> CompletionContext<'a> {
|
||||
if !name.is_empty() {
|
||||
self.completions.push(Completion {
|
||||
kind: CompletionKind::Constant,
|
||||
label: name.clone(),
|
||||
label: name,
|
||||
apply: None,
|
||||
detail: None,
|
||||
});
|
||||
|
Loading…
x
Reference in New Issue
Block a user