Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add multi language server support #48

Merged
merged 8 commits into from
Jun 19, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 13 additions & 5 deletions .vscode/launch.json
Original file line number Diff line number Diff line change
Expand Up @@ -34,13 +34,21 @@
}
},
{
"name": "Attach to Server",
"name": "Attach to Native Server",
"type": "node",
"request": "attach",
"port": 6009,
"restart": true,
"sourceMapPathOverrides": {
"webpack://?:*/*": "${workspaceFolder}/server/*"
"webpack://?:*/*": "${workspaceFolder}/server/gx-workflow-ls-native/*"
}
},
{
"name": "Attach to gxformat2 Server",
"type": "node",
"request": "attach",
"port": 6010,
"sourceMapPathOverrides": {
"webpack://?:*/*": "${workspaceFolder}/server/gx-workflow-ls-format2/*"
}
},
{
Expand Down Expand Up @@ -74,8 +82,8 @@
],
"compounds": [
{
"name": "Debug Extension + Server",
"configurations": ["Launch Extension", "Attach to Server"],
"name": "Debug Extension + Servers",
"configurations": ["Launch Extension", "Attach to Native Server", "Attach to gxformat2 Server"],
"presentation": {
"hidden": false,
"group": "",
Expand Down
3 changes: 2 additions & 1 deletion .vscode/settings.json
Original file line number Diff line number Diff line change
Expand Up @@ -11,5 +11,6 @@
"editor.codeActionsOnSave": {
"source.fixAll.eslint": true
},
"gitlens.advanced.blame.customArguments": ["--ignore-revs-file", ".git-blame-ignore-revs"]
"gitlens.advanced.blame.customArguments": ["--ignore-revs-file", ".git-blame-ignore-revs"],
"typescript.tsdk": "node_modules/typescript/lib"
}
24 changes: 16 additions & 8 deletions client/src/browser/extension.ts
Original file line number Diff line number Diff line change
@@ -1,21 +1,29 @@
import { ExtensionContext, Uri } from "vscode";
import { LanguageClientOptions } from "vscode-languageclient";
import { LanguageClient } from "vscode-languageclient/browser";
import { buildLanguageClientOptions, initExtension } from "../common";
import { buildBasicLanguageClientOptions, initExtension } from "../common";
import { Constants } from "../common/constants";

export function activate(context: ExtensionContext): void {
const client = buildWebLanguageClient(context);
const nativeLanguageClient = createWebWorkerLanguageClient(
Constants.NATIVE_WORKFLOW_LANGUAGE_ID,
Uri.joinPath(context.extensionUri, "server/gx-workflow-ls-native/dist/web/nativeServer.js")
);
const gxFormat2LanguageClient = createWebWorkerLanguageClient(
Constants.GXFORMAT2_WORKFLOW_LANGUAGE_ID,
Uri.joinPath(context.extensionUri, "server/gx-workflow-ls-format2/dist/web/gxFormat2Server.js")
);

initExtension(context, client);
initExtension(context, nativeLanguageClient, gxFormat2LanguageClient);
}

export function deactivate(): void {
// Nothing to do yet
}

function buildWebLanguageClient(context: ExtensionContext): LanguageClient {
const clientOptions: LanguageClientOptions = buildLanguageClientOptions();
const serverPath = Uri.joinPath(context.extensionUri, "server/dist/web/nativeServer.js");
const worker = new Worker(serverPath.toString());
return new LanguageClient("galaxy-workflow-language-client-native", "Galaxy Workflows LS", clientOptions, worker);
function createWebWorkerLanguageClient(languageId: string, serverUri: Uri): LanguageClient {
const documentSelector = [{ language: languageId }];
const clientOptions: LanguageClientOptions = buildBasicLanguageClientOptions(documentSelector);
const worker = new Worker(serverUri.toString());
return new LanguageClient(`${languageId}-language-client`, `Galaxy Workflows (${languageId})`, clientOptions, worker);
}
4 changes: 2 additions & 2 deletions client/src/commands/cleanWorkflow.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { window } from "vscode";
import { CleanWorkflowDocumentParams, CleanWorkflowDocumentRequest } from "../requestsDefinitions";
import { CustomCommand, getCommandFullIdentifier } from "./common";
import { CleanWorkflowDocumentParams, CleanWorkflowDocumentRequest } from "../common/requestsDefinitions";
import { CustomCommand, getCommandFullIdentifier } from ".";

/**
* Command to 'clean' the selected workflow document.
Expand Down
4 changes: 2 additions & 2 deletions client/src/commands/compareCleanWith.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,8 @@ import { commands, Uri } from "vscode";
import { CommonLanguageClient } from "vscode-languageclient";
import { toCleanWorkflowUri } from "../providers/cleanWorkflowDocumentProvider";
import { CleanWorkflowProvider } from "../providers/cleanWorkflowProvider";
import { addRefToUri } from "../utils";
import { ComparableWorkflow, ComparableWorkflowProvider, CustomCommand, getCommandFullIdentifier } from "./common";
import { addRefToUri } from "../common/utils";
import { ComparableWorkflow, ComparableWorkflowProvider, CustomCommand, getCommandFullIdentifier } from ".";

/**
* Compares (diff) a previously selected workflow document revision with
Expand Down
File renamed without changes.
2 changes: 1 addition & 1 deletion client/src/commands/previewCleanWorkflow.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { window, workspace } from "vscode";
import { toCleanWorkflowUri } from "../providers/cleanWorkflowDocumentProvider";
import { CustomCommand, getCommandFullIdentifier } from "./common";
import { CustomCommand, getCommandFullIdentifier } from ".";

/**
* Command to display a 'clean' version of the selected workflow document.
Expand Down
2 changes: 1 addition & 1 deletion client/src/commands/selectForCleanCompare.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { commands } from "vscode";
import { ComparableWorkflow, ComparableWorkflowProvider, CustomCommand, getCommandFullIdentifier } from "./common";
import { ComparableWorkflow, ComparableWorkflowProvider, CustomCommand, getCommandFullIdentifier } from ".";

/**
* Command to select a workflow for comparison with another. This workflow will
Expand Down
2 changes: 1 addition & 1 deletion client/src/commands/setup.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import { CompareCleanWithWorkflowsCommand } from "./compareCleanWith";
import { SelectForCleanCompareCommand } from "./selectForCleanCompare";
import { PreviewCleanWorkflowCommand } from "./previewCleanWorkflow";
import { CleanWorkflowProvider } from "../providers/cleanWorkflowProvider";
import { GitProvider } from "../providers/git/common";
import { GitProvider } from "../providers/git";
import { CleanWorkflowCommand } from "./cleanWorkflow";

/**
Expand Down
43 changes: 0 additions & 43 deletions client/src/common.ts

This file was deleted.

1 change: 1 addition & 0 deletions client/src/constants.ts → client/src/common/constants.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
/* eslint-disable @typescript-eslint/no-namespace */
export namespace Constants {
export const NATIVE_WORKFLOW_LANGUAGE_ID = "galaxyworkflow";
export const GXFORMAT2_WORKFLOW_LANGUAGE_ID = "gxformat2";
export const CLEAN_WORKFLOW_DOCUMENT_SCHEME = "galaxy-clean-workflow";
}
56 changes: 56 additions & 0 deletions client/src/common/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
import { commands, ExtensionContext } from "vscode";
import { CommonLanguageClient, DocumentSelector, LanguageClientOptions } from "vscode-languageclient";
import { setupCommands } from "../commands/setup";
import { CleanWorkflowDocumentProvider } from "../providers/cleanWorkflowDocumentProvider";
import { CleanWorkflowProvider } from "../providers/cleanWorkflowProvider";
import { GitProvider } from "../providers/git";
import { BuiltinGitProvider } from "../providers/git/gitProvider";

export function buildBasicLanguageClientOptions(documentSelector: DocumentSelector): LanguageClientOptions {
// Options to control the language client
const clientOptions: LanguageClientOptions = {
documentSelector,
synchronize: {},
initializationOptions: {},
};
return clientOptions;
}

export function initExtension(
context: ExtensionContext,
nativeClient: CommonLanguageClient,
gxFormat2Client: CommonLanguageClient
): void {
const gitProvider = initGitProvider(context);

// Setup native workflow language features
setupProviders(context, nativeClient, gitProvider);
setupCommands(context, nativeClient, gitProvider);
startLanguageClient(context, nativeClient);

// Setup gxformat2 language features
startLanguageClient(context, gxFormat2Client);
}

function initGitProvider(context: ExtensionContext): BuiltinGitProvider {
const gitProvider = new BuiltinGitProvider();
gitProvider.initialize().then(() => {
commands.executeCommand("setContext", "galaxy-workflows.gitProviderInitialized", gitProvider.isInitialized);
console.log(`${context.extension.id} Git initialized is ${gitProvider.isInitialized}.`);
});
return gitProvider;
}

function startLanguageClient(context: ExtensionContext, languageClient: CommonLanguageClient): void {
const disposable = languageClient.start();
context.subscriptions.push(disposable);

languageClient.onReady().then(() => {
console.log(`${context.extension.id} ${languageClient.outputChannel.name} server is ready.`);
});
}

function setupProviders(context: ExtensionContext, client: CommonLanguageClient, gitProvider: GitProvider): void {
const cleanWorkflowProvider = new CleanWorkflowProvider(client, gitProvider);
CleanWorkflowDocumentProvider.register(context, cleanWorkflowProvider);
}
File renamed without changes.
48 changes: 35 additions & 13 deletions client/src/extension.ts
Original file line number Diff line number Diff line change
@@ -1,36 +1,58 @@
import * as path from "path";
import { ExtensionContext } from "vscode";
import { LanguageClientOptions } from "vscode-languageclient";
import { integer, LanguageClientOptions } from "vscode-languageclient";
import { LanguageClient, ServerOptions, TransportKind } from "vscode-languageclient/node";
import { buildLanguageClientOptions, initExtension } from "./common";
import { buildBasicLanguageClientOptions, initExtension } from "./common";
import { Constants } from "./common/constants";

export function activate(context: ExtensionContext): void {
const client = buildLanguageClient(context);
const nativeLanguageClient = buildNodeLanguageClient(
Constants.NATIVE_WORKFLOW_LANGUAGE_ID,
buildNativeServerOptions(context)
);
const gxFormat2LanguageClient = buildNodeLanguageClient(
Constants.GXFORMAT2_WORKFLOW_LANGUAGE_ID,
buildGxFormat2ServerOptions(context)
);

initExtension(context, client);
initExtension(context, nativeLanguageClient, gxFormat2LanguageClient);
}

export function deactivate(): void {
// Nothing to do yet
}

function buildLanguageClient(context: ExtensionContext): LanguageClient {
const clientOptions: LanguageClientOptions = buildLanguageClientOptions();
const serverOptions: ServerOptions = buildServerOptions(context);
function buildNodeLanguageClient(languageId: string, serverOptions: ServerOptions): LanguageClient {
const documentSelector = [{ language: languageId }];
const clientOptions: LanguageClientOptions = buildBasicLanguageClientOptions(documentSelector);
return new LanguageClient(
"galaxy-workflow-language-client-native",
"Galaxy Workflows LS",
`${languageId}-language-client`,
`Galaxy Workflows (${languageId})`,
serverOptions,
clientOptions
);
}

function buildServerOptions(context: ExtensionContext): ServerOptions {
function buildNativeServerOptions(context: ExtensionContext): ServerOptions {
// The server is implemented in node
const serverModule = context.asAbsolutePath(path.join("server", "gx-workflow-ls-native", "dist", "nativeServer.js"));
const debugPort = 6009;
return buildBasicNodeServerOptions(serverModule, debugPort);
}

function buildGxFormat2ServerOptions(context: ExtensionContext): ServerOptions {
// The server is implemented in node
const serverModule = context.asAbsolutePath(path.join("server", "dist", "nativeServer.js"));
const serverModule = context.asAbsolutePath(
path.join("server", "gx-workflow-ls-format2", "dist", "gxFormat2Server.js")
);
const debugPort = 6010;
return buildBasicNodeServerOptions(serverModule, debugPort);
}

function buildBasicNodeServerOptions(serverModule: string, debugPort: integer): ServerOptions {
// The debug options for the server
// --inspect=6009: runs the server in Node's Inspector mode so VS Code can attach to the server for debugging
const debugOptions = { execArgv: ["--nolazy", "--inspect=6009"] };
// --inspect=<port>: runs the server in Node's Inspector mode so VS Code can attach to the server for debugging
const debugOptions = { execArgv: ["--nolazy", `--inspect=${debugPort}`] };

// If the extension is launched in debug mode then the debug server options are used
// Otherwise the run options are used
Expand Down
2 changes: 1 addition & 1 deletion client/src/providers/cleanWorkflowDocumentProvider.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { EventEmitter, ExtensionContext, TextDocumentContentProvider, Uri, workspace } from "vscode";
import { Constants } from "../constants";
import { Constants } from "../common/constants";
import { CleanWorkflowProvider } from "./cleanWorkflowProvider";

/**
Expand Down
6 changes: 3 additions & 3 deletions client/src/providers/cleanWorkflowProvider.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
import { Uri, window, workspace } from "vscode";
import { CommonLanguageClient } from "vscode-languageclient";
import { CleanWorkflowContentsParams, CleanWorkflowContentsRequest } from "../requestsDefinitions";
import { getWorkspaceScheme, replaceUriScheme } from "../utils";
import { GitProvider } from "./git/common";
import { CleanWorkflowContentsParams, CleanWorkflowContentsRequest } from "../common/requestsDefinitions";
import { getWorkspaceScheme, replaceUriScheme } from "../common/utils";
import { GitProvider } from "./git";

/**
* Provides utilities to clean (remove non-workflow logic related parts)
Expand Down
2 changes: 1 addition & 1 deletion client/src/providers/git/gitProvider.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { Extension, extensions, Uri } from "vscode";
import { GitExtension, API as GitAPI } from "../../@types/git";
import { GitProvider } from "./common";
import { GitProvider } from ".";

/**
* Implementation of a GitProvider using the `vscode.git` extension.
Expand Down
File renamed without changes.
4 changes: 2 additions & 2 deletions package-lock.json

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

17 changes: 12 additions & 5 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@
{
"id": "galaxyworkflow",
"aliases": [
"Galaxy Workflow"
"Galaxy Workflow (JSON)"
],
"extensions": [
".ga"
Expand All @@ -58,7 +58,7 @@
{
"id": "gxformat2",
"aliases": [
"Galaxy Workflow"
"Galaxy Workflow (YAML)"
],
"extensions": [
".yml",
Expand Down Expand Up @@ -204,15 +204,16 @@
},
"scripts": {
"postinstall": "cd client && npm install && cd ../server && npm install && cd ..",
"lint": "eslint ./client/src ./server/src --ext .ts,.tsx",
"lint": "eslint ./client/src ./server --ext .ts,.tsx",
"format": "prettier --write .",
"clean": "rimraf client/dist && rimraf server/dist",
"compile": "npm run clean && webpack --config ./client/webpack.config.js && webpack --config ./server/webpack.config.js",
"compile-servers": "cd server && npm run compile",
"compile": "npm run clean && webpack --config ./client/webpack.config.js && npm run compile-servers",
"vscode:prepublish": "npm run compile",
"watch": "concurrently --kill-others \"npm run watch-server\" \"npm run watch-client\"",
"watch-server": "cd server && npm run watch",
"watch-client": "cd client && npm run watch",
"test": "jest",
"test": "npm run test-unit-client && npm run test-unit-server",
"test-unit-client": "cd client && npm run test-unit && cd ..",
"test-unit-server": "cd server && npm run test-unit && cd ..",
"test-compile": "tsc --project ./client --outDir client/out",
Expand Down Expand Up @@ -244,5 +245,11 @@
"typescript": "^4.6.3",
"webpack": "^5.72.0",
"webpack-cli": "^4.9.2"
},
"__metadata": {
"id": "2306ad21-fa2c-46f9-bba8-a22e32c7cb9a",
"publisherDisplayName": "davelopez",
"publisherId": "b10132ef-3f96-4db4-acb0-d6a0ca1848c7",
"isPreReleaseVersion": false
}
}
Loading