From dc90036b098bab08ddce8672c9c30d4dd35ae9f0 Mon Sep 17 00:00:00 2001 From: Yuyao Nie Date: Sat, 7 Dec 2024 18:28:33 +0800 Subject: [PATCH] fix(vscode): update `enabledHybridMode` before activate extension (#5019) Co-authored-by: KazariEX <1364035137@qq.com> --- extensions/vscode/src/features/doctor.ts | 4 +- extensions/vscode/src/hybridMode.ts | 229 ++++++++++++----------- extensions/vscode/src/insiders.ts | 80 ++++---- extensions/vscode/src/languageClient.ts | 3 +- extensions/vscode/src/nodeClientMain.ts | 3 +- 5 files changed, 166 insertions(+), 153 deletions(-) diff --git a/extensions/vscode/src/features/doctor.ts b/extensions/vscode/src/features/doctor.ts index 8db6272f9a..db637d9dd8 100644 --- a/extensions/vscode/src/features/doctor.ts +++ b/extensions/vscode/src/features/doctor.ts @@ -157,12 +157,12 @@ export async function activate(client: BaseLanguageClient) { '', '- package.json', '```json', - JSON.stringify({ devDependencies: { "@vue/language-plugin-pug": "latest" } }, undefined, 2), + JSON.stringify({ devDependencies: { '@vue/language-plugin-pug': 'latest' } }, undefined, 2), '```', '', '- tsconfig.json / jsconfig.json', '```jsonc', - JSON.stringify({ vueCompilerOptions: { plugins: ["@vue/language-plugin-pug"] } }, undefined, 2), + JSON.stringify({ vueCompilerOptions: { plugins: ['@vue/language-plugin-pug'] } }, undefined, 2), '```', ].join('\n'), }); diff --git a/extensions/vscode/src/hybridMode.ts b/extensions/vscode/src/hybridMode.ts index 38fc895891..606b8b2775 100644 --- a/extensions/vscode/src/hybridMode.ts +++ b/extensions/vscode/src/hybridMode.ts @@ -1,6 +1,6 @@ import * as fs from 'node:fs'; import * as path from 'node:path'; -import { computed, executeCommand, ref, useAllExtensions, useVscodeContext, watchEffect } from "reactive-vscode"; +import { computed, executeCommand, useAllExtensions, useVscodeContext, watchEffect } from 'reactive-vscode'; import * as semver from 'semver'; import * as vscode from 'vscode'; import { incompatibleExtensions, unknownExtensions } from './compatibility'; @@ -8,31 +8,51 @@ import { config } from './config'; const extensions = useAllExtensions(); -export const enabledHybridMode = ref(true); +export const enabledHybridMode = computed(() => { + if (config.server.hybridMode === 'typeScriptPluginOnly') { + return false; + } + else if (config.server.hybridMode === 'auto') { + if ( + incompatibleExtensions.value.length || + unknownExtensions.value.length + ) { + return false; + } + else if ( + (vscodeTsdkVersion.value && !semver.gte(vscodeTsdkVersion.value, '5.3.0')) || + (workspaceTsdkVersion.value && !semver.gte(workspaceTsdkVersion.value, '5.3.0')) + ) { + return false; + } + return true; + } + return config.server.hybridMode; +}) export const enabledTypeScriptPlugin = computed(() => { return ( enabledHybridMode.value || - config.server.hybridMode === "typeScriptPluginOnly" + config.server.hybridMode === 'typeScriptPluginOnly' ); }); const vscodeTsdkVersion = computed(() => { const nightly = extensions.value.find( - ({ id }) => id === "ms-vscode.vscode-typescript-next" + ({ id }) => id === 'ms-vscode.vscode-typescript-next' ); if (nightly) { const libPath = path.join( - nightly.extensionPath.replace(/\\/g, "/"), - "node_modules/typescript/lib" + nightly.extensionPath.replace(/\\/g, '/'), + 'node_modules/typescript/lib' ); return getTsVersion(libPath); } if (vscode.env.appRoot) { const libPath = path.join( - vscode.env.appRoot.replace(/\\/g, "/"), - "extensions/node_modules/typescript/lib" + vscode.env.appRoot.replace(/\\/g, '/'), + 'extensions/node_modules/typescript/lib' ); return getTsVersion(libPath); } @@ -40,127 +60,111 @@ const vscodeTsdkVersion = computed(() => { const workspaceTsdkVersion = computed(() => { const libPath = vscode.workspace - .getConfiguration("typescript") - .get("tsdk") - ?.replace(/\\/g, "/"); + .getConfiguration('typescript') + .get('tsdk') + ?.replace(/\\/g, '/'); if (libPath) { return getTsVersion(libPath); } }); export function useHybridModeTips() { - useVscodeContext("vueHybridMode", enabledHybridMode); + useVscodeContext('vueHybridMode', enabledHybridMode); watchEffect(() => { - switch (config.server.hybridMode) { - case "typeScriptPluginOnly": { - enabledHybridMode.value = false; - break; - } - case "auto": { - if ( - incompatibleExtensions.value.length || - unknownExtensions.value.length - ) { - vscode.window - .showInformationMessage( - `Hybrid Mode is disabled automatically because there is a potentially incompatible ${[ - ...incompatibleExtensions.value, - ...unknownExtensions.value, - ].join(", ")} TypeScript plugin installed.`, - "Open Settings", - "Report a false positive" - ) - .then(value => { - if (value === "Open Settings") { - executeCommand( - "workbench.action.openSettings", - "vue.server.hybridMode" - ); - } - else if (value == "Report a false positive") { - vscode.env.openExternal( - vscode.Uri.parse( - "https://github.com/vuejs/language-tools/pull/4206" - ) - ); - } - }); - enabledHybridMode.value = false; - } - else if ( - (vscodeTsdkVersion.value && !semver.gte(vscodeTsdkVersion.value, "5.3.0")) || - (workspaceTsdkVersion.value && !semver.gte(workspaceTsdkVersion.value, "5.3.0")) - ) { - let msg = `Hybrid Mode is disabled automatically because TSDK >= 5.3.0 is required (VSCode TSDK: ${vscodeTsdkVersion.value}`; - if (workspaceTsdkVersion.value) { - msg += `, Workspace TSDK: ${workspaceTsdkVersion.value}`; - } - msg += `).`; - vscode.window - .showInformationMessage(msg, "Open Settings") - .then(value => { - if (value === "Open Settings") { - executeCommand( - "workbench.action.openSettings", - "vue.server.hybridMode" - ); - } - }); - enabledHybridMode.value = false; - } else { - enabledHybridMode.value = true; - } - break; + if (config.server.hybridMode === 'auto') { + if ( + incompatibleExtensions.value.length || + unknownExtensions.value.length + ) { + vscode.window + .showInformationMessage( + `Hybrid Mode is disabled automatically because there is a potentially incompatible ${[ + ...incompatibleExtensions.value, + ...unknownExtensions.value, + ].join(', ')} TypeScript plugin installed.`, + 'Open Settings', + 'Report a false positive' + ) + .then(value => { + if (value === 'Open Settings') { + executeCommand( + 'workbench.action.openSettings', + 'vue.server.hybridMode' + ); + } + else if (value == 'Report a false positive') { + vscode.env.openExternal( + vscode.Uri.parse( + 'https://github.com/vuejs/language-tools/pull/4206' + ) + ); + } + }); } - default: { - if ( - config.server.hybridMode && - incompatibleExtensions.value.length - ) { - vscode.window - .showWarningMessage( - `You have explicitly enabled Hybrid Mode, but you have installed known incompatible extensions: ${incompatibleExtensions.value.join( - ", " - )}. You may want to change vue.server.hybridMode to "auto" to avoid compatibility issues.`, - "Open Settings", - "Report a false positive" - ) - .then(value => { - if (value === "Open Settings") { - executeCommand( - "workbench.action.openSettings", - "vue.server.hybridMode" - ); - } else if (value == "Report a false positive") { - vscode.env.openExternal( - vscode.Uri.parse( - "https://github.com/vuejs/language-tools/pull/4206" - ) - ); - } - }); + else if ( + (vscodeTsdkVersion.value && !semver.gte(vscodeTsdkVersion.value, '5.3.0')) || + (workspaceTsdkVersion.value && !semver.gte(workspaceTsdkVersion.value, '5.3.0')) + ) { + let msg = `Hybrid Mode is disabled automatically because TSDK >= 5.3.0 is required (VSCode TSDK: ${vscodeTsdkVersion.value}`; + if (workspaceTsdkVersion.value) { + msg += `, Workspace TSDK: ${workspaceTsdkVersion.value}`; } - enabledHybridMode.value = config.server.hybridMode; + msg += `).`; + vscode.window + .showInformationMessage(msg, 'Open Settings') + .then(value => { + if (value === 'Open Settings') { + executeCommand( + 'workbench.action.openSettings', + 'vue.server.hybridMode' + ); + } + }); } } + else if (config.server.hybridMode && incompatibleExtensions.value.length) { + vscode.window + .showWarningMessage( + `You have explicitly enabled Hybrid Mode, but you have installed known incompatible extensions: ${incompatibleExtensions.value.join( + ', ' + )}. You may want to change vue.server.hybridMode to "auto" to avoid compatibility issues.`, + 'Open Settings', + 'Report a false positive' + ) + .then(value => { + if (value === 'Open Settings') { + executeCommand( + 'workbench.action.openSettings', + 'vue.server.hybridMode' + ); + } + else if (value == 'Report a false positive') { + vscode.env.openExternal( + vscode.Uri.parse( + 'https://github.com/vuejs/language-tools/pull/4206' + ) + ); + } + }); + } }); } export function useHybridModeStatusItem() { const item = vscode.languages.createLanguageStatusItem( - "vue-hybrid-mode", + 'vue-hybrid-mode', config.server.includeLanguages ); - item.text = "Hybrid Mode"; + item.text = 'Hybrid Mode'; item.detail = - (enabledHybridMode.value ? "Enabled" : "Disabled") + - (config.server.hybridMode === "auto" ? " (Auto)" : ""); + (enabledHybridMode.value ? 'Enabled' : 'Disabled') + + (config.server.hybridMode === 'auto' ? ' (Auto)' : ''); item.command = { - title: "Open Setting", - command: "workbench.action.openSettings", - arguments: ["vue.server.hybridMode"], + title: 'Open Setting', + command: 'workbench.action.openSettings', + arguments: ['vue.server.hybridMode'], }; if (!enabledHybridMode.value) { @@ -170,11 +174,11 @@ export function useHybridModeStatusItem() { function getTsVersion(libPath: string) { try { - const p = libPath.toString().split("/"); + const p = libPath.toString().split('/'); const p2 = p.slice(0, -1); - const modulePath = p2.join("/"); - const filePath = modulePath + "/package.json"; - const contents = fs.readFileSync(filePath, "utf-8"); + const modulePath = p2.join('/'); + const filePath = modulePath + '/package.json'; + const contents = fs.readFileSync(filePath, 'utf-8'); if (contents === undefined) { return; @@ -183,7 +187,8 @@ function getTsVersion(libPath: string) { let desc: any = null; try { desc = JSON.parse(contents); - } catch (err) { + } + catch (err) { return; } if (!desc || !desc.version) { diff --git a/extensions/vscode/src/insiders.ts b/extensions/vscode/src/insiders.ts index a0ccd80075..33fda238cd 100644 --- a/extensions/vscode/src/insiders.ts +++ b/extensions/vscode/src/insiders.ts @@ -1,10 +1,10 @@ -import { quickPick } from "@volar/vscode/lib/common"; +import { quickPick } from '@volar/vscode/lib/common'; import { executeCommand, useCommand } from 'reactive-vscode'; import * as vscode from 'vscode'; export function useInsidersStatusItem(context: vscode.ExtensionContext) { - const item = vscode.languages.createLanguageStatusItem("vue-insider", "vue"); - item.text = "Checking for Updates..."; + const item = vscode.languages.createLanguageStatusItem('vue-insider', 'vue'); + item.text = 'Checking for Updates...'; item.busy = true; let succeed = false; @@ -12,8 +12,8 @@ export function useInsidersStatusItem(context: vscode.ExtensionContext) { async function fetchJson() { for (const url of [ - "https://raw.githubusercontent.com/vuejs/language-tools/HEAD/insiders.json", - "https://cdn.jsdelivr.net/gh/vuejs/language-tools/insiders.json", + 'https://raw.githubusercontent.com/vuejs/language-tools/HEAD/insiders.json', + 'https://cdn.jsdelivr.net/gh/vuejs/language-tools/insiders.json', ]) { try { const res = await fetch(url); @@ -26,7 +26,7 @@ export function useInsidersStatusItem(context: vscode.ExtensionContext) { item.busy = false; if (!succeed) { - item.text = "Failed to Fetch Versions"; + item.text = 'Failed to Fetch Versions'; item.severity = vscode.LanguageStatusSeverity.Error; } } @@ -44,40 +44,40 @@ export function useInsidersStatusItem(context: vscode.ExtensionContext) { }) { item.detail = undefined; item.command = { - title: "Select Version", - command: "vue-insiders.update", + title: 'Select Version', + command: 'vue-insiders.update', }; if ( json.versions.some( version => version.version === context.extension.packageJSON.version ) ) { - item.text = "🚀 Insiders Edition"; + item.text = '🚀 Insiders Edition'; item.severity = vscode.LanguageStatusSeverity.Information; if (context.extension.packageJSON.version !== json.latest) { - item.detail = "New Version Available!"; + item.detail = 'New Version Available!'; item.severity = vscode.LanguageStatusSeverity.Warning; vscode.window - .showInformationMessage("New Insiders Version Available!", "Download") + .showInformationMessage('New Insiders Version Available!', 'Download') .then(download => { if (download) { - executeCommand("vue-insiders.update"); + executeCommand('vue-insiders.update'); } }); } } else { - item.text = "✨ Get Insiders Edition"; + item.text = '✨ Get Insiders Edition'; item.severity = vscode.LanguageStatusSeverity.Warning; } - useCommand("vue-insiders.update", async () => { + useCommand('vue-insiders.update', async () => { const quickPickItems: { [version: string]: vscode.QuickPickItem; } = {}; for (const { version, date } of json.versions) { let description = date; if (context.extension.packageJSON.version === version) { - description += " (current)"; + description += ' (current)'; } quickPickItems[version] = { label: version, @@ -88,31 +88,34 @@ export function useInsidersStatusItem(context: vscode.ExtensionContext) { quickPickItems, { learnMore: { - label: "Learn more about Insiders Edition", + label: 'Learn more about Insiders Edition', }, joinViaGitHub: { - label: "Join via GitHub Sponsors", + label: 'Join via GitHub Sponsors', }, joinViaAFDIAN: { - label: "Join via AFDIAN (爱发电)", + label: 'Join via AFDIAN (爱发电)', }, }, ]); - if (version === "learnMore") { + if (version === 'learnMore') { vscode.env.openExternal( vscode.Uri.parse( - "https://github.com/vuejs/language-tools/wiki/Get-Insiders-Edition" + 'https://github.com/vuejs/language-tools/wiki/Get-Insiders-Edition' ) ); - } else if (version === "joinViaGitHub") { + } + else if (version === 'joinViaGitHub') { vscode.env.openExternal( - vscode.Uri.parse("https://github.com/sponsors/johnsoncodehk") + vscode.Uri.parse('https://github.com/sponsors/johnsoncodehk') ); - } else if (version === "joinViaAFDIAN") { + } + else if (version === 'joinViaAFDIAN') { vscode.env.openExternal( - vscode.Uri.parse("https://afdian.net/a/johnsoncodehk") + vscode.Uri.parse('https://afdian.net/a/johnsoncodehk') ); - } else { + } + else { const downloads = json.versions.find( v => v.version === version )?.downloads; @@ -120,42 +123,45 @@ export function useInsidersStatusItem(context: vscode.ExtensionContext) { const quickPickItems: { [key: string]: vscode.QuickPickItem; } = { GitHub: { label: `${version} - GitHub Releases`, - description: "Access via GitHub Sponsors", + description: 'Access via GitHub Sponsors', detail: downloads.GitHub, }, AFDIAN: { label: `${version} - Insiders 电圈`, - description: "Access via AFDIAN (爱发电)", + description: 'Access via AFDIAN (爱发电)', detail: downloads.AFDIAN, }, }; const otherItems: { [key: string]: vscode.QuickPickItem; } = { learnMore: { - label: "Learn more about Insiders Edition", + label: 'Learn more about Insiders Edition', }, joinViaGitHub: { - label: "Join via GitHub Sponsors", + label: 'Join via GitHub Sponsors', }, joinViaAFDIAN: { - label: "Join via AFDIAN (爱发电)", + label: 'Join via AFDIAN (爱发电)', }, }; const option = await quickPick([quickPickItems, otherItems]); - if (option === "learnMore") { + if (option === 'learnMore') { vscode.env.openExternal( vscode.Uri.parse( - "https://github.com/vuejs/language-tools/wiki/Get-Insiders-Edition" + 'https://github.com/vuejs/language-tools/wiki/Get-Insiders-Edition' ) ); - } else if (option === "joinViaGitHub") { + } + else if (option === 'joinViaGitHub') { vscode.env.openExternal( - vscode.Uri.parse("https://github.com/sponsors/johnsoncodehk") + vscode.Uri.parse('https://github.com/sponsors/johnsoncodehk') ); - } else if (option === "joinViaAFDIAN") { + } + else if (option === 'joinViaAFDIAN') { vscode.env.openExternal( - vscode.Uri.parse("https://afdian.net/a/johnsoncodehk") + vscode.Uri.parse('https://afdian.net/a/johnsoncodehk') ); - } else if (option) { + } + else if (option) { vscode.env.openExternal( vscode.Uri.parse(downloads[option as keyof typeof downloads]) ); diff --git a/extensions/vscode/src/languageClient.ts b/extensions/vscode/src/languageClient.ts index e7948f40d9..01b2c7ff16 100644 --- a/extensions/vscode/src/languageClient.ts +++ b/extensions/vscode/src/languageClient.ts @@ -76,7 +76,8 @@ async function activateLc( requestReloadVscode( `Please reload VSCode to ${newValues[0] ? 'enable' : 'disable'} Hybrid Mode.` ); - } else if (newValues[1] !== oldValues[1]) { + } + else if (newValues[1] !== oldValues[1]) { requestReloadVscode( `Please reload VSCode to ${newValues[1] ? 'enable' : 'disable'} Vue TypeScript Plugin.` ); diff --git a/extensions/vscode/src/nodeClientMain.ts b/extensions/vscode/src/nodeClientMain.ts index 56960d104d..a828f15028 100644 --- a/extensions/vscode/src/nodeClientMain.ts +++ b/extensions/vscode/src/nodeClientMain.ts @@ -152,7 +152,8 @@ try { 'for(const e of n.contributes.typescriptServerPlugins', s => s + `.filter(p=>p.name!=='vue-typescript-plugin-pack')` ); - } else if (enabledHybridMode.value) { + } + else if (enabledHybridMode.value) { // patch readPlugins text = text.replace( 'languages:Array.isArray(e.languages)',