134 lines
3.3 KiB
Plaintext
134 lines
3.3 KiB
Plaintext
// Completion provider for the ƿit LSP.
|
|
|
|
// CompletionItemKind constants (LSP spec)
|
|
def KIND_FUNCTION = 3
|
|
def KIND_VARIABLE = 6
|
|
def KIND_KEYWORD = 14
|
|
def KIND_CONSTANT = 21
|
|
|
|
// All intrinsic function names
|
|
def intrinsic_functions = [
|
|
"abs", "apply", "array", "ceiling", "character", "codepoint",
|
|
"ends_with", "every", "extract", "fallback", "filter", "find",
|
|
"floor", "format", "fraction",
|
|
"is_array", "is_blob", "is_character", "is_data", "is_digit",
|
|
"is_false", "is_fit", "is_function", "is_integer", "is_letter",
|
|
"is_logical", "is_lower", "is_null", "is_number", "is_object",
|
|
"is_pattern", "is_stone", "is_text", "is_true", "is_upper",
|
|
"is_whitespace",
|
|
"length", "logical", "lower", "max", "min", "modulo",
|
|
"neg", "normalize", "not", "number",
|
|
"parallel", "print", "race", "record", "reduce", "remainder",
|
|
"replace", "reverse", "round",
|
|
"search", "sequence", "sign", "some", "sort", "starts_with",
|
|
"stone", "text", "trim", "trunc", "upper", "whole",
|
|
"meme", "proto", "isa", "splat", "use"
|
|
]
|
|
|
|
// Keywords that can be completed
|
|
def keywords = [
|
|
"var", "def", "if", "else", "for", "while", "do",
|
|
"function", "return", "go", "break", "continue",
|
|
"disrupt", "disruption", "delete", "in", "this",
|
|
"null", "true", "false"
|
|
]
|
|
|
|
// Actor intrinsics (only in .ce files)
|
|
def actor_intrinsics = [
|
|
"$me", "$send", "$start", "$stop", "$delay",
|
|
"$receiver", "$clock", "$portal", "$contact",
|
|
"$couple", "$unneeded", "$connection", "$time_limit"
|
|
]
|
|
|
|
// Walk AST scopes to find variables visible at a position.
|
|
var collect_scope_vars = function(doc, line, col) {
|
|
var vars = []
|
|
var ast = doc.ast
|
|
var _i = 0
|
|
var _j = 0
|
|
var scope = null
|
|
var v = null
|
|
|
|
if (ast == null || ast.scopes == null) {
|
|
return vars
|
|
}
|
|
|
|
// Collect variables from all scopes (simplified: return all declared vars)
|
|
while (_i < length(ast.scopes)) {
|
|
scope = ast.scopes[_i]
|
|
if (scope.vars != null) {
|
|
_j = 0
|
|
while (_j < length(scope.vars)) {
|
|
v = scope.vars[_j]
|
|
if (v.name != null) {
|
|
vars[] = {
|
|
label: v.name,
|
|
kind: (v.is_const == true) ? KIND_CONSTANT : KIND_VARIABLE,
|
|
detail: (v.is_const == true) ? "def" : "var"
|
|
}
|
|
}
|
|
_j = _j + 1
|
|
}
|
|
}
|
|
_i = _i + 1
|
|
}
|
|
|
|
return vars
|
|
}
|
|
|
|
// Provide completions for a document at a position.
|
|
var complete = function(doc, line, col) {
|
|
var items = []
|
|
var _i = 0
|
|
var is_actor = ends_with(doc.uri, ".ce")
|
|
|
|
// Intrinsic functions
|
|
_i = 0
|
|
while (_i < length(intrinsic_functions)) {
|
|
items[] = {
|
|
label: intrinsic_functions[_i],
|
|
kind: KIND_FUNCTION,
|
|
detail: "intrinsic"
|
|
}
|
|
_i = _i + 1
|
|
}
|
|
|
|
// Keywords
|
|
_i = 0
|
|
while (_i < length(keywords)) {
|
|
items[] = {
|
|
label: keywords[_i],
|
|
kind: KIND_KEYWORD,
|
|
detail: "keyword"
|
|
}
|
|
_i = _i + 1
|
|
}
|
|
|
|
// Actor intrinsics (only for .ce files)
|
|
if (is_actor) {
|
|
_i = 0
|
|
while (_i < length(actor_intrinsics)) {
|
|
items[] = {
|
|
label: actor_intrinsics[_i],
|
|
kind: KIND_FUNCTION,
|
|
detail: "actor intrinsic"
|
|
}
|
|
_i = _i + 1
|
|
}
|
|
}
|
|
|
|
// Variables from scope analysis
|
|
var scope_vars = collect_scope_vars(doc, line, col)
|
|
_i = 0
|
|
while (_i < length(scope_vars)) {
|
|
items[] = scope_vars[_i]
|
|
_i = _i + 1
|
|
}
|
|
|
|
return items
|
|
}
|
|
|
|
return {
|
|
complete: complete
|
|
}
|