Skip to content
This repository has been archived by the owner on Apr 28, 2024. It is now read-only.

Commit

Permalink
feat(lsp): initial stub for server and client
Browse files Browse the repository at this point in the history
  • Loading branch information
nokome committed Apr 15, 2024
1 parent c195dce commit eb023d2
Show file tree
Hide file tree
Showing 4 changed files with 152 additions and 27 deletions.
70 changes: 63 additions & 7 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 4 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -81,5 +81,9 @@
"eslint": "^8.57.0",
"js-yaml": "^4.1.0",
"typescript": "^5.3.3"
},
"dependencies": {
"vscode-languageclient": "^9.0.1",
"vscode-languageserver": "^9.0.1"
}
}
77 changes: 57 additions & 20 deletions src/extension.ts
Original file line number Diff line number Diff line change
@@ -1,26 +1,63 @@
// 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 * as path from "path";

// 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) {
import * as vscode from "vscode";
import {
LanguageClient,
LanguageClientOptions,
ServerOptions,
TransportKind,
} from "vscode-languageclient/node";

let client: LanguageClient;

// Use the console to output diagnostic information (console.log) and errors (console.error)
// This line of code will only be executed once when your extension is activated
console.log('Congratulations, your extension "stencila" is now active!');
/**
* Activate the extension
*/
export function activate(context: vscode.ExtensionContext) {
// Use the console to output diagnostic information (console.log) and errors (console.error)
// This line of code will only be executed once when your extension is activated
console.log('Congratulations, your extension "stencila" is now active!');

// 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
let disposable = vscode.commands.registerCommand('stencila.helloWorld', () => {
// The code you place here will be executed every time your command is executed
// Display a message box to the user
vscode.window.showInformationMessage('Hello World from Stencila!');
});
// 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
let disposable = vscode.commands.registerCommand(
"stencila.helloWorld",
() => {
// The code you place here will be executed every time your command is executed
// Display a message box to the user
vscode.window.showInformationMessage("Hello World from Stencila!");
}
);
context.subscriptions.push(disposable);

context.subscriptions.push(disposable);
// Start the language server client
const serverModule = context.asAbsolutePath(path.join("out", "server.js"));
const serverOptions: ServerOptions = {
run: { module: serverModule, transport: TransportKind.ipc },
debug: {
module: serverModule,
transport: TransportKind.ipc,
},
};
const clientOptions: LanguageClientOptions = {
documentSelector: [{ scheme: "file", language: "smd" }],
};
client = new LanguageClient(
"stencila",
"Stencila",
serverOptions,
clientOptions
);
client.start();
}

// This method is called when your extension is deactivated
export function deactivate() {}
/**
* Deactivate the extension
*/
export function deactivate() {
if (!client) {
return undefined;
}
return client.stop();
}
28 changes: 28 additions & 0 deletions src/server.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
/**
* A module to run the Stencila language server from within Node.js
*
* Rather than bundling the Stencila CLI binary with this VSCode extension
* and spawning `stencila lsp` this script calls Stencila LSP functions
* exposed by the `@stencila/node` bindings. This has two main advantages:
*
* - distributing `@stencila/node` is easier than distributing `stencila` binaries
*
* - we can prototype interactions between VSCode and the Stencila language server
* i.e. event handlers in this module act as mocks for what the Rust-based
* language server function will implement
*/

import { createConnection } from "vscode-languageserver/node";

// Custom logging functions for better visibility in server outputs
const debug = (...args: any[]) => process.stderr.write(`DEBUG ${JSON.stringify(args)}`);
const info = (...args: any[]) => process.stderr.write(`INFO ${JSON.stringify(args)}`);
const warning = (...args: any[]) => process.stderr.write(`WARN ${JSON.stringify(args)}`);
const error = (...args: any[]) => process.stderr.write(`ERROR ${JSON.stringify(args)}`);

// Create a connection for the server, using Node's IPC as a transport.
const connection = createConnection();

// Listen on the connection
info("Listening on LSP connection");
connection.listen();

0 comments on commit eb023d2

Please sign in to comment.