@yaegassy/coc-volar
Version:
Volar (Fast Vue Language Support) extension for coc.nvim
509 lines (500 loc) • 18.2 kB
JavaScript
;
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
});