diff --git a/package.json b/package.json index 6a914ae..78c6db3 100644 --- a/package.json +++ b/package.json @@ -54,19 +54,22 @@ "lint": "eslint src --ext ts" }, "devDependencies": { - "@types/vscode": "^1.72.0", "@types/glob": "^8.0.0", "@types/mocha": "^10.0.0", "@types/node": "16.x", + "@types/vscode": "^1.72.0", "@typescript-eslint/eslint-plugin": "^5.38.1", "@typescript-eslint/parser": "^5.38.1", + "@vscode/test-electron": "^2.1.5", "eslint": "^8.24.0", "glob": "^8.0.3", "mocha": "^10.0.0", - "typescript": "^4.8.4", "ts-loader": "^9.4.1", + "typescript": "^4.8.4", "webpack": "^5.74.0", - "webpack-cli": "^4.10.0", - "@vscode/test-electron": "^2.1.5" + "webpack-cli": "^4.10.0" + }, + "dependencies": { + "vscode-languageclient": "^8.0.2" } } diff --git a/src/completion.ts b/src/completion.ts deleted file mode 100644 index 3e50e94..0000000 --- a/src/completion.ts +++ /dev/null @@ -1,34 +0,0 @@ -// completion provider for feakin - -import * as vscode from "vscode"; -import * as fs from "fs"; - -export class FklCompletionItemProvider - implements vscode.CompletionItemProvider -{ - output: vscode.OutputChannel; - constructor(output: vscode.OutputChannel) { - this.output = output; - } - - public async provideCompletionItems( - document: vscode.TextDocument, - position: vscode.Position, - token: vscode.CancellationToken - ): Promise { - this.output.appendLine("provideCompletionItems:"); - this.output.appendLine(" document: " + document.fileName); - this.output.appendLine( - " position: " + position.line + ", " + position.character - ); - - return [ - { - label: "hello", - kind: vscode.CompletionItemKind.Text, - }, - ]; - - return []; - } -} diff --git a/src/extension.ts b/src/extension.ts index d8b1134..6bcbd3c 100644 --- a/src/extension.ts +++ b/src/extension.ts @@ -1,33 +1,62 @@ +import * as path from "node:path"; + // The module 'vscode' contains the VS Code extensibility API // Import the module and reference it with the alias vscode in your code below import * as vscode from "vscode"; - -import { FklCompletionItemProvider } from "./completion"; +import { + LanguageClient, + LanguageClientOptions, + ServerOptions, + TransportKind, +} from "vscode-languageclient/node"; let output: vscode.OutputChannel; -// This method is called when your extension is activated -// Your extension is activated the very first time the command is executed -export function activate(context: vscode.ExtensionContext) { - // The command has been defined in the package.json file - // Now provide the implementation of the command with registerCommand - // The commandId parameter must match the command field in package.json +export async function activate(context: vscode.ExtensionContext) { console.log("Congratulations, your extension 'fkl' is now active!"); output = vscode.window.createOutputChannel("Fkl", "fkl"); context.subscriptions.push(output); output.show(); - console.log("Fkl: activate" + context.extensionPath + " " + output); + let client; + + // TODO: download fkl-lsp from github + let exe = path.resolve(__dirname, "../../fklang/target/debug/fkl-lsp.exe"); + + // check if exe exists + try { + await vscode.workspace.fs.stat(vscode.Uri.file(exe)); + } catch (error) { + output.appendLine("fkl-lsp not found"); + return; + } + + const serverOptions: ServerOptions = { + run: { command: exe, transport: TransportKind.stdio }, + debug: { + command: exe, + transport: TransportKind.stdio, + }, + }; + + // Options to control the language client + let clientOptions: LanguageClientOptions = { + // Register the server for plain text documents + documentSelector: [{ scheme: "file", language: "fkl" }], + outputChannel: output, + progressOnInitialization: true, + traceOutputChannel: output, + synchronize: { + // Notify the server about file changes to '.clientrc files contained in the workspace + fileEvents: vscode.workspace.createFileSystemWatcher("**/*.fkl"), + }, + }; + + client = new LanguageClient("fkl-lsp-client", serverOptions, clientOptions); + client.start(); - context.subscriptions.push( - vscode.languages.registerCompletionItemProvider( - { pattern: "**/*.fkl", scheme: "file" }, - new FklCompletionItemProvider(output), - ".", - " " - ) - ); + context.subscriptions.push(client); } // This method is called when your extension is deactivated diff --git a/test_data/a.fkl b/test_data/a.fkl index 032e095..58ccafe 100644 --- a/test_data/a.fkl +++ b/test_data/a.fkl @@ -10,6 +10,7 @@ Context Reservation { Aggregate Reservation { Entity Ticket, Reservation; + } Entity Reservation { diff --git a/yarn.lock b/yarn.lock index 2380fa1..b940384 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1681,7 +1681,7 @@ schema-utils@^3.1.0, schema-utils@^3.1.1: ajv "^6.12.5" ajv-keywords "^3.5.2" -semver@^7.3.4, semver@^7.3.7: +semver@^7.3.4, semver@^7.3.5, semver@^7.3.7: version "7.3.8" resolved "https://registry.yarnpkg.com/semver/-/semver-7.3.8.tgz#07a78feafb3f7b32347d725e33de7e2a2df67798" integrity sha512-NB1ctGL5rlHrPJtFDVIVzTyQylMLu9N9VICA6HSFJo8MCGVTMW6gfpicwKmmK/dAjTOrqu5l63JJOpDSrAis3A== @@ -1902,6 +1902,33 @@ util-deprecate@~1.0.1: resolved "https://registry.yarnpkg.com/util-deprecate/-/util-deprecate-1.0.2.tgz#450d4dc9fa70de732762fbd2d4a28981419a0ccf" integrity sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw== +vscode-jsonrpc@8.0.2: + version "8.0.2" + resolved "https://registry.yarnpkg.com/vscode-jsonrpc/-/vscode-jsonrpc-8.0.2.tgz#f239ed2cd6004021b6550af9fd9d3e47eee3cac9" + integrity sha512-RY7HwI/ydoC1Wwg4gJ3y6LpU9FJRZAUnTYMXthqhFXXu77ErDd/xkREpGuk4MyYkk4a+XDWAMqe0S3KkelYQEQ== + +vscode-languageclient@^8.0.2: + version "8.0.2" + resolved "https://registry.yarnpkg.com/vscode-languageclient/-/vscode-languageclient-8.0.2.tgz#f1f23ce8c8484aa11e4b7dfb24437d3e59bb61c6" + integrity sha512-lHlthJtphG9gibGb/y72CKqQUxwPsMXijJVpHEC2bvbFqxmkj9LwQ3aGU9dwjBLqsX1S4KjShYppLvg1UJDF/Q== + dependencies: + minimatch "^3.0.4" + semver "^7.3.5" + vscode-languageserver-protocol "3.17.2" + +vscode-languageserver-protocol@3.17.2: + version "3.17.2" + resolved "https://registry.yarnpkg.com/vscode-languageserver-protocol/-/vscode-languageserver-protocol-3.17.2.tgz#beaa46aea06ed061576586c5e11368a9afc1d378" + integrity sha512-8kYisQ3z/SQ2kyjlNeQxbkkTNmVFoQCqkmGrzLH6A9ecPlgTbp3wDTnUNqaUxYr4vlAcloxx8zwy7G5WdguYNg== + dependencies: + vscode-jsonrpc "8.0.2" + vscode-languageserver-types "3.17.2" + +vscode-languageserver-types@3.17.2: + version "3.17.2" + resolved "https://registry.yarnpkg.com/vscode-languageserver-types/-/vscode-languageserver-types-3.17.2.tgz#b2c2e7de405ad3d73a883e91989b850170ffc4f2" + integrity sha512-zHhCWatviizPIq9B7Vh9uvrH6x3sK8itC84HkamnBWoDFJtzBf7SWlpLCZUit72b3os45h6RWQNC9xHRDF8dRA== + watchpack@^2.4.0: version "2.4.0" resolved "https://registry.yarnpkg.com/watchpack/-/watchpack-2.4.0.tgz#fa33032374962c78113f93c7f2fb4c54c9862a5d"