1
1
mirror of https://github.com/oxalica/nil.git synced 2024-11-27 00:06:26 +03:00

Classify completion kinds

This commit is contained in:
oxalica 2022-08-09 06:44:09 +08:00
parent e222ab8363
commit 9ef631bb0c
4 changed files with 111 additions and 40 deletions

View File

@ -64,9 +64,12 @@ pub(crate) fn completion(
.into_iter()
.map(|item| {
let kind = match item.kind {
// FIXME: More specific?
CompletionItemKind::Builtin => lsp::CompletionItemKind::KEYWORD,
CompletionItemKind::Binding => lsp::CompletionItemKind::VARIABLE,
CompletionItemKind::Param => lsp::CompletionItemKind::VARIABLE,
CompletionItemKind::LetBinding => lsp::CompletionItemKind::VARIABLE,
CompletionItemKind::Field => lsp::CompletionItemKind::FIELD,
CompletionItemKind::BuiltinConst => lsp::CompletionItemKind::CONSTANT,
CompletionItemKind::BuiltinFunction => lsp::CompletionItemKind::FUNCTION,
CompletionItemKind::BuiltinAttrset => lsp::CompletionItemKind::CLASS,
};
CompletionItem {
label: item.label.into(),

View File

@ -1,4 +1,27 @@
pub static NAMES: phf::Set<&'static str> = phf::phf_set! {
macro_rules! def {
(__impl $name:tt) => {
Builtin {
name: $name,
is_hidden: true,
// Ignored.
kind: BuiltinKind::Function,
}
};
(__impl $name:tt $kind:tt) => {
Builtin {
name: $name,
is_hidden: false,
kind: BuiltinKind::$kind,
}
};
($($name:literal $(= $kind:tt)?,)*) => {
phf::phf_map! {
$($name => def!(__impl $name $($kind)?),)*
}
};
}
pub static BUILTINS: phf::Map<&'static str, Builtin> = def! {
"__addErrorContext",
"__all",
"__any",
@ -87,27 +110,41 @@ pub static NAMES: phf::Set<&'static str> = phf::phf_set! {
"__unsafeDiscardStringContext",
"__unsafeGetAttrPos",
"__zipAttrsWith",
"abort",
"baseNameOf",
"break",
"builtins",
"derivation",
"derivationStrict",
"dirOf",
"false",
"fetchGit",
"fetchMercurial",
"fetchTarball",
"fetchTree",
"fromTOML",
"import",
"isNull",
"map",
"null",
"placeholder",
"removeAttrs",
"scopedImport",
"throw",
"toString",
"true",
"abort" = Function,
"baseNameOf" = Function,
"break" = Function,
"builtins" = Attrset,
"derivation" = Function,
"derivationStrict" = Function,
"dirOf" = Function,
"false" = Const,
"fetchGit" = Function,
"fetchMercurial" = Function,
"fetchTarball" = Function,
"fetchTree" = Function,
"fromTOML" = Function,
"import" = Function,
"isNull" = Function,
"map" = Function,
"null" = Const,
"placeholder" = Function,
"removeAttrs" = Function,
"scopedImport" = Function,
"throw" = Function,
"toString" = Function,
"true" = Const,
};
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
pub struct Builtin {
pub name: &'static str,
pub is_hidden: bool,
pub kind: BuiltinKind,
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
pub enum BuiltinKind {
Const,
Function,
Attrset,
}

View File

@ -64,7 +64,7 @@ impl ModuleScopes {
return Some(ResolveResult::NameDef(*def));
}
// 2. Builtin names.
if let Some(name) = builtin::NAMES.get_key(name) {
if let Some(name) = builtin::BUILTINS.get_key(name) {
return Some(ResolveResult::Builtin(name));
}
// 3. "with" exprs.

View File

@ -1,4 +1,5 @@
use crate::def::{AstPtr, DefDatabase};
use crate::builtin::BuiltinKind;
use crate::def::{AstPtr, DefDatabase, NameDefKind};
use crate::{builtin, FileId};
use rowan::ast::AstNode;
use smol_str::SmolStr;
@ -20,8 +21,32 @@ pub struct CompletionItem {
/// The type of the completion item.
#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord)]
pub enum CompletionItemKind {
Builtin,
Binding,
Param,
LetBinding,
Field,
BuiltinConst,
BuiltinFunction,
BuiltinAttrset,
}
impl From<BuiltinKind> for CompletionItemKind {
fn from(k: BuiltinKind) -> Self {
match k {
BuiltinKind::Const => Self::BuiltinConst,
BuiltinKind::Function => Self::BuiltinFunction,
BuiltinKind::Attrset => Self::BuiltinAttrset,
}
}
}
impl From<NameDefKind> for CompletionItemKind {
fn from(k: NameDefKind) -> Self {
match k {
NameDefKind::LetIn => Self::LetBinding,
NameDefKind::RecAttrset => Self::Field,
NameDefKind::Param | NameDefKind::PatField => Self::Param,
}
}
}
pub(crate) fn completions(
@ -46,6 +71,7 @@ pub(crate) fn completions(
}
}
})?;
let module = db.module(file_id);
let source_map = db.source_map(file_id);
let expr_id = source_map.node_expr(AstPtr::new(ref_node.syntax()))?;
let scopes = db.scopes(file_id);
@ -55,19 +81,24 @@ pub(crate) fn completions(
let mut items = scopes
.ancestors(scope_id)
.filter_map(|scope| scope.as_name_defs())
.flat_map(|scope| scope.keys())
.map(|name| CompletionItem {
.flatten()
.map(|(name, &def)| CompletionItem {
label: name.clone(),
source_range,
replace: name.clone(),
kind: CompletionItemKind::Binding,
kind: module[def].kind.into(),
})
.chain(builtin::NAMES.iter().map(|name| CompletionItem {
label: name.into(),
source_range,
replace: name.into(),
kind: CompletionItemKind::Builtin,
}))
.chain(
builtin::BUILTINS
.values()
.filter(|b| !b.is_hidden)
.map(|b| CompletionItem {
label: b.name.into(),
source_range,
replace: b.name.into(),
kind: b.kind.into(),
}),
)
.collect::<Vec<_>>();
items.sort_by(|lhs, rhs| lhs.label.cmp(&rhs.label));
items.dedup_by(|lhs, rhs| lhs.label == rhs.label);