-
-
Notifications
You must be signed in to change notification settings - Fork 53
/
languageServerPlugin.ts
123 lines (110 loc) · 4.21 KB
/
languageServerPlugin.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
import {
LanguageServerPlugin,
MessageType,
ShowMessageNotification,
} from '@volar/language-server/node';
import { getLanguageModule } from './core';
import { getSvelteLanguageModule } from './core/svelte.js';
import { getVueLanguageModule } from './core/vue.js';
import { getPrettierPluginPath, importPrettier } from './importPackage.js';
import { getAstroInstall } from './utils.js';
// Services
import { create as createCssService } from 'volar-service-css';
import { create as createEmmetService } from 'volar-service-emmet';
import { create as createPrettierService } from 'volar-service-prettier';
import { create as createTypeScriptTwoSlashService } from 'volar-service-typescript-twoslash-queries';
import { create as createAstroService } from './plugins/astro.js';
import { create as createHtmlService } from './plugins/html.js';
import { create as createTypescriptAddonsService } from './plugins/typescript-addons/index.js';
import { create as createTypeScriptService } from './plugins/typescript/index.js';
export const plugin: LanguageServerPlugin = (
initOptions,
modules
): ReturnType<LanguageServerPlugin> => ({
extraFileExtensions: [
{ extension: 'astro', isMixedContent: true, scriptKind: 7 },
{ extension: 'vue', isMixedContent: true, scriptKind: 7 },
{ extension: 'svelte', isMixedContent: true, scriptKind: 7 },
],
watchFileExtensions: [
'js',
'cjs',
'mjs',
'ts',
'cts',
'mts',
'jsx',
'tsx',
'json',
'astro',
'vue',
'svelte',
],
resolveConfig(config, ctx) {
config.languages ??= {};
if (ctx) {
const astroInstall = getAstroInstall([ctx.project.rootUri.fsPath]);
if (!astroInstall) {
ctx.server.connection.sendNotification(ShowMessageNotification.type, {
message: `Couldn't find Astro in workspace "${ctx.project.rootUri.fsPath}". Experience might be degraded. For the best experience, please make sure Astro is installed into your project and restart the language server.`,
type: MessageType.Warning,
});
}
config.languages.astro = getLanguageModule(astroInstall, modules.typescript!);
config.languages.vue = getVueLanguageModule();
config.languages.svelte = getSvelteLanguageModule();
}
config.services ??= {};
config.services.html ??= createHtmlService();
config.services.css ??= createCssService();
config.services.emmet ??= createEmmetService();
config.services.typescript ??= createTypeScriptService();
config.services.typescripttwoslash ??= createTypeScriptTwoSlashService();
config.services.typescriptaddons ??= createTypescriptAddonsService();
config.services.astro ??= createAstroService();
if (ctx) {
const rootDir = ctx.env.uriToFileName(ctx.project.rootUri.toString());
const prettier = importPrettier(rootDir);
const prettierPluginPath = getPrettierPluginPath(rootDir);
if (prettier && prettierPluginPath) {
config.services.prettier ??= createPrettierService({
prettier: prettier,
languages: ['astro'],
ignoreIdeOptions: true,
useIdeOptionsFallback: true,
resolveConfigOptions: {
// This seems to be broken since Prettier 3, and it'll always use its cumbersome cache. Hopefully it works one day.
useCache: false,
},
additionalOptions: async (resolvedConfig) => {
async function getAstroPrettierPlugin() {
if (!prettier || !prettierPluginPath) {
return [];
}
const hasPluginLoadedAlready =
(await prettier.getSupportInfo()).languages.some((l: any) => l.name === 'astro') ||
resolvedConfig.plugins?.includes('prettier-plugin-astro'); // getSupportInfo doesn't seems to work very well in Prettier 3 for plugins
return hasPluginLoadedAlready ? [] : [prettierPluginPath];
}
const plugins = [
...(await getAstroPrettierPlugin()),
...(resolvedConfig.plugins ?? []),
];
return {
plugins: plugins,
parser: 'astro',
...resolvedConfig,
};
},
});
} else {
ctx.server.connection.sendNotification(ShowMessageNotification.type, {
message:
"Couldn't load `prettier` or `prettier-plugin-astro`. Formatting will not work. Please make sure those two packages are installed into your project.",
type: MessageType.Warning,
});
}
}
return config;
},
});