UNPKG

@yaegassy/coc-volar

Version:

Volar (Fast Vue Language Support) extension for coc.nvim

509 lines (500 loc) 18.2 kB
"use strict"; var __create = Object.create; var __defProp = Object.defineProperty; var __getOwnPropDesc = Object.getOwnPropertyDescriptor; var __getOwnPropNames = Object.getOwnPropertyNames; var __getProtoOf = Object.getPrototypeOf; var __hasOwnProp = Object.prototype.hasOwnProperty; var __export = (target, all) => { for (var name in all) __defProp(target, name, { get: all[name], enumerable: true }); }; var __copyProps = (to, from, except, desc) => { if (from && typeof from === "object" || typeof from === "function") { for (let key of __getOwnPropNames(from)) if (!__hasOwnProp.call(to, key) && key !== except) __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable }); } return to; }; var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps( // If the importer is in node compatibility mode or this is not an ESM // file that has been converted to a CommonJS file using a Babel- // compatible transform (i.e. "__esModule" has not been set), then set // "default" to the CommonJS "module.exports" for node compatibility. isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target, mod )); var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod); // src/index.ts var src_exports = {}; __export(src_exports, { activate: () => activate2, deactivate: () => deactivate2 }); module.exports = __toCommonJS(src_exports); var import_coc6 = require("coc.nvim"); var fs4 = __toESM(require("fs")); var path4 = __toESM(require("path")); // src/common.ts var import_coc5 = require("coc.nvim"); // src/client/commands/doctor.ts var import_coc = require("coc.nvim"); var import_fs = __toESM(require("fs")); var import_path = __toESM(require("path")); async function register(context) { context.subscriptions.push(import_coc.commands.registerCommand("volar.action.doctor", doctorCommand(context))); } function doctorCommand(context) { return async () => { const { document } = await import_coc.workspace.getCurrentState(); const filePath = import_coc.Uri.parse(document.uri).fsPath; if (!filePath.endsWith(".vue")) { return import_coc.window.showInformationMessage("Failed to doctor. Make sure the current file is a .vue file."); } const clientJSON = import_path.default.join(context.extensionPath, "package.json"); const clientPackage = JSON.parse(import_fs.default.readFileSync(clientJSON, "utf8")); const serverJSON = import_path.default.join(context.extensionPath, "node_modules", "@vue", "language-server", "package.json"); const serverPackage = JSON.parse(import_fs.default.readFileSync(serverJSON, "utf8")); let vueVersion; let vueRuntimeDomVersion; let vueTscVersion; if (import_coc.workspace.workspaceFolders) { for (const folder of import_coc.workspace.workspaceFolders) { const pnpmPackagesDirNames = getDirectoryItemNames( import_path.default.join(import_coc.Uri.parse(folder.uri).fsPath, "node_modules", ".pnpm") ); const vuePackageJsonPath = import_path.default.join(import_coc.Uri.parse(folder.uri).fsPath, "node_modules", "vue", "package.json"); const vueRuntimeDomPackageJsonPath = import_path.default.join( import_coc.Uri.parse(folder.uri).fsPath, "node_modules", "@vue", "runtime-dom", "package.json" ); const vueTscVersionPackageJsonPath = import_path.default.join( import_coc.Uri.parse(folder.uri).fsPath, "node_modules", "vue-tsc", "package.json" ); if (import_fs.default.existsSync(vuePackageJsonPath)) { vueVersion = getPackageVersionFromJson(vuePackageJsonPath); } if (import_fs.default.existsSync(vueRuntimeDomPackageJsonPath)) { vueRuntimeDomVersion = getPackageVersionFromJson(vueRuntimeDomPackageJsonPath); } if (!vueRuntimeDomVersion) { vueRuntimeDomVersion = getPackageVersionFromDirectoryName(pnpmPackagesDirNames, /^@vue\+runtime-dom@.*$/); } if (import_fs.default.existsSync(vueTscVersionPackageJsonPath)) { vueTscVersion = getPackageVersionFromJson(vueTscVersionPackageJsonPath); } } } let tsVersion; const tsdkPath = context.workspaceState.get("coc-volar-tsdk-path"); if (tsdkPath) { const typescriptPackageJsonPath = import_path.default.join(import_path.default.resolve(import_path.default.dirname(tsdkPath), ".."), "package.json"); if (import_fs.default.existsSync(typescriptPackageJsonPath)) { tsVersion = getPackageVersionFromJson(typescriptPackageJsonPath); } } const doctorData = { name: "Volar doctor info", filePath, clientVersion: clientPackage.version, serverVersion: serverPackage.version, vueVersion: vueVersion === void 0 ? "none" : vueVersion, vueRuntimeDomVersion: vueRuntimeDomVersion === void 0 ? "none" : vueRuntimeDomVersion, vueTscVersion: vueTscVersion === void 0 ? "none" : vueTscVersion, tsVersion, tsdkPath, settings: { volar: { ...import_coc.workspace.getConfiguration("volar") }, vue: { ...import_coc.workspace.getConfiguration("vue") } } }; const outputText = JSON.stringify(doctorData, null, 2); await import_coc.workspace.nvim.command("belowright vnew volar-doctor | setlocal buftype=nofile bufhidden=hide noswapfile filetype=json").then(async () => { const buf = await import_coc.workspace.nvim.buffer; buf.setLines(outputText.split("\n"), { start: 0, end: -1 }); }); }; } function getPackageVersionFromJson(packageJsonPath) { let version; try { const packageJsonText = import_fs.default.readFileSync(packageJsonPath, "utf8"); const packageJson = JSON.parse(packageJsonText); version = packageJson.version; } catch { } return version; } function getDirectoryItemNames(dirPath) { let a = []; try { a = import_fs.default.readdirSync(dirPath); } catch { return void 0; } return a; } function getPackageVersionFromDirectoryName(items, regex) { let r; if (items) { items.forEach((v) => { const m = v.match(regex); if (m) { v = v.replace(/^@/, ""); r = v.split("@")[1]; } }); } return r; } // src/client/completions/scaffoldSnippets.ts var import_coc2 = require("coc.nvim"); var import_fs2 = __toESM(require("fs")); var import_path2 = __toESM(require("path")); async function register2(context) { if (import_coc2.workspace.getConfiguration("volar").get("scaffoldSnippets.enable")) { context.subscriptions.push( import_coc2.languages.registerCompletionItemProvider( "volar", "volar", ["vue"], new scaffoldSnippetsCompletionProvider(context) ) ); } } var scaffoldSnippetsCompletionProvider = class { constructor(context) { this._context = context; this.snippetsFilePaths = [import_path2.default.join(this._context.extensionPath, "snippets", "vue.code-snippets")]; } async getSnippetsCompletionItems(snippetsFilePath) { const snippetsCompletionList = []; if (import_fs2.default.existsSync(snippetsFilePath)) { const snippetsJsonText = import_fs2.default.readFileSync(snippetsFilePath, "utf8"); const snippetsJson = JSON.parse(snippetsJsonText); if (snippetsJson) { Object.keys(snippetsJson).map((key) => { let snippetsText; const body = snippetsJson[key].body; if (body instanceof Array) { snippetsText = body.join("\n"); } else { snippetsText = body; } snippetsCompletionList.push({ label: snippetsJson[key].prefix, kind: import_coc2.CompletionItemKind.Snippet, filterText: snippetsJson[key].prefix, detail: snippetsJson[key].description, documentation: { kind: "markdown", value: "```vue\n" + snippetsText + "\n```" }, insertTextFormat: import_coc2.InsertTextFormat.Snippet, // The "snippetsText" that will eventually be added to the insertText // will be stored in the "data" key data: snippetsText }); }); } } return snippetsCompletionList; } async provideCompletionItems(document, position, token, context) { if (position.line !== 0) return []; const doc = import_coc2.workspace.getDocument(document.uri); if (!doc) return []; const completionItemList = []; this.snippetsFilePaths.forEach((v) => { this.getSnippetsCompletionItems(v).then((vv) => completionItemList.push(...vv)); }); return completionItemList; } async resolveCompletionItem(item) { if (item.kind === import_coc2.CompletionItemKind.Snippet) { item.insertText = item.data; } return item; } }; // src/features/tsVersion.ts var import_coc3 = require("coc.nvim"); var import_fs3 = __toESM(require("fs")); var import_path3 = __toESM(require("path")); var defaultTsdk = "node_modules/typescript/lib"; function getCurrentTsPaths(context) { if (getConfigUseWorkspaceTsdk()) { const workspaceTsPaths = getWorkspaceTsPaths(true); if (workspaceTsPaths) { return { ...workspaceTsPaths, isWorkspacePath: true }; } } const builtinTsPaths = { tsdk: import_path3.default.join(context.extensionPath, "node_modules", "typescript", "lib") }; return { ...builtinTsPaths, isWorkspacePath: false }; } function getWorkspaceTsPaths(useDefault = false) { let tsdk = getConfigCocTsserverTsdk(); if (!tsdk && useDefault) { tsdk = defaultTsdk; } if (tsdk) { const tsPath = getWorkspaceTypescriptPath( tsdk, import_coc3.workspace.workspaceFolders.map((folder) => import_coc3.Uri.parse(folder.uri).fsPath) ); if (tsPath) { return { tsdk: tsPath }; } } } function getWorkspaceTypescriptPath(tsdk, workspaceFolderFsPaths) { if (import_path3.default.isAbsolute(tsdk)) { const tsPath = findTypescriptModulePathInLib(tsdk); if (tsPath) { return tsPath; } } else { for (const folder of workspaceFolderFsPaths) { const tsPath = findTypescriptModulePathInLib(import_path3.default.join(folder, tsdk)); if (tsPath) { return tsPath; } } } } function findTypescriptModulePathInLib(lib) { if (import_fs3.default.existsSync(lib)) { return lib; } } function getConfigUseWorkspaceTsdk() { return import_coc3.workspace.getConfiguration("volar").get("useWorkspaceTsdk", false); } function getConfigCocTsserverTsdk() { return import_coc3.workspace.getConfiguration("tsserver").get("tsdk"); } // src/config.ts var import_coc4 = require("coc.nvim"); var _config = () => import_coc4.workspace.getConfiguration("vue"); var config = { get server() { return _config().get("server"); }, get codeActions() { return _config().get("codeActions"); }, get codeLens() { return _config().get("codeLens"); }, get complete() { return _config().get("complete"); } }; function getConfigVolarEnable() { return import_coc4.workspace.getConfiguration("volar").get("enable", true); } function getConfigDisableProgressNotifications() { return import_coc4.workspace.getConfiguration("volar").get("disableProgressNotifications", false); } function getConfigMiddlewareProvideCompletionItemEnable() { return import_coc4.workspace.getConfiguration("volar").get("middleware.provideCompletionItem.enable", true); } function getDisabledFeatures() { const disabledFeatures = []; if (import_coc4.workspace.getConfiguration("volar").get("disableCompletion")) { disabledFeatures.push("completion"); } if (import_coc4.workspace.getConfiguration("volar").get("disableDiagnostics")) { disabledFeatures.push("diagnostics"); } if (import_coc4.workspace.getConfiguration("volar").get("disableFormatting")) { disabledFeatures.push("formatting"); disabledFeatures.push("documentFormatting"); disabledFeatures.push("documentRangeFormatting"); } if (!config.codeActions.enabled) { disabledFeatures.push("codeAction"); } if (!config.codeLens.enabled) { disabledFeatures.push("codeLens"); } if (getConfigDisableProgressNotifications()) { disabledFeatures.push("progress"); } return disabledFeatures; } // src/common.ts var client; var resolveCurrentTsPaths; var activated; async function activate(context, createLc) { if (!activated) { const { document } = await import_coc5.workspace.getCurrentState(); const currentLangId = document.languageId; if (currentLangId === "vue") { doActivate(context, createLc); activated = true; } } import_coc5.workspace.onDidOpenTextDocument( async () => { if (activated) return; const { document } = await import_coc5.workspace.getCurrentState(); const currentlangId = document.languageId; if (currentlangId === "vue") { doActivate(context, createLc); activated = true; } }, null, context.subscriptions ); } var enabledHybridMode = config.server.hybridMode; async function doActivate(context, createLc) { initializeWorkspaceState(context); const outputChannel = import_coc5.window.createOutputChannel("Vue Language Server"); client = createLc( "vue", "Vue", getDocumentSelector(), await getInitializationOptions(context, enabledHybridMode), 6009, outputChannel ); activateRestartRequest(); register(context); register2(context); async function activateRestartRequest() { context.subscriptions.push( import_coc5.commands.registerCommand("vue.action.restartServer", async () => { await client.stop(); outputChannel.clear(); client.clientOptions.initializationOptions = await getInitializationOptions(context, enabledHybridMode); await client.start(); }) ); } } function deactivate() { return client == null ? void 0 : client.stop(); } function getDocumentSelector() { const selectors = []; selectors.push({ language: "vue" }); return selectors; } async function getInitializationOptions(context, hybridMode) { if (!resolveCurrentTsPaths) { resolveCurrentTsPaths = getCurrentTsPaths(context); context.workspaceState.update("coc-volar-tsdk-path", resolveCurrentTsPaths.tsdk); } return { typescript: resolveCurrentTsPaths, vue: { hybridMode } }; } function initializeWorkspaceState(context) { context.workspaceState.update("coc-volar-tsdk-path", void 0); } // src/index.ts var serverModule; async function activate2(context) { if (!getConfigVolarEnable()) return; const cocTypeScriptVuePlugin = import_coc6.extensions.getExtensionById("@yaegassy/coc-typescript-vue-plugin"); if (cocTypeScriptVuePlugin) { import_coc6.window.showWarningMessage( "Please uninstall @yaegassy/coc-typescript-vue-plugin as it has been deprecated. :CocUninstall @yaegassy/coc-typescript-vue-plugin" ); return; } let tsExtension = import_coc6.extensions.getExtensionById("coc-tsserver"); if (!tsExtension) { tsExtension = import_coc6.extensions.getExtensionById("coc-tsserver-dev"); } if (tsExtension) { if (!tsExtension.isActive) await tsExtension.activate(); const tsService = import_coc6.services.getService("tsserver"); if (tsService) await tsService.start(); } return activate(context, (id, name, documentSelector, initOptions, port, outputChannel) => { class _LanguageClient extends import_coc6.LanguageClient { fillInitializeParams(params) { params.locale = import_coc6.workspace.getConfiguration("volar").get("tsLocale", "en"); } } const vueServerPath = config.server.path ? import_coc6.workspace.expand(config.server.path) : null; if (vueServerPath != null && fs4.existsSync(vueServerPath)) { serverModule = vueServerPath; } else { serverModule = context.asAbsolutePath( path4.join("node_modules", "@vue", "language-server", "bin", "vue-language-server.js") ); } const runOptions = {}; if (config.server.maxOldSpaceSize) { runOptions.execArgv ?? (runOptions.execArgv = []); runOptions.execArgv.push("--max-old-space-size=" + config.server.maxOldSpaceSize); } const debugOptions = { execArgv: ["--nolazy", "--inspect=" + port] }; const serverOptions = { run: { module: serverModule, transport: import_coc6.TransportKind.ipc, options: runOptions }, debug: { module: serverModule, transport: import_coc6.TransportKind.ipc, options: debugOptions } }; const clientOptions = { documentSelector, initializationOptions: initOptions, progressOnInitialization: !getConfigDisableProgressNotifications(), disabledFeatures: getDisabledFeatures(), middleware: { provideCompletionItem: getConfigMiddlewareProvideCompletionItemEnable() ? id === "vue" ? handleProvideCompletionItem : void 0 : void 0 }, outputChannel }; const client2 = new _LanguageClient(id, name, serverOptions, clientOptions); context.subscriptions.push(import_coc6.services.registLanguageClient(client2)); return client2; }); } function deactivate2() { return deactivate(); } async function handleProvideCompletionItem(document, position, context, token, next) { const res = await Promise.resolve(next(document, position, context, token)); const doc = import_coc6.workspace.getDocument(document.uri); if (!doc || !res) return []; let items = res.hasOwnProperty("isIncomplete") ? res.items : res; const pre = doc.getline(position.line).slice(0, position.character); if (context.triggerCharacter === "@" || /@\w*$/.test(pre)) { items = items.filter((o) => o.label.startsWith("@")); } return items; } // Annotate the CommonJS export names for ESM import in node: 0 && (module.exports = { activate, deactivate });