UNPKG

@vtsls/language-server

Version:

LSP wrapper for typescript extension of vscode

280 lines (273 loc) 10.3 kB
"use strict"; // src/index.ts var import_language_service2 = require("@vtsls/language-service"); var import_node2 = require("vscode-languageserver/node"); var import_vscode_uri = require("vscode-uri"); // src/capabilities.ts var import_language_service = require("@vtsls/language-service"); var import_node = require("vscode-languageserver/node"); function getTsLspDefaultCapabilities() { return { textDocumentSync: { openClose: true, change: import_node.TextDocumentSyncKind.Incremental, willSave: false, willSaveWaitUntil: false, save: false }, completionProvider: { triggerCharacters: import_language_service.completionTriggerCharacters, resolveProvider: true, completionItem: { labelDetailsSupport: true } }, hoverProvider: true, signatureHelpProvider: { triggerCharacters: import_language_service.signatureHelpTriggerCharacters, retriggerCharacters: import_language_service.signatureHelpReTriggerCharacters }, declarationProvider: false, definitionProvider: true, typeDefinitionProvider: true, implementationProvider: true, referencesProvider: true, documentHighlightProvider: true, documentSymbolProvider: { label: "typescript" }, codeActionProvider: { codeActionKinds: import_language_service.codeActionKinds, resolveProvider: true }, codeLensProvider: { resolveProvider: true }, // documentLinkProvider: { resolveProvider: false }, documentLinkProvider: void 0, colorProvider: false, workspaceSymbolProvider: { resolveProvider: false }, documentFormattingProvider: true, documentRangeFormattingProvider: true, documentOnTypeFormattingProvider: { firstTriggerCharacter: import_language_service.onTypeFormatFirstTriggerCharacter, moreTriggerCharacter: import_language_service.onTypeFormatMoreTriggerCharacter }, renameProvider: { prepareProvider: true }, foldingRangeProvider: true, selectionRangeProvider: true, executeCommandProvider: { commands: import_language_service.commands }, callHierarchyProvider: true, linkedEditingRangeProvider: true, semanticTokensProvider: { legend: { tokenTypes: import_language_service.semanticTokenTypes, tokenModifiers: import_language_service.semanticTokenModifiers }, full: true, range: true }, monikerProvider: false, typeHierarchyProvider: false, inlineValueProvider: false, inlayHintProvider: true, workspace: { workspaceFolders: { supported: true, changeNotifications: true }, fileOperations: { didRename: { filters: [ { scheme: "file", pattern: { glob: "**/*.{ts,cts,mts,tsx,js,cjs,mjs,jsx}", matches: "file" } }, { scheme: "file", pattern: { glob: "**/*", matches: "folder" } } ] } } } }; } // src/index.ts function createLanguageServer() { const conn = (0, import_node2.createConnection)(import_node2.ProposedFeatures.all); conn.onInitialize((params) => { return onServerInitialize(conn, params); }); conn.listen(); } function onServerInitialize(conn, params) { const clientCapabilities = params.capabilities; const root = params.rootUri ?? (params.rootPath ? import_vscode_uri.URI.file(params.rootPath).toString() : void 0); const folders = params.workspaceFolders ?? (typeof root == "string" ? [{ name: root, uri: root }] : void 0); const service = (0, import_language_service2.createTSLanguageService)({ locale: params.locale, workspaceFolders: folders, clientCapabilities, hostInfo: params.initializationOptions?.hostInfo, tsExtLogPath: params.initializationOptions?.tsLogPath }); async function initializeService() { try { if (clientCapabilities.workspace?.configuration) { const config = await conn.sendRequest(import_node2.ConfigurationRequest.type, { items: [{ section: "" }] }); await service.initialize(Array.isArray(config) ? config[0] : {}); } else { await service.initialize({}); } } catch (e) { conn.console.error(`Server initialization failed: ${String(e)}`); conn.dispose(); } } conn.onInitialized(() => { bindServiceHandlers(conn, service, clientCapabilities); void initializeService(); }); process.on("exit", () => service.dispose()); const capabilities = getTsLspDefaultCapabilities(); if (!clientCapabilities.textDocument?.codeAction?.codeActionLiteralSupport) { capabilities.codeActionProvider = true; } return { capabilities, serverInfo: { name: "vtsls", version: "0.3.0" } }; } function bindServiceHandlers(conn, service, clientCapabilities) { service.onLogMessage((params) => void conn.sendNotification(import_node2.LogMessageNotification.type, params)); service.onLogTrace((params) => void conn.tracer.log(params.message)); if (clientCapabilities.window?.showMessage) { service.onShowMessage((params) => conn.sendRequest(import_node2.ShowMessageRequest.type, params)); } if (clientCapabilities.window?.showDocument) { service.onShowDocument( async (params) => (await conn.sendRequest(import_node2.ShowDocumentRequest.type, params)).success ); } if (clientCapabilities.window?.workDoneProgress) { service.onWorkDoneProgress(() => conn.window.createWorkDoneProgress()); } if (clientCapabilities.workspace?.applyEdit) { service.onApplyWorkspaceEdit((params) => conn.workspace.applyEdit(params)); } if (clientCapabilities.textDocument?.publishDiagnostics) { service.onDiagnostics((params) => conn.sendDiagnostics(params)); } conn.onExit(() => service.dispose()); conn.onShutdown(() => service.dispose()); function safeRun(handler, fallback, catchProviderNotFound = false) { return async (...args) => { try { return await handler(...args); } catch (e) { if (catchProviderNotFound && e instanceof import_language_service2.ProviderNotFoundError) { conn.console.warn(e.message); return fallback; } else if (e instanceof import_language_service2.DocumentNotOpenedError) { return fallback; } throw e; } }; } conn.onDidOpenTextDocument(service.openTextDocument); conn.onDidCloseTextDocument(service.closeTextDocument); conn.onDidChangeTextDocument(service.changeTextDocument); conn.onDidChangeConfiguration(service.changeConfiguration); conn.workspace.onDidRenameFiles(service.renameFiles); if (clientCapabilities.workspace?.workspaceFolders) { conn.workspace.onDidChangeWorkspaceFolders( (event) => service.changeWorkspaceFolders({ event }) ); } conn.onCompletion(safeRun(service.completion, null)); conn.onCompletionResolve(service.completionItemResolve); conn.onDocumentHighlight(safeRun(service.documentHighlight, null)); conn.onSignatureHelp(safeRun(service.signatureHelp, null)); conn.onDefinition(safeRun(service.definition, null)); conn.onReferences(safeRun(service.references, null)); conn.onHover(safeRun(service.hover, null)); conn.onDocumentSymbol(safeRun(service.documentSymbol, null)); conn.onWorkspaceSymbol(safeRun(service.workspaceSymbol, null)); conn.onCodeAction(safeRun(service.codeAction, null)); conn.onCodeActionResolve(service.codeActionResolve); conn.onExecuteCommand(safeRun(service.executeCommand, null)); conn.onImplementation(safeRun(service.implementation, null)); conn.onTypeDefinition(safeRun(service.typeDefinition, null)); conn.onDocumentFormatting(safeRun(service.documentFormatting, null)); conn.onDocumentRangeFormatting(safeRun(service.documentRangeFormatting, null)); conn.onDocumentOnTypeFormatting(safeRun(service.documentOnTypeFormatting, null)); conn.onPrepareRename(safeRun(service.prepareRename, null)); conn.onRenameRequest(safeRun(service.rename, null)); conn.onFoldingRanges(safeRun(service.foldingRanges, null)); conn.onSelectionRanges(safeRun(service.selectionRanges, null)); conn.onCodeLens(safeRun(service.codeLens, null)); conn.onCodeLensResolve(service.codeLensResolve); conn.languages.callHierarchy.onPrepare(safeRun(service.prepareCallHierarchy, null, true)); conn.languages.callHierarchy.onIncomingCalls(safeRun(service.incomingCalls, null, true)); conn.languages.callHierarchy.onOutgoingCalls(safeRun(service.outgoingCalls, null, true)); conn.languages.inlayHint.on(safeRun(service.inlayHint, null, true)); conn.languages.onLinkedEditingRange(safeRun(service.linkedEditingRange, null, true)); const nullSemanticTokens = { data: [] }; conn.languages.semanticTokens.on(safeRun(service.semanticTokensFull, nullSemanticTokens, true)); conn.languages.semanticTokens.onRange( safeRun(service.semanticTokensRange, nullSemanticTokens, true) ); } function printHelp() { console.log(`vtsls v${"0.3.0"} Usage: vtsls [options] Language Server Options: --stdio Use stdio for communication (default) --node-ipc Use node-ipc for communication --socket=<number> Use socket for communication Other Options: --help, -h Show this help message --version, -V Print version information --print-config-schema Print the configuration schema as JSON `); } function printVersion() { console.log("0.3.0"); } function printConfigSchema() { try { const schema = require("@vtsls/language-service/configuration-schema"); console.log(JSON.stringify(schema, null, 2)); } catch (error) { console.error(`Error: Could not load configuration schema: ${error}`); console.log("{}"); } } function main() { const args = process.argv.slice(2); if (args.includes("--help") || args.includes("-h")) { printHelp(); process.exit(0); } else if (args.includes("--version") || args.includes("-V")) { printVersion(); process.exit(0); } else if (args.includes("--print-config-schema")) { printConfigSchema(); process.exit(0); } else { createLanguageServer(); } } main();