"use strict";
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
    if (k2 === undefined) k2 = k;
    var desc = Object.getOwnPropertyDescriptor(m, k);
    if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
      desc = { enumerable: true, get: function() { return m[k]; } };
    }
    Object.defineProperty(o, k2, desc);
}) : (function(o, m, k, k2) {
    if (k2 === undefined) k2 = k;
    o[k2] = m[k];
}));
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
    Object.defineProperty(o, "default", { enumerable: true, value: v });
}) : function(o, v) {
    o["default"] = v;
});
var __importStar = (this && this.__importStar) || (function () {
    var ownKeys = function(o) {
        ownKeys = Object.getOwnPropertyNames || function (o) {
            var ar = [];
            for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
            return ar;
        };
        return ownKeys(o);
    };
    return function (mod) {
        if (mod && mod.__esModule) return mod;
        var result = {};
        if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
        __setModuleDefault(result, mod);
        return result;
    };
})();
Object.defineProperty(exports, "__esModule", { value: true });
exports.NexusCompletionItemProvider = void 0;
const vscode = __importStar(require("vscode"));
const KEYWORD_ITEMS = [
    {
        label: "let",
        kind: vscode.CompletionItemKind.Keyword,
        detail: "Variable declaration",
        insertText: new vscode.SnippetString("let ${1:name} = ${2:value};"),
    },
    {
        label: "let mut",
        kind: vscode.CompletionItemKind.Keyword,
        detail: "Mutable binding",
        insertText: new vscode.SnippetString("let mut ${1:name} = ${2:value};"),
    },
    {
        label: "fn",
        kind: vscode.CompletionItemKind.Keyword,
        detail: "Function literal",
        insertText: new vscode.SnippetString("fn(${1:params}) {\n\t${2:return ${3:0};}\n}"),
    },
    {
        label: "enum",
        kind: vscode.CompletionItemKind.Keyword,
        detail: "Algebraic data type",
        insertText: new vscode.SnippetString("enum ${1:Name} {\n\t${2:Variant},\n\t${3:Other}(${4:x})\n}"),
    },
    {
        label: "match",
        kind: vscode.CompletionItemKind.Keyword,
        detail: "Exhaustive pattern match",
        insertText: new vscode.SnippetString("match ${1:value} {\n\t${2:Pattern} => { $0 },\n}"),
    },
    {
        label: "struct",
        kind: vscode.CompletionItemKind.Keyword,
        detail: "Struct type",
        insertText: new vscode.SnippetString("struct ${1:Name} {\n\t${2:field}: ${3:int}\n}"),
    },
    {
        label: "effect",
        kind: vscode.CompletionItemKind.Keyword,
        detail: "Algebraic effect",
        insertText: new vscode.SnippetString("effect ${1:IO} {\n\t${2:print}(${3:msg})\n}"),
    },
    {
        label: "perform",
        kind: vscode.CompletionItemKind.Keyword,
        detail: "Perform an effect operation",
        insertText: new vscode.SnippetString("perform ${1:IO}::${2:print}(${3:args})"),
    },
    {
        label: "handle",
        kind: vscode.CompletionItemKind.Keyword,
        detail: "Handle effect operations",
        insertText: new vscode.SnippetString("handle {\n\t$1\n} with ${2:IO} {\n\t${3:print}(${4:msg}) => { resume($5); }\n}"),
    },
    {
        label: "region",
        kind: vscode.CompletionItemKind.Keyword,
        detail: "Lexical memory region",
        insertText: new vscode.SnippetString("region ${1:r} {\n\t$0\n}"),
    },
    {
        label: "async",
        kind: vscode.CompletionItemKind.Keyword,
        detail: "Async block / function",
        insertText: new vscode.SnippetString("async {\n\t$0\n}"),
    },
    {
        label: "await",
        kind: vscode.CompletionItemKind.Keyword,
        detail: "Await a promise",
        insertText: new vscode.SnippetString("await ${1:expr}"),
    },
    {
        label: "spawn",
        kind: vscode.CompletionItemKind.Keyword,
        detail: "Spawn green task",
        insertText: new vscode.SnippetString("spawn ${1:expr}"),
    },
    {
        label: "chan",
        kind: vscode.CompletionItemKind.Keyword,
        detail: "Message channel",
        insertText: new vscode.SnippetString("chan(${1:0})"),
    },
    {
        label: "macro rules!",
        kind: vscode.CompletionItemKind.Snippet,
        detail: "Hygienic macro",
        insertText: new vscode.SnippetString("macro rules! ${1:name} {\n\t($${2:x}:expr) => { $0 }\n}"),
    },
    {
        label: "&mut",
        kind: vscode.CompletionItemKind.Keyword,
        detail: "Mutable borrow",
        insertText: new vscode.SnippetString("&mut ${1:name}"),
    },
    {
        label: "move",
        kind: vscode.CompletionItemKind.Keyword,
        detail: "Explicit move",
        insertText: new vscode.SnippetString("move ${1:name}"),
    },
    {
        label: "reflect",
        kind: vscode.CompletionItemKind.Function,
        detail: "Compile-time / runtime type reflection",
        insertText: new vscode.SnippetString("reflect(${1:Type})"),
    },
    {
        label: "return",
        kind: vscode.CompletionItemKind.Keyword,
        detail: "Return from a function",
        insertText: new vscode.SnippetString("return ${1:value};"),
    },
    {
        label: "if",
        kind: vscode.CompletionItemKind.Keyword,
        detail: "Conditional expression",
        insertText: new vscode.SnippetString("if (${1:condition}) {\n\t$0\n}"),
    },
    {
        label: "else",
        kind: vscode.CompletionItemKind.Keyword,
        detail: "Alternate branch",
        insertText: new vscode.SnippetString("else {\n\t$0\n}"),
    },
    {
        label: "true",
        kind: vscode.CompletionItemKind.Constant,
        detail: "Boolean true",
    },
    {
        label: "false",
        kind: vscode.CompletionItemKind.Constant,
        detail: "Boolean false",
    },
    {
        label: "puts",
        kind: vscode.CompletionItemKind.Function,
        detail: "Builtin: print values",
        insertText: new vscode.SnippetString("puts(${1:value})"),
    },
    {
        label: "fs_read",
        kind: vscode.CompletionItemKind.Function,
        detail: "Std: read file",
        insertText: new vscode.SnippetString("fs_read(${1:path})"),
    },
    {
        label: "sha256",
        kind: vscode.CompletionItemKind.Function,
        detail: "Std: SHA-256 hash",
        insertText: new vscode.SnippetString("sha256(${1:text})"),
    },
    {
        label: "net_fetch",
        kind: vscode.CompletionItemKind.Function,
        detail: "Std: HTTP fetch",
        insertText: new vscode.SnippetString("net_fetch(${1:url})"),
    },
    {
        label: "spawn_task",
        kind: vscode.CompletionItemKind.Function,
        detail: "Std: spawn task",
        insertText: new vscode.SnippetString("spawn_task(${1:fn})"),
    },
];
class NexusCompletionItemProvider {
    provideCompletionItems(document, position, _token, _context) {
        const linePrefix = document
            .lineAt(position)
            .text.slice(0, position.character);
        if (isInsideString(linePrefix)) {
            return [];
        }
        const wordRange = document.getWordRangeAtPosition(position, /[A-Za-z_][A-Za-z0-9_]*/);
        return KEYWORD_ITEMS.map((item) => {
            const completion = new vscode.CompletionItem(item.label, item.kind);
            completion.detail = item.detail;
            completion.documentation = item.documentation
                ? new vscode.MarkdownString(item.documentation)
                : undefined;
            completion.insertText = item.insertText ?? item.label;
            if (wordRange) {
                completion.range = wordRange;
            }
            return completion;
        });
    }
}
exports.NexusCompletionItemProvider = NexusCompletionItemProvider;
function isInsideString(linePrefix) {
    let inString = false;
    let escaped = false;
    for (const ch of linePrefix) {
        if (escaped) {
            escaped = false;
            continue;
        }
        if (ch === "\\") {
            escaped = true;
            continue;
        }
        if (ch === '"') {
            inString = !inString;
        }
    }
    return inString;
}
//# sourceMappingURL=completions.js.map