Skip to content

Commit 423bb6b

Browse files
KazariEXkermanx
andcommitted
refactor: split
Co-authored-by: _Kerman <[email protected]>
1 parent 306d3c9 commit 423bb6b

File tree

8 files changed

+581
-441
lines changed

8 files changed

+581
-441
lines changed

extensions/vscode/src/common.ts

+120-402
Large diffs are not rendered by default.
+49
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
import * as vscode from 'vscode';
2+
import * as semver from 'semver';
3+
import { computed, useAllExtensions } from 'reactive-vscode';
4+
5+
const extensions = useAllExtensions();
6+
7+
export const incompatibleExtensions = computed(() => {
8+
return extensions.value
9+
.filter((ext) => isExtensionCompatibleWithHybridMode(ext) === false)
10+
.map((ext) => ext.id);
11+
});
12+
13+
export const unknownExtensions = computed(() => {
14+
return extensions.value
15+
.filter((ext) => isExtensionCompatibleWithHybridMode(ext) === undefined && !!ext.packageJSON?.contributes?.typescriptServerPlugins)
16+
.map((ext) => ext.id);
17+
});
18+
19+
20+
function isExtensionCompatibleWithHybridMode(extension: vscode.Extension<any>) {
21+
if (
22+
extension.id === 'Vue.volar'
23+
|| extension.id === 'unifiedjs.vscode-mdx'
24+
|| extension.id === 'astro-build.astro-vscode'
25+
|| extension.id === 'ije.esm-vscode'
26+
|| extension.id === 'johnsoncodehk.vscode-tsslint'
27+
|| extension.id === 'VisualStudioExptTeam.vscodeintellicode'
28+
|| extension.id === 'bierner.lit-html'
29+
|| extension.id === 'jenkey2011.string-highlight'
30+
|| extension.id === 'mxsdev.typescript-explorer'
31+
|| extension.id === 'miaonster.vscode-tsx-arrow-definition'
32+
|| extension.id === 'runem.lit-plugin'
33+
|| extension.id === 'kimuson.ts-type-expand'
34+
|| extension.id === 'p42ai.refactor'
35+
|| extension.id === 'styled-components.vscode-styled-components'
36+
|| extension.id === 'Divlo.vscode-styled-jsx-languageserver'
37+
|| extension.id === 'nrwl.angular-console'
38+
|| extension.id === 'ShenQingchuan.vue-vine-extension'
39+
|| extension.id === 'ms-dynamics-smb.al'
40+
) {
41+
return true;
42+
}
43+
if (extension.id === 'denoland.vscode-deno') {
44+
return !vscode.workspace.getConfiguration('deno').get<boolean>('enable');
45+
}
46+
if (extension.id === 'svelte.svelte-vscode') {
47+
return semver.gte(extension.packageJSON.version, '108.4.0');
48+
}
49+
}

extensions/vscode/src/features/doctor.ts

+2-2
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,10 @@
11
import { BaseLanguageClient, ExecuteCommandParams, ExecuteCommandRequest, getTsdk } from '@volar/vscode';
22
import type { SFCParseResult } from '@vue/language-server';
33
import { commands } from '@vue/language-server/lib/types';
4+
import { executeCommand, useActiveTextEditor, useCommand, useEventEmitter, useStatusBarItem, watch } from 'reactive-vscode';
45
import * as semver from 'semver';
56
import * as vscode from 'vscode';
67
import { config } from '../config';
7-
import { executeCommand, useActiveTextEditor, useCommand, useEventEmitter, useStatusBarItem, watch } from 'reactive-vscode';
88

99
const scheme = 'vue-doctor';
1010
const knownValidSyntaxHighlightExtensions = {
@@ -13,7 +13,7 @@ const knownValidSyntaxHighlightExtensions = {
1313
sass: ['Syler.sass-indented'],
1414
};
1515

16-
export async function register(context: vscode.ExtensionContext, client: BaseLanguageClient) {
16+
export async function activate(context: vscode.ExtensionContext, client: BaseLanguageClient) {
1717

1818
const item = useStatusBarItem({
1919
alignment: vscode.StatusBarAlignment.Right,

extensions/vscode/src/features/nameCasing.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,9 @@
11
import { BaseLanguageClient, ExecuteCommandParams, ExecuteCommandRequest, TextEdit } from '@volar/vscode';
22
import { quickPick } from '@volar/vscode/lib/common';
33
import { AttrNameCasing, TagNameCasing, commands } from '@vue/language-server/lib/types';
4+
import { ref, useActiveTextEditor, useCommand, watch } from 'reactive-vscode';
45
import * as vscode from 'vscode';
56
import { config } from '../config';
6-
import { ref, useActiveTextEditor, useCommand, watch } from 'reactive-vscode';
77

88
export const attrNameCasings = ref(new Map<string, AttrNameCasing>());
99
export const tagNameCasings = ref(new Map<string, TagNameCasing>());

extensions/vscode/src/features/splitEditors.ts

+2-2
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,13 @@
11
import { ExecuteCommandParams, ExecuteCommandRequest, type BaseLanguageClient } from '@volar/vscode';
22
import type { SFCParseResult } from '@vue/language-server';
33
import { commands } from '@vue/language-server/lib/types';
4+
import { executeCommand, useActiveTextEditor, useCommand } from 'reactive-vscode';
45
import * as vscode from 'vscode';
56
import { config } from '../config';
6-
import { executeCommand, useActiveTextEditor, useCommand } from 'reactive-vscode';
77

88
type SFCBlock = SFCParseResult['descriptor']['customBlocks'][number];
99

10-
export function register(client: BaseLanguageClient) {
10+
export function activate(client: BaseLanguageClient) {
1111

1212
const activeTextEditor = useActiveTextEditor();
1313
const getDocDescriptor = useDocDescriptor(client);

extensions/vscode/src/hybridMode.ts

+195
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,195 @@
1+
import * as path from 'node:path';
2+
import * as fs from 'node:fs';
3+
import * as semver from 'semver';
4+
import * as vscode from 'vscode';
5+
import { computed, executeCommand, ref, useAllExtensions, useVscodeContext, watchEffect } from "reactive-vscode";
6+
import { incompatibleExtensions, unknownExtensions } from './compatibility';
7+
import { config } from './config';
8+
9+
const extensions = useAllExtensions();
10+
11+
export const enabledHybridMode = ref<boolean>(true);
12+
13+
export const enabledTypeScriptPlugin = computed(() => {
14+
return (
15+
enabledHybridMode.value ||
16+
config.server.value.hybridMode === "typeScriptPluginOnly"
17+
);
18+
});
19+
20+
const vscodeTsdkVersion = computed(() => {
21+
const nightly = extensions.value.find(
22+
({ id }) => id === "ms-vscode.vscode-typescript-next"
23+
);
24+
if (nightly) {
25+
const libPath = path.join(
26+
nightly.extensionPath.replace(/\\/g, "/"),
27+
"node_modules/typescript/lib"
28+
);
29+
return getTsVersion(libPath);
30+
}
31+
32+
if (vscode.env.appRoot) {
33+
const libPath = path.join(
34+
vscode.env.appRoot.replace(/\\/g, "/"),
35+
"extensions/node_modules/typescript/lib"
36+
);
37+
return getTsVersion(libPath);
38+
}
39+
});
40+
41+
const workspaceTsdkVersion = computed(() => {
42+
const libPath = vscode.workspace
43+
.getConfiguration("typescript")
44+
.get<string>("tsdk")
45+
?.replace(/\\/g, "/");
46+
if (libPath) {
47+
return getTsVersion(libPath);
48+
}
49+
});
50+
51+
export function useHybridModeTips() {
52+
useVscodeContext("vueHybridMode", enabledHybridMode);
53+
54+
watchEffect(() => {
55+
switch (config.server.value.hybridMode) {
56+
case "typeScriptPluginOnly": {
57+
enabledHybridMode.value = false;
58+
break;
59+
}
60+
case "auto": {
61+
if (
62+
incompatibleExtensions.value.length ||
63+
unknownExtensions.value.length
64+
) {
65+
vscode.window
66+
.showInformationMessage(
67+
`Hybrid Mode is disabled automatically because there is a potentially incompatible ${[
68+
...incompatibleExtensions.value,
69+
...unknownExtensions.value,
70+
].join(", ")} TypeScript plugin installed.`,
71+
"Open Settings",
72+
"Report a false positive"
73+
)
74+
.then((value) => {
75+
if (value === "Open Settings") {
76+
executeCommand(
77+
"workbench.action.openSettings",
78+
"vue.server.hybridMode"
79+
);
80+
}
81+
else if (value == "Report a false positive") {
82+
vscode.env.openExternal(
83+
vscode.Uri.parse(
84+
"https://github.com/vuejs/language-tools/pull/4206"
85+
)
86+
);
87+
}
88+
});
89+
enabledHybridMode.value = false;
90+
}
91+
else if (
92+
(vscodeTsdkVersion.value && !semver.gte(vscodeTsdkVersion.value, "5.3.0")) ||
93+
(workspaceTsdkVersion.value && !semver.gte(workspaceTsdkVersion.value, "5.3.0"))
94+
) {
95+
let msg = `Hybrid Mode is disabled automatically because TSDK >= 5.3.0 is required (VSCode TSDK: ${vscodeTsdkVersion.value}`;
96+
if (workspaceTsdkVersion.value) {
97+
msg += `, Workspace TSDK: ${workspaceTsdkVersion.value}`;
98+
}
99+
msg += `).`;
100+
vscode.window
101+
.showInformationMessage(msg, "Open Settings")
102+
.then((value) => {
103+
if (value === "Open Settings") {
104+
executeCommand(
105+
"workbench.action.openSettings",
106+
"vue.server.hybridMode"
107+
);
108+
}
109+
});
110+
enabledHybridMode.value = false;
111+
} else {
112+
enabledHybridMode.value = true;
113+
}
114+
break;
115+
}
116+
default: {
117+
if (
118+
config.server.value.hybridMode &&
119+
incompatibleExtensions.value.length
120+
) {
121+
vscode.window
122+
.showWarningMessage(
123+
`You have explicitly enabled Hybrid Mode, but you have installed known incompatible extensions: ${incompatibleExtensions.value.join(
124+
", "
125+
)}. You may want to change vue.server.hybridMode to "auto" to avoid compatibility issues.`,
126+
"Open Settings",
127+
"Report a false positive"
128+
)
129+
.then((value) => {
130+
if (value === "Open Settings") {
131+
executeCommand(
132+
"workbench.action.openSettings",
133+
"vue.server.hybridMode"
134+
);
135+
} else if (value == "Report a false positive") {
136+
vscode.env.openExternal(
137+
vscode.Uri.parse(
138+
"https://github.com/vuejs/language-tools/pull/4206"
139+
)
140+
);
141+
}
142+
});
143+
}
144+
enabledHybridMode.value = config.server.value.hybridMode;
145+
}
146+
}
147+
});
148+
}
149+
150+
export function useHybridModeStatusItem() {
151+
const item = vscode.languages.createLanguageStatusItem(
152+
"vue-hybrid-mode",
153+
config.server.value.includeLanguages
154+
);
155+
156+
item.text = "Hybrid Mode";
157+
item.detail =
158+
(enabledHybridMode.value ? "Enabled" : "Disabled") +
159+
(config.server.value.hybridMode === "auto" ? " (Auto)" : "");
160+
item.command = {
161+
title: "Open Setting",
162+
command: "workbench.action.openSettings",
163+
arguments: ["vue.server.hybridMode"],
164+
};
165+
166+
if (!enabledHybridMode.value) {
167+
item.severity = vscode.LanguageStatusSeverity.Warning;
168+
}
169+
}
170+
171+
function getTsVersion(libPath: string) {
172+
try {
173+
const p = libPath.toString().split("/");
174+
const p2 = p.slice(0, -1);
175+
const modulePath = p2.join("/");
176+
const filePath = modulePath + "/package.json";
177+
const contents = fs.readFileSync(filePath, "utf-8");
178+
179+
if (contents === undefined) {
180+
return;
181+
}
182+
183+
let desc: any = null;
184+
try {
185+
desc = JSON.parse(contents);
186+
} catch (err) {
187+
return;
188+
}
189+
if (!desc || !desc.version) {
190+
return;
191+
}
192+
193+
return desc.version as string;
194+
} catch { }
195+
}

0 commit comments

Comments
 (0)