vscode-languageclient/node#ServerOptions TypeScript Examples
The following examples show how to use
vscode-languageclient/node#ServerOptions.
You can vote up the ones you like or vote down the ones you don't like,
and go to the original project or source file by following the links above each example. You may check out the related API usage on the sidebar.
Example #1
Source File: dafnyLanguageClient.ts From ide-vscode with MIT License | 6 votes |
public static async create(context: ExtensionContext, statusOutput: OutputChannel): Promise<DafnyLanguageClient> {
const { path: dotnetExecutable } = await getDotnetExecutablePath();
const launchArguments = [ getLanguageServerRuntimePath(context), ...getLanguageServerLaunchArgs() ];
statusOutput.appendLine(`Language server arguments: ${DafnyLanguageClient.argumentsToCommandLine(launchArguments)}`);
const serverOptions: ServerOptions = {
run: { command: dotnetExecutable, args: launchArguments },
debug: { command: dotnetExecutable, args: launchArguments }
};
const diagnosticsListeners: ((uri: Uri, diagnostics: Diagnostic[]) => void)[] = [];
const clientOptions: LanguageClientOptions = {
documentSelector: [ DafnyDocumentFilter ],
diagnosticCollectionName: LanguageServerId,
middleware: {
handleDiagnostics: (uri: Uri, diagnostics: Diagnostic[], next: HandleDiagnosticsSignature) => {
for(const handler of diagnosticsListeners) {
handler(uri, diagnostics);
}
next(uri, diagnostics);
}
}
};
return new DafnyLanguageClient(LanguageServerId, LanguageServerName, serverOptions, clientOptions, diagnosticsListeners);
}
Example #2
Source File: languageServerClient.ts From vscode-stripe with MIT License | 6 votes |
static async startStandardServer(
context: ExtensionContext,
clientOptions: LanguageClientOptions,
serverOptions: ServerOptions,
outputChannel: OutputChannel,
telemetry: Telemetry,
) {
if (standardClient.getClientStatus() !== ClientStatus.Uninitialized) {
return;
}
const checkConflicts: boolean = await hasNoBuildToolConflict(context);
if (!checkConflicts) {
outputChannel.appendLine(
`Build tool conflict detected in workspace. Please enable either maven (${IMPORT_MAVEN}) or gradle (${IMPORT_GRADLE}) in user settings.`,
);
telemetry.sendEvent('standardJavaServerHasBuildToolConflict');
return;
}
if (javaServerMode === ServerMode.LIGHTWEIGHT) {
// Before standard server is ready, we are in hybrid.
javaServerMode = ServerMode.HYBRID;
}
await standardClient.initialize(clientOptions, serverOptions);
standardClient.start();
outputChannel.appendLine('Java language service (standard) is running.');
telemetry.sendEvent('standardJavaServerStarted');
}
Example #3
Source File: languageServerClient.ts From vscode-stripe with MIT License | 6 votes |
static async startSyntaxServer(
clientOptions: LanguageClientOptions,
serverOptions: ServerOptions,
outputChannel: OutputChannel,
telemetry: Telemetry,
) {
await syntaxClient.initialize(clientOptions, serverOptions);
syntaxClient.start();
outputChannel.appendLine('Java language service (syntax) is running.');
telemetry.sendEvent('syntaxJavaServerStarted');
}
Example #4
Source File: languageServerClient.ts From vscode-stripe with MIT License | 6 votes |
static activateUniversalServer(
context: ExtensionContext,
outputChannel: OutputChannel,
serverOptions: ServerOptions,
telemetry: Telemetry,
) {
outputChannel.appendLine('Starting universal language server');
const universalClientOptions: LanguageClientOptions = {
// Register the server for stripe-supported languages. dotnet is not yet supported.
documentSelector: [
{scheme: 'file', language: 'javascript'},
{scheme: 'file', language: 'typescript'},
{scheme: 'file', language: 'go'},
// {scheme: 'file', language: 'java'},
{scheme: 'file', language: 'php'},
{scheme: 'file', language: 'python'},
{scheme: 'file', language: 'ruby'},
],
synchronize: {
fileEvents: workspace.createFileSystemWatcher('**/.clientrc'),
},
};
const universalClient = new LanguageClient(
'stripeLanguageServer',
'Stripe Language Server',
serverOptions,
universalClientOptions,
);
universalClient.onTelemetry((data: any) => {
const eventData = data.data || null;
telemetry.sendEvent(data.name, eventData);
});
universalClient.start();
outputChannel.appendLine('Universal language server is running');
telemetry.sendEvent('universalLanguageServerStarted');
}
Example #5
Source File: languageServerClient.ts From vscode-stripe with MIT License | 6 votes |
static async activate(
context: ExtensionContext,
serverOptions: ServerOptions,
telemetry: Telemetry,
) {
const outputChannel = window.createOutputChannel('Stripe Language Client');
// start the csharp server if this is a dotnet project
const dotnetProjectFile = await this.getDotnetProjectFiles();
if (dotnetProjectFile.length > 0) {
this.activateDotNetServer(context, outputChannel, dotnetProjectFile[0], telemetry);
return;
}
// start the java server if this is a java project
const javaFiles = await this.getJavaProjectFiles();
if (javaFiles.length > 0) {
const jdkInfo = await getJavaSDKInfo(context, outputChannel);
if (jdkInfo.javaVersion < REQUIRED_JDK_VERSION) {
outputChannel.appendLine(
`Minimum JDK version required for Java API Reference at code hover is ${REQUIRED_JDK_VERSION}. Please update the ${STRIPE_JAVA_HOME} variable in user settings.`,
);
telemetry.sendEvent('doesNotMeetRequiredJdkVersion');
return;
}
this.activateJavaServer(context, jdkInfo, outputChannel, javaFiles, telemetry);
return;
}
// start the universal server for all other languages
this.activateUniversalServer(context, outputChannel, serverOptions, telemetry);
}
Example #6
Source File: lsp.ts From vscode-sql-notebook with MIT License | 6 votes |
start(config: LspConfig) {
let serverOptions: ServerOptions = {
command: config.binPath,
args: [],
};
let clientOptions: LanguageClientOptions = {
documentSelector: [{ language: 'sql' }],
initializationOptions: {
disableCodeAction: true,
connectionConfig: {
driver: config.driver,
user: config.user,
passwd: config.password,
host: config.host,
port: config.port,
dbName: config.database,
proto: 'tcp',
},
},
outputChannel: vscode.window.createOutputChannel('sqls'),
};
this.client = new LanguageClient('sqls', serverOptions, clientOptions);
this.client.start();
}
Example #7
Source File: extension.ts From zls-vscode with MIT License | 5 votes |
export function activate(context: ExtensionContext) {
const zlsPath = workspace.getConfiguration('zigLanguageClient').get('path', '');
const debugLog = workspace.getConfiguration('zigLanguageClient').get('debugLog', false);
if (!zlsPath) {
window.showErrorMessage("Failed to find zls executable! Please specify its path in your settings with `zigLanguageClient.path`.");
return;
}
let serverOptions: ServerOptions = {
command: zlsPath,
args: debugLog ? [ "--debug-log" ] : []
};
// Options to control the language client
let clientOptions: LanguageClientOptions = {
documentSelector: [{ scheme: 'file', language: 'zig' }],
outputChannel: window.createOutputChannel("Zig Language Server")
};
// Create the language client and start the client.
client = new LanguageClient(
'zigLanguageClient',
'Zig Language Server Client',
serverOptions,
clientOptions
);
client.start();
vscode.commands.registerCommand("zls.start", () => {
client.start();
});
vscode.commands.registerCommand("zls.stop", async () => {
await client.stop();
});
vscode.commands.registerCommand("zls.restart", async () => {
await client.stop();
client.start();
});
}
Example #8
Source File: extension.ts From svlangserver with MIT License | 5 votes |
export function activate(context: ExtensionContext) {
let serverModule = context.asAbsolutePath(path.join('dist', 'svlangserver.js'));
let serverOptions: ServerOptions = {
run: {module: serverModule, transport: TransportKind.ipc},
debug: {module: serverModule, transport: TransportKind.ipc}
}
let clientOptions: LanguageClientOptions = {
outputChannelName: "SVLangServer",
documentSelector: selector as string[]
}
client = new LanguageClient('systemverilog', "svlangserver LSP", serverOptions, clientOptions);
// For debugging only
//client.trace = Trace.Verbose;
let getHierCmdHandler = () => {
let selectedText: string;
let editor = window.activeTextEditor;
if (!!editor) {
selectedText = editor.document.getText(editor.selection);
}
window.showInputBox({
placeHolder: "Module/interface Name",
prompt: "Hierarchy to be reported for module/interface",
value: selectedText
}).then((cntnrName: string) => {
if (!!cntnrName) {
client.sendRequest('workspace/executeCommand', {'command': 'systemverilog.report_hierarchy', 'arguments': [cntnrName]});
}
});
};
context.subscriptions.push(commands.registerCommand('systemverilog.get_hierarchy', getHierCmdHandler));
context.subscriptions.push(client.start());
client.onReady().then(() => {
workspace.onDidChangeConfiguration(() => {
client.sendNotification('workspace/didChangeConfiguration', getSettings(client));
});
});
}
Example #9
Source File: extension.ts From vscode-css-variables with MIT License | 5 votes |
export function activate(context: ExtensionContext) {
// The server is implemented in node
const serverModule = context.asAbsolutePath(
path.join('server', 'out', 'server.js')
);
// 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'] };
// If the extension is launched in debug mode then the debug server options are used
// Otherwise the run options are used
const serverOptions: ServerOptions = {
run: { module: serverModule, transport: TransportKind.ipc },
debug: {
module: serverModule,
transport: TransportKind.ipc,
options: debugOptions,
},
};
// Options to control the language client
const clientOptions: LanguageClientOptions = {
// Register the server for plain text documents
documentSelector: [
'onLanguage:svelte',
'onLanguage:vue',
'onLanguage:vue-html',
'onLanguage:vue-postcss',
'onLanguage:scss',
'onLanguage:postcss',
'onLanguage:less',
'onLanguage:css',
'onLanguage:html',
'onLanguage:javascript',
'onLanguage:javascriptreact',
'onLanguage:typescript',
'onLanguage:typescriptreact',
'onLanguage:source.css.styled',
].map((event) => ({
scheme: 'file',
language: event.split(':')[1],
})),
synchronize: {
// Notify the server about file changes to '.clientrc files contained in the workspace
fileEvents: [
workspace.createFileSystemWatcher('**/*.css'),
workspace.createFileSystemWatcher('**/*.scss'),
workspace.createFileSystemWatcher('**/*.sass'),
workspace.createFileSystemWatcher('**/*.less'),
],
},
};
// Create the language client and start the client.
client = new LanguageClient(
'cssVariables',
'CSS Variables Language Server',
serverOptions,
clientOptions
);
// Start the client. This will also launch the server
client.start();
}
Example #10
Source File: client.ts From vala-vscode with MIT License | 5 votes |
constructor(_context: ExtensionContext) {
this.config = workspace.getConfiguration('vala', window.activeTextEditor?.document.uri);
let serverModule = this.languageServerPath;
if (serverModule == null)
return;
let clientOptions: LanguageClientOptions = {
documentSelector: ['vala', 'genie'],
revealOutputChannelOn: RevealOutputChannelOn.Info
};
// default environment in non-debug mode
let runEnvironment = { ...process.env };
if (this.config.debugMode)
runEnvironment['G_MESSAGES_DEBUG'] = 'all';
if (this.config.failOnCriticals)
runEnvironment['G_DEBUG'] = 'fatal-criticals';
let serverOptions: ServerOptions = {
run: {
command: serverModule,
transport: TransportKind.stdio,
options: {
env: runEnvironment
}
},
debug: {
command: serverModule,
options: {
env: {
...process.env,
G_MESSAGES_DEBUG: 'all'
}
},
transport: TransportKind.stdio
}
};
this.ls = new LanguageClient('Vala Language Server', serverOptions, clientOptions);
commands.registerTextEditorCommand('vala.showBaseSymbol', this.peekSymbol);
commands.registerTextEditorCommand('vala.showHiddenSymbol', this.peekSymbol);
this.ls.start();
}
Example #11
Source File: extension.ts From vscode-teal with MIT License | 5 votes |
export function activate(context: ExtensionContext) {
// The server is implemented in node
let serverModule = context.asAbsolutePath(path.join('out', 'server', 'server.js'));
// 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
let debugOptions = { execArgv: ['--nolazy', '--inspect=6009'] };
// If the extension is launched in debug mode then the debug server options are used
// Otherwise the run options are used
let serverOptions: ServerOptions = {
run: { module: serverModule, transport: TransportKind.ipc },
debug: {
module: serverModule,
transport: TransportKind.ipc,
options: debugOptions
}
};
// Options to control the language client
let clientOptions: LanguageClientOptions = {
// Register the server for .tl files and tlconfig.lua
documentSelector: [
{ scheme: 'file', language: 'teal' },
{ scheme: 'file', language: 'lua', pattern: '**/tlconfig.lua' }
],
synchronize: {
// Notify the server about file changes to .tl and .lua files contained in the workspace
fileEvents: workspace.createFileSystemWatcher('**/*.{tl,lua}')
},
outputChannelName: 'Teal Language Server'
};
// Create the language client and start the client.
client = new LanguageClient(
'TealLanguageServer',
'Teal Language Server',
serverOptions,
clientOptions
);
// Start the client. This will also launch the server
client.start();
}
Example #12
Source File: extension.ts From language-tools with MIT License | 5 votes |
function createLanguageServer(serverOptions: ServerOptions, clientOptions: LanguageClientOptions) {
return new LanguageClient('svelte', 'Svelte', serverOptions, clientOptions);
}
Example #13
Source File: syntaxLanguageClient.ts From vscode-stripe with MIT License | 5 votes |
public initialize(
clientOptions: LanguageClientOptions,
serverOptions: ServerOptions,
) {
if (!serverOptions) {
return;
}
const newClientOptions: LanguageClientOptions = Object.assign({}, clientOptions, {
errorHandler: {
error: (error: string, message: string) => {
console.log(message);
console.log(error);
return ErrorAction.Continue;
},
closed: () => CloseAction.DoNotRestart,
},
});
this.languageClient = new LanguageClient(
'java',
EXTENSION_NAME_SYNTAX,
serverOptions,
newClientOptions,
);
this.languageClient.onReady().then(() => {
if (this.languageClient) {
this.languageClient.onNotification(StatusNotification.type, (report: {type: any}) => {
switch (report.type) {
case 'Started':
this.status = ClientStatus.Started;
break;
case 'Error':
this.status = ClientStatus.Error;
break;
default:
break;
}
});
}
});
this.status = ClientStatus.Initialized;
}
Example #14
Source File: standardLanguageClient.ts From vscode-stripe with MIT License | 5 votes |
public initialize(
clientOptions: LanguageClientOptions,
serverOptions: ServerOptions,
) {
if (!serverOptions || this.status !== ClientStatus.Uninitialized) {
return;
}
this.languageClient = new LanguageClient(
'java',
EXTENSION_NAME_STANDARD,
serverOptions,
clientOptions,
);
this.languageClient.onReady().then(() => {
if (!this.languageClient) {
return;
}
this.languageClient.onNotification(StatusNotification.type, (report: StatusReport) => {
switch (report.type) {
case 'ServiceReady':
updateServerMode(ServerMode.STANDARD);
break;
case 'Started':
this.status = ClientStatus.Started;
break;
case 'Error':
this.status = ClientStatus.Error;
break;
case 'Starting':
case 'Message':
// message goes to progress report instead
break;
}
});
});
this.status = ClientStatus.Initialized;
}
Example #15
Source File: dafnyLanguageClient.ts From ide-vscode with MIT License | 5 votes |
// eslint-disable-next-line max-params
private constructor(id: string, name: string, serverOptions: ServerOptions, clientOptions: LanguageClientOptions, diagnosticsListeners: DiagnosticListener[], forceDebug?: boolean) {
super(id, name, serverOptions, clientOptions, forceDebug);
this.diagnosticsListeners = diagnosticsListeners;
}
Example #16
Source File: extension.ts From fower with MIT License | 5 votes |
export function activate(context: ExtensionContext) {
// The server is implemented in node
const serverModule = context.asAbsolutePath(path.join('server', 'out', 'server.js'))
// The debug options for the server
const debugOptions = { execArgv: ['--nolazy', '--inspect=6011'] }
// If the extension is launched in debug mode then the debug server options are used
// Otherwise the run options are used
const serverOptions: ServerOptions = {
run: { module: serverModule, transport: TransportKind.ipc },
debug: {
module: serverModule,
transport: TransportKind.ipc,
options: debugOptions,
},
}
// Options to control the language client
const clientOptions: LanguageClientOptions = {
// Register the server for plain text documents
// documentSelector: [{ scheme: 'file', language: 'plaintext' }],
documentSelector: [
{ scheme: 'file', language: 'vue' },
{
scheme: 'file',
language: 'svelte',
},
],
middleware: {
provideCompletionItem: async (document, position, context, token, next) => {
return await next(document, position, context, token)
},
},
synchronize: {
// Notify the server about file changes to '.clientrc files contained in the workspace
fileEvents: workspace.createFileSystemWatcher('**/.clientrc'),
},
}
// Create the language client and start the client.
client = new LanguageClient(CLIENT_ID, CLIENT_NAME, serverOptions, clientOptions)
// Start the client. This will also launch the server
client.start()
}
Example #17
Source File: client.ts From coffeesense with MIT License | 5 votes |
export function initializeLanguageClient(lspModulePath: string): LanguageClient {
const debugOptions = { execArgv: ['--nolazy', '--inspect=6005'] };
const documentSelector: DocumentFilter[] = [{ language: 'coffeescript', scheme: 'file' }];
const config = vscode.workspace.getConfiguration();
let serverPath;
const devLspPackagePath = config.get('coffeesense.dev.lspPath', '');
if (devLspPackagePath && devLspPackagePath !== '' && existsSync(devLspPackagePath)) {
serverPath = resolve(devLspPackagePath, 'dist/coffeescriptServerMain.js');
} else {
serverPath = lspModulePath;
}
const runExecArgv: string[] = [];
const lspPort = config.get('coffeesense.dev.lspPort');
if (lspPort !== -1) {
runExecArgv.push(`--inspect=${lspPort}`);
console.log(`Will launch LSP in port: ${lspPort}`);
}
const serverOptions: ServerOptions = {
run: { module: serverPath, transport: TransportKind.ipc, options: { execArgv: runExecArgv } },
debug: { module: serverPath, transport: TransportKind.ipc, options: debugOptions }
};
const clientOptions: LanguageClientOptions = {
documentSelector,
synchronize: {
configurationSection: ['coffeesense', 'javascript', 'typescript', 'files.associations'],
fileEvents: vscode.workspace.createFileSystemWatcher('{**/*.js,**/*.ts,**/*.json}', false, false, true)
},
initializationOptions: {
},
revealOutputChannelOn: RevealOutputChannelOn.Never
};
return new LanguageClient('coffeesense', 'CoffeeSense Language Server', serverOptions, clientOptions);
}
Example #18
Source File: languageServerClient.ts From vscode-stripe with MIT License | 4 votes |
static async activateDotNetServer(
context: ExtensionContext,
outputChannel: OutputChannel,
projectFile: string,
telemetry: Telemetry,
) {
outputChannel.appendLine('Detected C# Project file: ' + projectFile);
// Applie Silicon is not supported for dotnet < 6.0:
// https://github.com/dotnet/core/issues/4879#issuecomment-729046912
if (getOSType() === OSType.macOSarm) {
outputChannel.appendLine(
`.NET runtime v${REQUIRED_DOTNET_RUNTIME_VERSION} is not supported for M1`,
);
telemetry.sendEvent('dotnetRuntimeAcquisitionSkippedForM1');
return;
}
const result = await commands.executeCommand<{dotnetPath: string}>('dotnet.acquire', {
version: REQUIRED_DOTNET_RUNTIME_VERSION,
requestingExtensionId: 'stripe.vscode-stripe',
});
if (!result) {
outputChannel.appendLine(
`Failed to install .NET runtime v${REQUIRED_DOTNET_RUNTIME_VERSION}. Unable to start language server`,
);
telemetry.sendEvent('dotnetRuntimeAcquisitionFailed');
return;
}
const dotNetExecutable = path.resolve(result.dotnetPath);
outputChannel.appendLine('dotnet runtime acquired: ' + dotNetExecutable);
const serverAssembly = context.asAbsolutePath(
'dist/stripeDotnetLanguageServer/stripe.LanguageServer.dll',
);
const serverOptions: ServerOptions = {
command: dotNetExecutable,
args: [serverAssembly, projectFile],
};
// Options to control the language client
const clientOptions: LanguageClientOptions = {
// Register the server for plain text documents
documentSelector: [{scheme: 'file', language: 'csharp'}],
synchronize: {
configurationSection: 'stripeCsharpLangaugeServer',
fileEvents: workspace.createFileSystemWatcher('**/*.cs'),
},
diagnosticCollectionName: 'Stripe C# language server',
errorHandler: {
error: (error, message, count) => {
console.log(message);
console.log(error);
return ErrorAction.Continue;
},
closed: () => CloseAction.DoNotRestart,
},
};
// Create the language client and start the client.
// We are overriding the show notification for the dotnet client.
const dotnetClient = new (class extends LanguageClient {
error(message: string, data: any, showNotification: boolean) {
super.error(message, data, false);
}
})('stripeCsharpLanguageServer', 'Stripe C# Server', serverOptions, clientOptions);
dotnetClient.trace = Trace.Verbose;
outputChannel.appendLine('Starting C# language service for ' + projectFile);
const disposable = dotnetClient.start();
// Push the disposable to the context's subscriptions so that the
// client can be deactivated on extension deactivation
context.subscriptions.push(disposable);
await dotnetClient.onReady();
outputChannel.appendLine('C# language service is running.');
telemetry.sendEvent('dotnetServerStarted');
}
Example #19
Source File: extension.ts From language-tools with MIT License | 4 votes |
export function activateSvelteLanguageServer(context: ExtensionContext) { warnIfOldExtensionInstalled(); const runtimeConfig = workspace.getConfiguration('svelte.language-server'); const { workspaceFolders } = workspace; const rootPath = Array.isArray(workspaceFolders) ? workspaceFolders[0].uri.fsPath : undefined; const tempLsPath = runtimeConfig.get<string>('ls-path'); // Returns undefined if path is empty string // Return absolute path if not already const lsPath = tempLsPath && tempLsPath.trim() !== '' ? path.isAbsolute(tempLsPath) ? tempLsPath : path.join(rootPath as string, tempLsPath) : undefined; const serverModule = require.resolve(lsPath || 'svelte-language-server/bin/server.js'); console.log('Loading server from ', serverModule); // Add --experimental-modules flag for people using node 12 < version < 12.17 // Remove this in mid 2022 and bump vs code minimum required version to 1.55 const runExecArgv: string[] = ['--experimental-modules']; let port = runtimeConfig.get<number>('port') ?? -1; if (port < 0) { port = 6009; } else { console.log('setting port to', port); runExecArgv.push(`--inspect=${port}`); } const debugOptions = { execArgv: ['--nolazy', '--experimental-modules', `--inspect=${port}`] }; const serverOptions: ServerOptions = { run: { module: serverModule, transport: TransportKind.ipc, options: { execArgv: runExecArgv } }, debug: { module: serverModule, transport: TransportKind.ipc, options: debugOptions } }; const serverRuntime = runtimeConfig.get<string>('runtime'); if (serverRuntime) { serverOptions.run.runtime = serverRuntime; serverOptions.debug.runtime = serverRuntime; console.log('setting server runtime to', serverRuntime); } const clientOptions: LanguageClientOptions = { documentSelector: [{ scheme: 'file', language: 'svelte' }], revealOutputChannelOn: RevealOutputChannelOn.Never, synchronize: { // TODO deprecated, rework upon next VS Code minimum version bump configurationSection: [ 'svelte', 'prettier', 'emmet', 'javascript', 'typescript', 'css', 'less', 'scss' ], fileEvents: workspace.createFileSystemWatcher('{**/*.js,**/*.ts}', false, false, false) }, initializationOptions: { configuration: { svelte: workspace.getConfiguration('svelte'), prettier: workspace.getConfiguration('prettier'), emmet: workspace.getConfiguration('emmet'), typescript: workspace.getConfiguration('typescript'), javascript: workspace.getConfiguration('javascript'), css: workspace.getConfiguration('css'), less: workspace.getConfiguration('less'), scss: workspace.getConfiguration('scss') }, dontFilterIncompleteCompletions: true, // VSCode filters client side and is smarter at it than us isTrusted: (workspace as any).isTrusted } }; let ls = createLanguageServer(serverOptions, clientOptions); context.subscriptions.push(ls.start()); ls.onReady().then(() => { const tagRequestor = (document: TextDocument, position: Position) => { const param = ls.code2ProtocolConverter.asTextDocumentPositionParams( document, position ); return ls.sendRequest(TagCloseRequest.type, param); }; const disposable = activateTagClosing( tagRequestor, { svelte: true }, 'html.autoClosingTags' ); context.subscriptions.push(disposable); }); workspace.onDidSaveTextDocument(async (doc) => { const parts = doc.uri.toString(true).split(/\/|\\/); if ( [ /^tsconfig\.json$/, /^jsconfig\.json$/, /^svelte\.config\.(js|cjs|mjs)$/, // https://prettier.io/docs/en/configuration.html /^\.prettierrc$/, /^\.prettierrc\.(json|yml|yaml|json5|toml)$/, /^\.prettierrc\.(js|cjs)$/, /^\.prettierrc\.config\.(js|cjs)$/ ].some((regex) => regex.test(parts[parts.length - 1])) ) { await restartLS(false); } }); context.subscriptions.push( commands.registerCommand('svelte.restartLanguageServer', async () => { await restartLS(true); }) ); let restartingLs = false; async function restartLS(showNotification: boolean) { if (restartingLs) { return; } restartingLs = true; await ls.stop(); ls = createLanguageServer(serverOptions, clientOptions); context.subscriptions.push(ls.start()); await ls.onReady(); if (showNotification) { window.showInformationMessage('Svelte language server restarted.'); } restartingLs = false; } function getLS() { return ls; } addDidChangeTextDocumentListener(getLS); addFindFileReferencesListener(getLS, context); addRenameFileListener(getLS); addCompilePreviewCommand(getLS, context); addExtracComponentCommand(getLS, context); languages.setLanguageConfiguration('svelte', { indentationRules: { // Matches a valid opening tag that is: // - Not a doctype // - Not a void element // - Not a closing tag // - Not followed by a closing tag of the same element // Or matches `<!--` // Or matches open curly brace // increaseIndentPattern: // eslint-disable-next-line max-len, no-useless-escape /<(?!\?|(?:area|base|br|col|frame|hr|html|img|input|link|meta|param)\b|[^>]*\/>)([-_\.A-Za-z0-9]+)(?=\s|>)\b[^>]*>(?!.*<\/\1>)|<!--(?!.*-->)|\{[^}"']*$/, // Matches a closing tag that: // - Follows optional whitespace // - Is not `</html>` // Or matches `-->` // Or closing curly brace // // eslint-disable-next-line no-useless-escape decreaseIndentPattern: /^\s*(<\/(?!html)[-_\.A-Za-z0-9]+\b[^>]*>|-->|\})/ }, // Matches a number or word that either: // - Is a number with an optional negative sign and optional full number // with numbers following the decimal point. e.g `-1.1px`, `.5`, `-.42rem`, etc // - Is a sequence of characters without spaces and not containing // any of the following: `~!@$^&*()=+[{]}\|;:'",.<>/ // wordPattern: // eslint-disable-next-line max-len, no-useless-escape /(-?\d*\.\d\w*)|([^\`\~\!\@\$\#\^\&\*\(\)\=\+\[\{\]\}\\\|\;\:\'\"\,\.\<\>\/\s]+)/g, onEnterRules: [ { // Matches an opening tag that: // - Isn't an empty element // - Is possibly namespaced // - Isn't a void element // - Isn't followed by another tag on the same line // // eslint-disable-next-line no-useless-escape beforeText: new RegExp( `<(?!(?:${EMPTY_ELEMENTS.join( '|' )}))([_:\\w][_:\\w-.\\d]*)([^/>]*(?!/)>)[^<]*$`, 'i' ), // Matches a closing tag that: // - Is possibly namespaced // - Possibly has excess whitespace following tagname afterText: /^<\/([_:\w][_:\w-.\d]*)\s*>/i, action: { indentAction: IndentAction.IndentOutdent } }, { // Matches an opening tag that: // - Isn't an empty element // - Isn't namespaced // - Isn't a void element // - Isn't followed by another tag on the same line // // eslint-disable-next-line no-useless-escape beforeText: new RegExp( `<(?!(?:${EMPTY_ELEMENTS.join('|')}))(\\w[\\w\\d]*)([^/>]*(?!/)>)[^<]*$`, 'i' ), action: { indentAction: IndentAction.Indent } } ] }); return { getLS }; }
Example #20
Source File: extension.ts From macro-executor with MIT License | 4 votes |
export function activate(context: ExtensionContext) {
// The server is implemented in node
let serverModule = context.asAbsolutePath(
path.join('server', 'out', 'server.js')
);
let debugOptions = { execArgv: ['--nolazy', '--inspect=6011'], cwd: process.cwd() };
let serverOptions: ServerOptions = {
run: { module: serverModule, transport: TransportKind.ipc, options: { cwd: process.cwd() } },
debug: {
module: serverModule,
transport: TransportKind.ipc,
options: debugOptions
}
};
let clientOptions: LanguageClientOptions = {
documentSelector: [{ language: 'macro', scheme: 'file' }],
initializationOptions: workspace.getConfiguration('macro'),
synchronize: {
fileEvents: workspace.createFileSystemWatcher('**/*.{[sS][rR][cC],[dD][eE][fF],[lL][nN][kK]}')
},
diagnosticCollectionName: 'macro',
progressOnInitialization: true,
revealOutputChannelOn: RevealOutputChannelOn.Never,
middleware: {
executeCommand: async (command:string, args:any[], next:ExecuteCommandSignature) => {
if (command === 'macro.codelens.references') {
const arg:CodeLensReferenceArgument = args[0];
const position = client.protocol2CodeConverter.asPosition(arg.position);
const locations:Location[] = [];
for (const location of arg.locations){
locations.push(client.protocol2CodeConverter.asLocation(location));
}
if (Window.activeTextEditor) {
commands.executeCommand('editor.action.showReferences', Window.activeTextEditor.document.uri, position, locations);
}
}
else if (command === 'macro.action.refactorsequeces' || command === 'macro.action.addsequeces') {
function validate(input:string): string | null {
return Number.isInteger(Number(input)) ? null : 'Integer expected';
}
const config = workspace.getConfiguration('macro');
let start = undefined;
if (command === 'macro.action.refactorsequeces') {
start = await Window.showInputBox({
prompt: 'Start sequence number',
value: config.sequence.base,
validateInput: validate
});
}
const increment = await Window.showInputBox({
prompt: 'Sequence number increment',
value: config.sequence.increment,
validateInput: validate
});
if (Window.activeTextEditor) {
if (command === 'macro.action.addsequeces' && increment) {
return next(command, [Window.activeTextEditor.document.uri.toString(), Window.activeTextEditor.selection.start, increment]);
}
else if (command === 'macro.action.refactorsequeces' && start && increment) {
return next(command, [Window.activeTextEditor.document.uri.toString(), Window.activeTextEditor.selection.start, start, increment]);
}
}
}
},
workspace : {
configuration: async (params, _token, _next): Promise<any[]> => {
if (params.items === undefined) {
return [];
}
const result: (ConfigurationSettings | null)[] = [];
for (const item of params.items) {
if (item.section || !item.scopeUri) {
result.push(null);
continue;
}
const resource = client.protocol2CodeConverter.asUri(item.scopeUri);
const workspaceFolder = Workspace.getWorkspaceFolder(resource);
const config = workspace.getConfiguration('macro', workspaceFolder);
const settings: ConfigurationSettings = {
codelens: config.get('codelens'),
lint:config.get('lint', {}),
sequence: config.get('sequence'),
validate: config.get('validate'),
keywords: config.get('keywords'),
};
if (workspaceFolder !== undefined) {
settings.workspaceFolder = {
name: workspaceFolder.name,
uri: client.code2ProtocolConverter.asUri(workspaceFolder.uri),
};
}
result.push(settings);
}
return result;
}
}
} as any
};
// Create the language client and start the client.
client = new LanguageClient(
'macroLanguageServer',
'Macro Language Server',
serverOptions,
clientOptions
);
disposables.add(registerCommands());
context.subscriptions.push(disposables);
context.subscriptions.push(client.start());
}
Example #21
Source File: extension.ts From vscode-stripe with MIT License | 4 votes |
export function activate(this: any, context: ExtensionContext) {
initializeStripeWorkspaceState(context);
new TelemetryPrompt(context).activate();
const surveyPrompt: SurveyPrompt = new SurveyPrompt(context);
surveyPrompt.activate();
const telemetry = getTelemetry(context);
telemetry.sendEvent('activate');
const stripeOutputChannel = window.createOutputChannel('Stripe');
const stripeClient = new StripeClient(telemetry, context);
const stripeDaemon = new StripeDaemon(stripeClient);
const stripeSamples = new StripeSamples(stripeClient, stripeDaemon);
const stripeEventsViewProvider = new StripeEventsViewProvider(
stripeClient,
stripeDaemon,
context,
);
window.createTreeView('stripeEventsView', {
treeDataProvider: stripeEventsViewProvider,
showCollapseAll: true,
});
const stripeLogsViewProvider = new StripeLogsViewProvider(stripeClient, stripeDaemon, context);
window.createTreeView('stripeLogsView', {
treeDataProvider: stripeLogsViewProvider,
showCollapseAll: true,
});
const stripeWebhooksViewProvider = new StripeWebhooksViewProvider(stripeDaemon);
window.createTreeView('stripeWebhooksView', {
treeDataProvider: stripeWebhooksViewProvider,
showCollapseAll: true,
});
stripeWebhooksViewProvider.refreshEndpoints();
window.createTreeView('stripeSamplesView', {
treeDataProvider: new StripeSamplesViewProvider(),
showCollapseAll: false,
});
window.createTreeView('stripeQuickLinksView', {
treeDataProvider: new StripeQuickLinksViewProvider(),
showCollapseAll: false,
});
const stripeHelpView = window.createTreeView('stripeHelpView', {
treeDataProvider: new StripeHelpViewProvider(),
showCollapseAll: false,
});
stripeHelpView.message = 'This extension runs with your Stripe account in test mode.';
debug.registerDebugConfigurationProvider('stripe', new StripeDebugProvider(telemetry));
workspace.registerTextDocumentContentProvider(
'stripeEvent',
new StripeResourceDocumentContentProvider(context, EVENT_ID_REGEXP, retrieveEventDetails),
);
workspace.registerTextDocumentContentProvider(
'stripeLog',
new StripeResourceDocumentContentProvider(context, LOG_ID_REGEXP, retrieveLogDetails),
);
languages.registerDocumentLinkProvider(
{scheme: 'stripeLog'},
new StripeLogsDashboardLinkProvider(),
);
const git = new Git();
new StripeLinter(telemetry, git).activate();
// Start language Server for hover matching of Stripe methods
const serverModule = context.asAbsolutePath(
path.join('dist', 'stripeLanguageServer', 'server.js'),
);
const serverOptions: ServerOptions = {
run: {
module: serverModule,
transport: TransportKind.ipc,
},
debug: {
module: serverModule,
transport: TransportKind.ipc,
options: {execArgv: ['--nolazy', '--inspect=6009']},
},
};
StripeLanguageClient.activate(context, serverOptions, telemetry);
const stripeTerminal = new StripeTerminal(stripeClient);
const stripeCommands = new Commands(telemetry, stripeTerminal, context);
const commandCallbackPairs: [string, (...args: any[]) => any][] = [
['stripe.createStripeSample', () => stripeCommands.createStripeSample(stripeSamples)],
['stripe.login', () => stripeCommands.startLogin(stripeDaemon)],
['stripe.openCLI', stripeCommands.openCLI],
['stripe.openDashboardApikeys', stripeCommands.openDashboardApikeys],
['stripe.openDashboardEvent', stripeCommands.openDashboardEvent],
['stripe.openDashboardEvents', stripeCommands.openDashboardEvents],
['stripe.openDashboardLog', stripeCommands.openDashboardLog],
['stripe.openDashboardLogs', stripeCommands.openDashboardLogs],
['stripe.openDashboardWebhooks', stripeCommands.openDashboardWebhooks],
['stripe.openDocs', stripeCommands.openDocs],
['stripe.openEventDetails', stripeCommands.openEventDetails],
['stripe.openLogDetails', stripeCommands.openLogDetails],
['stripe.openReportIssue', stripeCommands.openReportIssue],
['stripe.openSamples', stripeCommands.openSamples],
['stripe.openSurvey', () => stripeCommands.openSurvey(surveyPrompt)],
['stripe.openTelemetryInfo', stripeCommands.openTelemetryInfo],
[
'stripe.openTriggerEvent',
() => stripeCommands.openTriggerEvent(context, stripeDaemon, stripeOutputChannel),
],
[
'stripe.openCreateCustomizedEvent',
() => stripeCommands.openCreateCustomizedEvent(context, stripeDaemon, stripeOutputChannel),
],
[
'stripe.openTriggerCustomizedEvent',
() => stripeCommands.openTriggerCustomizedEvent(stripeDaemon, stripeOutputChannel),
],
['stripe.openWebhooksDebugConfigure', stripeCommands.openWebhooksDebugConfigure],
['stripe.openWebhooksListen', stripeCommands.openWebhooksListen],
[
'stripe.createWebhookEndpoint',
() => stripeCommands.createWebhookEndpoint(stripeDaemon, stripeOutputChannel, stripeWebhooksViewProvider),
],
[
'stripe.resendEvent',
(treeItem) => stripeCommands.resendEvent(treeItem, stripeDaemon, stripeOutputChannel),
],
[
'stripe.startEventsStreaming',
() => stripeCommands.startEventsStreaming(stripeEventsViewProvider),
],
[
'stripe.stopEventsStreaming',
() => stripeCommands.stopEventsStreaming(stripeEventsViewProvider),
],
['stripe.clearRecentEvents', () => stripeCommands.clearRecentEvents(stripeEventsViewProvider)],
['stripe.startLogsStreaming', () => stripeCommands.startLogsStreaming(stripeLogsViewProvider)],
['stripe.stopLogsStreaming', () => stripeCommands.stopLogsStreaming(stripeLogsViewProvider)],
['stripe.clearRecentLogs', () => stripeCommands.clearRecentLogs(stripeLogsViewProvider)],
];
const registeredCommands: Disposable[] = commandCallbackPairs.map(([command, callback]) =>
commands.registerCommand(command, callback),
);
context.subscriptions.push(...registeredCommands);
}
Example #22
Source File: leanclient.ts From vscode-lean4 with Apache License 2.0 | 4 votes |
async restart(): Promise<void> {
const startTime = Date.now()
console.log('Restarting Lean Language Server')
if (this.isStarted()) {
await this.stop()
}
this.restartingEmitter.fire(undefined)
this.toolchainPath = this.storageManager.getLeanPath();
if (!this.toolchainPath) this.toolchainPath = toolchainPath();
const version = this.storageManager.getLeanVersion();
const env = addServerEnvPaths(process.env);
if (serverLoggingEnabled()) {
env.LEAN_SERVER_LOG_DIR = serverLoggingPath()
}
let executable = (this.toolchainPath) ? join(this.toolchainPath, 'bin', 'lake') : 'lake';
// check if the lake process will start (skip it on scheme: 'untitled' files)
let useLake = lakeEnabled() && this.folderUri && this.folderUri.scheme === 'file';
if (useLake) {
let knownDate = false;
const lakefile = Uri.joinPath(this.folderUri, 'lakefile.lean')
if (!await fileExists(new URL(lakefile.toString()))) {
useLake = false;
}
else {
// see if we can avoid the more expensive checkLakeVersion call.
const date = await this.checkToolchainVersion(this.folderUri);
if (date){
// Feb 16 2022 is when the 3.1.0.pre was released.
useLake = date >= new Date(2022, 1, 16);
knownDate = true;
}
if (useLake && !knownDate){
useLake = await this.checkLakeVersion(executable, version);
}
}
}
if (!useLake) {
executable = (this.toolchainPath) ? join(this.toolchainPath, 'bin', 'lean') : 'lean';
}
let options = version ? ['+' + version] :[]
if (useLake) {
options = options.concat(['serve', '--'])
} else{
options = options.concat(['--server'])
}
// Add folder name to command-line so that it shows up in `ps aux`.
if (this.folderUri) {
options.push('' + this.folderUri.fsPath)
} else {
options.push('untitled')
}
const serverOptions: ServerOptions = {
command: executable,
args: options.concat(serverArgs()),
options: {
cwd: this.folderUri?.fsPath,
env
}
}
const documentSelector: DocumentFilter = {
language: 'lean4'
}
if (this.folderUri){
documentSelector.scheme = this.folderUri.scheme
if (this.folderUri.scheme !== 'untitled') {
documentSelector.pattern = `${this.folderUri.fsPath}/**/*`
}
}
const clientOptions: LanguageClientOptions = {
outputChannel: this.outputChannel,
documentSelector: [documentSelector],
workspaceFolder: this.workspaceFolder,
initializationOptions: {
editDelay: getElaborationDelay(), hasWidgets: true,
},
connectionOptions: {
maxRestartCount: 0,
cancellationStrategy: undefined as any,
},
middleware: {
handleDiagnostics: (uri, diagnostics, next) => {
next(uri, diagnostics);
if (!this.client) return;
const uri_ = c2pConverter.asUri(uri);
const diagnostics_ = [];
for (const d of diagnostics) {
const d_: ls.Diagnostic = {
...c2pConverter.asDiagnostic(d),
};
diagnostics_.push(d_);
}
this.diagnosticsEmitter.fire({uri: uri_, diagnostics: diagnostics_});
},
didOpen: async () => {
// Note: as per the LSP spec: An open notification must not be sent more than once
// without a corresponding close notification send before. This means open and close
// notification must be balanced and the max open count for a particular textDocument
// is one. So this even does nothing the notification is handled by the
// openLean4Document method below after the 'lean4' languageId is established and
// it has weeded out documents opened to invisible editors (like 'git:' schemes and
// invisible editors created for Ctrl+Hover events. A side effect of unbalanced
// open/close notification is leaking 'lean --worker' processes.
// See https://github.com/microsoft/vscode/issues/78453).
return;
},
didChange: async (data, next) => {
await next(data);
if (!this.running || !this.client) return; // there was a problem starting lean server.
const params = c2pConverter.asChangeTextDocumentParams(data);
this.didChangeEmitter.fire(params);
},
didClose: async (doc, next) => {
if (!this.isOpen.delete(doc.uri.toString())) {
return;
}
await next(doc);
if (!this.running || !this.client) return; // there was a problem starting lean server.
const params = c2pConverter.asCloseTextDocumentParams(doc);
this.didCloseEmitter.fire(params);
},
provideDocumentHighlights: async (doc, pos, ctok, next) => {
const leanHighlights = await next(doc, pos, ctok);
if (leanHighlights?.length) return leanHighlights;
// vscode doesn't fall back to textual highlights,
// so we need to do that manually
await new Promise((res) => setTimeout(res, 250));
if (ctok.isCancellationRequested) return;
const wordRange = doc.getWordRangeAtPosition(pos);
if (!wordRange) return;
const word = doc.getText(wordRange);
const highlights: DocumentHighlight[] = [];
const text = doc.getText();
const nonWordPattern = '[`~@$%^&*()-=+\\[{\\]}⟨⟩⦃⦄⟦⟧⟮⟯‹›\\\\|;:\",./\\s]|^|$'
const regexp = new RegExp(`(?<=${nonWordPattern})${escapeRegExp(word)}(?=${nonWordPattern})`, 'g')
for (const match of text.matchAll(regexp)) {
const start = doc.positionAt(match.index ?? 0)
highlights.push({
range: new Range(start, start.translate(0, match[0].length)),
kind: DocumentHighlightKind.Text,
})
}
return highlights;
}
},
}
this.client = new LanguageClient(
'lean4',
'Lean 4',
serverOptions,
clientOptions
)
let insideRestart = true;
patchConverters(this.client.protocol2CodeConverter, this.client.code2ProtocolConverter)
try {
this.client.onDidChangeState(async (s) => {
// see https://github.com/microsoft/vscode-languageserver-node/issues/825
if (s.newState === State.Starting) {
console.log('client starting');
} else if (s.newState === State.Running) {
const end = Date.now()
console.log('client running, started in ', end - startTime, 'ms');
this.running = true; // may have been auto restarted after it failed.
if (!insideRestart) {
this.restartedEmitter.fire(undefined)
}
} else if (s.newState === State.Stopped) {
this.stoppedEmitter.fire('Lean language server has stopped. ');
console.log('client has stopped or it failed to start');
this.running = false;
if (!this.noPrompt){
await this.showRestartMessage();
}
}
})
this.client.start()
await this.client.onReady();
// tell the new client about the documents that are already open!
for (const key of this.isOpen.keys()) {
const doc = this.isOpen.get(key);
if (doc) this.notifyDidOpen(doc);
}
// if we got this far then the client is happy so we are running!
this.running = true;
} catch (error) {
this.outputChannel.appendLine('' + error);
this.serverFailedEmitter.fire('' + error);
insideRestart = false;
return;
}
// HACK(WN): Register a default notification handler to fire on custom notifications.
// A mechanism to do this is provided in vscode-jsonrpc. One can register a `StarNotificationHandler`
// here: https://github.com/microsoft/vscode-languageserver-node/blob/b2fc85d28a1a44c22896559ee5f4d3ba37a02ef5/jsonrpc/src/common/connection.ts#L497
// which fires on any LSP notifications not in the standard, for example the `$/lean/..` ones.
// However this mechanism is not exposed in vscode-languageclient, so we hack around its implementation.
const starHandler = (method: string, params_: any) => {
if (method === '$/lean/fileProgress' && this.client) {
const params = params_ as LeanFileProgressParams;
const uri = p2cConverter.asUri(params.textDocument.uri)
this.progressChangedEmitter.fire([uri.toString(), params.processing]);
// save the latest progress on this Uri in case infoview needs it later.
this.progress.set(uri, params.processing);
}
this.customNotificationEmitter.fire({method, params: params_});
};
// eslint-disable-next-line @typescript-eslint/no-unsafe-argument
this.client.onNotification(starHandler as any, () => {});
// Reveal the standard error output channel when the server prints something to stderr.
// The vscode-languageclient library already takes care of writing it to the output channel.
(this.client as any)._serverProcess.stderr.on('data', () => {
this.client?.outputChannel.show(true);
});
this.restartedEmitter.fire(undefined)
insideRestart = false;
}
Example #23
Source File: client.ts From vscode-q with MIT License | 4 votes |
export function activate(context: ExtensionContext): void {
// extra language configurations
languages.setLanguageConfiguration('q', {
onEnterRules: [
{
// eslint-disable-next-line no-useless-escape
beforeText: /^(?!\s+).*[\(\[{].*$/,
afterText: /^[)}\]]/,
action: {
indentAction: IndentAction.None,
appendText: '\n '
}
},
{
// eslint-disable-next-line no-useless-escape
beforeText: /^\s[)}\]];?$/,
action: {
indentAction: IndentAction.Outdent
}
},
{
// eslint-disable-next-line no-useless-escape
beforeText: /^\/.*$/,
action: {
indentAction: IndentAction.None,
appendText: '/ '
}
}
]
});
// append space to start [,(,{
languages.registerDocumentFormattingEditProvider('q', {
provideDocumentFormattingEdits(document: TextDocument): TextEdit[] {
const textEdit: TextEdit[] = [];
for (let i = 0; i < document.lineCount; i++) {
const line = document.lineAt(i);
if (line.isEmptyOrWhitespace) {
continue;
}
if (line.text.match('^[)\\]}]')) {
textEdit.push(TextEdit.insert(line.range.start, ' '));
}
}
return textEdit;
}
});
// <-- init
QStatusBarManager.create(context);
QStatusBarManager.updateConnStatus(undefined);
// q-server-explorer
const qServers = new QServerTree('root', null);
const qRoot = new QDictTreeItem('root', null);
const qHistory = HistoryTreeItem.createHistoryTree();
window.registerTreeDataProvider('q-servers', qServers);
qServers.refresh();
window.registerTreeDataProvider('q-explorer', qRoot);
window.registerTreeDataProvider('q-history', qHistory);
qHistory.refresh();
QueryConsole.createOrGet();
QueryView.setExtensionPath(context.extensionPath);
QueryGrid.setExtensionPath(context.extensionPath);
AddServer.setExtensionPath(context.extensionPath);
ChartView.setExtensionPath(context.extensionPath);
// --> init
// <-- configuration
const queryMode = workspace.getConfiguration().get('q-client.queryMode');
QConnManager.setQueryMode(queryMode as string);
// -->
commands.registerCommand(
'q-client.refreshEntry', () => qServers.refresh());
commands.registerCommand(
'q-explorer.toggleAutoRefresh', () => {
QConnManager.autoRefreshExplorer = !QConnManager.autoRefreshExplorer;
window.showInformationMessage(`Auto Refresh Explorer ${QConnManager.autoRefreshExplorer ? 'On' : 'Off'}`);
});
// q cfg input
commands.registerCommand(
'q-client.addEntry',
() => {
AddServer.createOrShow();
});
commands.registerCommand(
'q-client.editEntry',
(qConn: QConn) => {
AddServer.createOrShow();
AddServer.update(qConn);
});
commands.registerCommand(
'q-client.deleteEntry',
(qConn: QConn) => {
window.showInputBox(
{ prompt: `Confirm to Remove Server '${qConn.uniqLabel.replace(',', '-')}' (Y/n)` }
).then(value => {
if (value === 'Y') {
QConnManager.current?.removeCfg(qConn.uniqLabel);
}
});
});
commands.registerCommand(
'q-client.reactions',
async () => {
const option = await window.showQuickPick(
['1 - Raising an Issue', '2 - Writing a Review', '3 - Creating a Pull Request', '4 - Buying Me a Beer', '5 - Q & A'],
{ placeHolder: 'Contribute to vscode-q by' });
switch (option?.[0]) {
case '1':
env.openExternal(Uri.parse('https://github.com/jshinonome/vscode-q/issues'));
break;
case '2':
env.openExternal(Uri.parse('https://marketplace.visualstudio.com/items?itemName=jshinonome.vscode-q&ssr=false#review-details'));
break;
case '3':
env.openExternal(Uri.parse('https://github.com/jshinonome/vscode-q/blob/master/CONTRIBUTING.md'));
break;
case '4':
env.openExternal(Uri.parse('https://www.buymeacoffee.com/jshinonome'));
break;
case '5':
env.openExternal(Uri.parse('https://github.com/jshinonome/vscode-q/discussions'));
}
});
commands.registerCommand(
'q-client.connectEntry',
async () => {
const connManager = QConnManager.current;
if (connManager) {
const quickPickItems: QuickPickItem[] = connManager.qCfg.map(qcfg => {
return {
label: qcfg.uniqLabel,
description: `\`:${qcfg.host}:${qcfg.port}`
};
});
const recentlyUsedItems: QuickPickItem[] = Array.from(connManager.qConnPool.values())
.filter(qConn => !(qConn.conn == undefined))
.map(qConn => {
return {
label: qConn.uniqLabel,
description: `\`:${qConn.host}:${qConn.port}`
};
});
const allItems: QuickPickItem[] = [
{
label: 'Connected',
kind: QuickPickItemKind.Separator
},
...recentlyUsedItems,
{
label: 'Process',
kind: QuickPickItemKind.Separator
},
...quickPickItems
];
const item = await window.showQuickPick(
allItems,
{ placeHolder: 'Connect to a q process' });
if (item) {
commands.executeCommand('q-client.connect', item.label);
return item.label;
}
}
});
commands.registerCommand(
'q-client.connect',
uniqLabel => {
QConnManager.current?.connect(uniqLabel);
});
commands.registerCommand(
'q-client.tagEntry',
async (qConn: QConn) => {
qConn.tags = await window.showInputBox({
prompt: `Tags for '${qConn.label}' separate by ',' (e.g. 'dev,quant,tca')`
}) ?? '';
QConnManager.current?.addCfg(qConn);
});
commands.registerCommand(
'q-client.switchMode',
async () => {
const mode = await window.showQuickPick(['Console', 'Grid', 'Visualization'],
{ placeHolder: 'Please choose a query mode from the list below' });
if (mode) {
window.showInformationMessage(`Switch to Query ${mode} Mode`);
QConnManager.setQueryMode(mode);
QStatusBarManager.updateQueryModeStatus();
}
});
commands.registerCommand(
'q-client.toggleLimitQuery',
() => {
QConnManager.current?.toggleLimitQuery();
});
commands.registerCommand(
'q-client.abortQuery',
() => {
QConnManager.current?.abortQuery();
});
commands.registerCommand(
'q-client.exportServers',
() => {
QConnManager.current?.exportCfg();
});
commands.registerCommand(
'q-client.importServers',
() => {
QConnManager.current?.importCfg();
});
commands.registerCommand(
'q-explorer.refreshEntry', () => qRoot.refresh());
const previewQueryLimit = workspace.getConfiguration().get('q-client.expl.prevQueryLimit');
commands.registerCommand('q-explorer.preview', (item: TreeItem) => {
switch (item.contextValue) {
case 'qtable':
QConnManager.current?.sync(
`{[t;l]$[@[{x in value \`.Q.pt};t;{'"preview feature requires v3.5+ kdb"}];select from t where date=last date, i<l;select from t where i<l]}[\`${item.label};${previewQueryLimit}]`);
break;
case 'qfunction':
QueryConsole.current?.append((item as QFunctionTreeItem).getBody(), 0, 'cached');
break;
default:
if (item.label)
QConnManager.current?.sync(item.label as string);
}
});
commands.registerCommand('q-explorer.click', label => {
console.log(label);
});
context.subscriptions.push(
commands.registerCommand('q-history.rerun', (history) => {
if (QConnManager.current?.activeConn?.uniqLabel === history.uniqLabel)
QConnManager.current?.sync(history.query);
else
QConnManager.current?.connect(history.uniqLabel, history.query);
})
);
enum QueryCodeType {
Line,
Selection,
Block
}
enum QueryTarget {
Process,
Terminal
}
async function queryCode(code: QueryCodeType, target: QueryTarget): Promise<void> {
const editor = window.activeTextEditor;
if (editor) {
let n = 0;
let query = '';
const params = {
textDocument: {
uri: editor.document.uri.toString(),
},
position: editor.selection.active,
};
switch (code) {
case QueryCodeType.Line:
n = editor.selection.active.line;
query = editor.document.lineAt(n).text;
n = 0;
break;
case QueryCodeType.Selection:
query = editor?.document.getText(
new Range(editor.selection.start, editor.selection.end)
);
break;
case QueryCodeType.Block:
({ query, n } = await client.sendRequest('onQueryBlock', params));
break;
}
if (query) {
if (code === QueryCodeType.Line && query.startsWith('/<=>')) {
const uniqLabel = query.substring(4).trim();
commands.executeCommand('q-client.connect', uniqLabel);
} else {
switch (target) {
case QueryTarget.Process:
QConnManager.current?.sync(query);
break;
case QueryTarget.Terminal:
sendToCurrentTerm(query.replace(/(\r\n|\n|\r)/gm, ''));
break;
}
}
}
if (n > 0) {
let line = editor.document.lineAt(n).text;
while (n < editor.document.lineCount && (line === '' || line.startsWith('/'))) {
n++;
line = editor.document.lineAt(n).text;
}
const range = editor.document.lineAt(n).range;
editor.selection = new Selection(range.start, range.start);
editor.revealRange(new Range(range.start, range.start));
}
}
}
context.subscriptions.push(
commands.registerCommand('q-client.queryCurrentLine', async () => {
queryCode(QueryCodeType.Line, QueryTarget.Process);
})
);
context.subscriptions.push(
commands.registerCommand('q-client.querySelection', () => {
queryCode(QueryCodeType.Selection, QueryTarget.Process);
})
);
context.subscriptions.push(
commands.registerCommand('q-client.queryBlock', () => {
queryCode(QueryCodeType.Block, QueryTarget.Process);
})
);
context.subscriptions.push(
commands.registerCommand('q-term.sendCurrentLine', () => {
queryCode(QueryCodeType.Line, QueryTarget.Terminal);
})
);
context.subscriptions.push(
commands.registerCommand('q-term.sendSelection', () => {
queryCode(QueryCodeType.Selection, QueryTarget.Terminal);
})
);
context.subscriptions.push(
commands.registerCommand('q-term.sendBlock', () => {
queryCode(QueryCodeType.Block, QueryTarget.Terminal);
})
);
context.subscriptions.push(
commands.registerCommand('q-client.terminal.run', () => {
const filepath = window.activeTextEditor?.document.fileName;
if (filepath)
runQFile(filepath);
})
);
context.subscriptions.push(
commands.registerCommand('q-client.insertActiveConnLabel', () => {
const editor = window.activeTextEditor;
if (editor) {
editor.edit(editBuilder => {
if (QConnManager.current?.activeConn?.uniqLabel) {
editBuilder.insert(editor.selection.active, '/<=>' + QConnManager.current?.activeConn?.uniqLabel);
}
});
}
})
);
if (window.registerWebviewPanelSerializer) {
// Make sure we register a serializer in activation event
window.registerWebviewPanelSerializer(QueryView.viewType, {
// eslint-disable-next-line @typescript-eslint/no-explicit-any
async deserializeWebviewPanel(webviewPanel: WebviewPanel) {
QueryView.revive(webviewPanel, context.extensionPath);
}
});
}
workspace.onDidChangeConfiguration(e => {
if (e.affectsConfiguration('q-client') && !e.affectsConfiguration('q-client.term')) {
window.showInformationMessage('Reload/Restart vscode to Make the Configuration Take Effect.');
} else if (e.affectsConfiguration('q-server')) {
const cfg = workspace.getConfiguration('q-server.sourceFiles');
client.sendNotification('analyzeSourceCode', { globsPattern: cfg.get('globsPattern'), ignorePattern: cfg.get('ignorePattern') });
}
});
// q language server
const qls = path.join(context.extensionPath, 'dist', 'server.js');
// The debug options for the server
// runs the server in Node's Inspector mode for debugging
const debugOptions = { execArgv: ['--nolazy', '--inspect=6018'] };
// If launched in debug mode then the debug server options are used
// Otherwise the run options are used
const serverOptions: ServerOptions = {
run: { module: qls, transport: TransportKind.ipc },
debug: {
module: qls,
transport: TransportKind.ipc,
options: debugOptions
}
};
// Options to control the language client
const clientOptions: LanguageClientOptions = {
// Register the server for plain text documents
documentSelector: [{ scheme: 'file', language: 'q' }],
synchronize: {
// Notify the server about q file changes
fileEvents: workspace.createFileSystemWatcher('**/*.q')
}
};
// Create the language client and start the client.
const client = new LanguageClient(
'qLangServer',
'q Language Server',
serverOptions,
clientOptions
);
context.subscriptions.push(
commands.registerCommand('q-client.sendServerCache', code => {
client.sendNotification('analyzeServerCache', code);
})
);
context.subscriptions.push(
commands.registerCommand('q-client.sendOnHover', hoverItems => {
client.sendNotification('prepareOnHover', hoverItems);
})
);
client.start().then(() => {
const cfg = workspace.getConfiguration('q-server.sourceFiles');
client.sendNotification('analyzeSourceCode', { globsPattern: cfg.get('globsPattern'), ignorePattern: cfg.get('ignorePattern') });
});
}