diff --git a/src/completion/xquery-completion-item-provider.ts b/src/completion/xquery-completion-item-provider.ts new file mode 100644 index 0000000..d9d9941 --- /dev/null +++ b/src/completion/xquery-completion-item-provider.ts @@ -0,0 +1,51 @@ +import { CompletionItem, CompletionItemKind, CompletionItemProvider, Position, TextDocument } from "vscode"; + +const XQLint = require("xqlint").XQLint; + +export class XQueryCompletionItemProvider implements CompletionItemProvider { + + provideCompletionItems(document: TextDocument, position: Position): CompletionItem[] { + const completionItems = new Array(); + const linter = new XQLint(document.getText()); + + linter.getCompletions({ line: position.line, col: position.character }).forEach((x: any) => { + completionItems.push(this._getCompletionItem(x)); + }); + + return completionItems; + } + + private _getCompletionItem(xqLintCompletionItem: any): CompletionItem { + const completionItem = new CompletionItem(xqLintCompletionItem.name); + completionItem.insertText = xqLintCompletionItem.value; + + switch (xqLintCompletionItem.meta) { + // functions (always qualified with a colon) + case "function": + completionItem.kind = CompletionItemKind.Function; + + const funcStart = (xqLintCompletionItem.value.indexOf(":") + 1); + const funcEnd = xqLintCompletionItem.value.indexOf("("); + + completionItem.insertText = xqLintCompletionItem.value.substring(funcStart, funcEnd); + break; + + // variables and parameters (always qualified with a dollar sign) + case "Let binding": + case "Local variable": + case "Window variable": + case "Function parameter": + completionItem.kind = CompletionItemKind.Variable; + completionItem.insertText = xqLintCompletionItem.value.substring(1); + break; + + // everything else + default: + completionItem.kind = CompletionItemKind.Text; + break; + } + + return completionItem; + } + +} \ No newline at end of file diff --git a/src/extension.ts b/src/extension.ts index eb4fcb3..834d097 100644 --- a/src/extension.ts +++ b/src/extension.ts @@ -1,6 +1,7 @@ import { languages, window, workspace, commands } from "vscode"; import { ExtensionContext, TextEditor, TextEditorSelectionChangeEvent, WorkspaceConfiguration } from "vscode"; +import { XQueryCompletionItemProvider } from "./completion/xquery-completion-item-provider"; import { FormatAsXmlCommandName, formatAsXml } from "./formatting/commands/formatAsXml"; import { MinifyXmlCommandName, minifyXml } from "./formatting/commands/minifyXml"; import { XmlFormatterFactory } from "./formatting/xml-formatter"; @@ -12,6 +13,11 @@ import * as constants from "./constants"; export function activate(context: ExtensionContext) { const config = workspace.getConfiguration(constants.extensionPrefix); + /* Completion Features */ + context.subscriptions.push( + languages.registerCompletionItemProvider("xquery", new XQueryCompletionItemProvider(), ":", "$") + ); + /* Formatting Features */ const xmlFormattingEditProvider = new XmlFormattingEditProvider(config, XmlFormatterFactory.getXmlFormatter());