diff --git a/src/bundleTypes.ts b/src/bundleTypes.ts new file mode 100644 index 000000000..6a6b62b00 --- /dev/null +++ b/src/bundleTypes.ts @@ -0,0 +1,5 @@ +export interface YAMLLanguageServerBundle { + name: string; + version: string; + commandFunctions: Map; +} diff --git a/src/languageservice/bundleCommandManager.ts b/src/languageservice/bundleCommandManager.ts new file mode 100644 index 000000000..03b61561c --- /dev/null +++ b/src/languageservice/bundleCommandManager.ts @@ -0,0 +1,23 @@ +import { ExecuteCommandParams } from 'vscode-languageserver'; + +export class BundleCommandManager { + + private commands = new Map(); + + registerCommand(name: string, action: Function) { + this.commands.set(name, action); + } + + /** + * Execute a registered command if found + * @param e the ExecuteCommandParams you want to use + */ + executeCommand(e: ExecuteCommandParams): any { + const com = this.commands.get(e.command); + if (com) { + return com.apply(e.arguments); + } + return null; + } + +} diff --git a/src/server.ts b/src/server.ts index d87390fed..99c493dbe 100755 --- a/src/server.ts +++ b/src/server.ts @@ -52,6 +52,7 @@ import { isRelativePath, relativeToAbsolutePath, workspaceFoldersChanged } from import { URI } from 'vscode-uri'; import { KUBERNETES_SCHEMA_URL, JSON_SCHEMASTORE_URL } from './languageservice/utils/schemaUrls'; import { schemaRequestHandler } from './languageservice/services/schemaRequestHandler'; +import { BundleCommandManager } from './languageservice/bundleCommandManager'; // eslint-disable-next-line @typescript-eslint/no-explicit-any nls.config(process.env['VSCODE_NLS_CONFIG'] as any); @@ -103,6 +104,7 @@ interface JSONSchemaSettings { ****************/ // Language server configuration +const commandManager = new BundleCommandManager(); let yamlConfigurationSettings: JSONSchemaSettings[] = undefined; let schemaAssociations: ISchemaAssociations | SchemaConfiguration[] | undefined = undefined; let formatterRegistration: Thenable = null; @@ -417,6 +419,24 @@ connection.onInitialize( capabilities.textDocument.rangeFormatting.dynamicRegistration ); hasWorkspaceFolderCapability = capabilities.workspace && !!capabilities.workspace.workspaceFolders; + + // Path to an array of javascript bundles + const bundlePath = params.initializationOptions?.bundles ? params.initializationOptions.bundles : []; + + // The commands you want run on the server side + const serverCommands = []; + + // register everything with the command manager and gather server side commands + for (const path of bundlePath) { + const bundle = require(path) as YAMLLanguageServerBundle; + const cmdsFunctions = bundle.commandFunctions; + if (cmdsFunctions) { + cmdsFunctions.forEach((action: Function, commandID: string) => { + commandManager.registerCommand(commandID, action); + serverCommands.push(commandID); + }); + } + } return { capabilities: { textDocumentSync: documents.syncKind, @@ -432,6 +452,9 @@ connection.onInitialize( supported: true, }, }, + executeCommandProvider: { + commands: serverCommands + } }, }; } @@ -679,5 +702,9 @@ connection.onRequest(SchemaModificationNotification.type, (modifications: Schema return Promise.resolve(); }); +connection.onExecuteCommand(e => { + return commandManager.executeCommand(e); +}); + // Start listening for any messages from the client connection.listen();