Skip to content

Commit 51a6d4e

Browse files
committed
feat: downgrade template script to javascript with <script lang="js">
fix #46
1 parent f57ce6d commit 51a6d4e

File tree

6 files changed

+80
-93
lines changed

6 files changed

+80
-93
lines changed

packages/vscode-server/src/formatters.ts

Lines changed: 60 additions & 60 deletions
Original file line numberDiff line numberDiff line change
@@ -7,84 +7,84 @@ const pugBeautify = require('pug-beautify');
77

88
export function html(document: TextDocument, options: vscode.FormattingOptions): vscode.TextEdit[] {
99

10-
const prefixes = '<template>';
11-
const suffixes = '</template>';
12-
13-
let newHtml = prettyhtml(prefixes + document.getText() + suffixes, {
14-
tabWidth: options.tabSize,
15-
useTabs: !options.insertSpaces,
16-
printWidth: 100,
17-
}).contents;
18-
newHtml = newHtml.trim();
19-
newHtml = newHtml.substring(prefixes.length, newHtml.length - suffixes.length);
20-
21-
const htmlEdit = vscode.TextEdit.replace(
22-
vscode.Range.create(
23-
document.positionAt(0),
24-
document.positionAt(document.getText().length),
25-
),
26-
newHtml,
27-
);
28-
29-
return [htmlEdit];
10+
const prefixes = '<template>';
11+
const suffixes = '</template>';
12+
13+
let newHtml = prettyhtml(prefixes + document.getText() + suffixes, {
14+
tabWidth: options.tabSize,
15+
useTabs: !options.insertSpaces,
16+
printWidth: 100,
17+
}).contents;
18+
newHtml = newHtml.trim();
19+
newHtml = newHtml.substring(prefixes.length, newHtml.length - suffixes.length);
20+
21+
const htmlEdit = vscode.TextEdit.replace(
22+
vscode.Range.create(
23+
document.positionAt(0),
24+
document.positionAt(document.getText().length),
25+
),
26+
newHtml,
27+
);
28+
29+
return [htmlEdit];
3030
}
3131

3232
export function pug(document: TextDocument, options: vscode.FormattingOptions): vscode.TextEdit[] {
3333

34-
const pugCode = document.getText();
35-
if (pugCode.trim() === '') {
36-
return []; // fix https://github.com/johnsoncodehk/volar/issues/304
37-
}
38-
39-
const prefixesLength = pugCode.length - pugCode.trimStart().length;
40-
const suffixesLength = pugCode.length - pugCode.trimEnd().length;
41-
const prefixes = pugCode.substr(0, prefixesLength);
42-
const suffixes = pugCode.substr(pugCode.length - suffixesLength);
43-
const newPugCode: string = pugBeautify(pugCode, {
44-
tab_size: options.tabSize,
45-
fill_tab: !options.insertSpaces,
46-
});
47-
const pugEdit = vscode.TextEdit.replace(
48-
vscode.Range.create(
49-
document.positionAt(0),
50-
document.positionAt(pugCode.length),
51-
),
52-
prefixes + newPugCode.trim() + suffixes,
53-
);
54-
55-
return [pugEdit];
34+
const pugCode = document.getText();
35+
if (pugCode.trim() === '') {
36+
return []; // fix https://github.com/johnsoncodehk/volar/issues/304
37+
}
38+
39+
const prefixesLength = pugCode.length - pugCode.trimStart().length;
40+
const suffixesLength = pugCode.length - pugCode.trimEnd().length;
41+
const prefixes = pugCode.substr(0, prefixesLength);
42+
const suffixes = pugCode.substr(pugCode.length - suffixesLength);
43+
const newPugCode: string = pugBeautify(pugCode, {
44+
tab_size: options.tabSize,
45+
fill_tab: !options.insertSpaces,
46+
});
47+
const pugEdit = vscode.TextEdit.replace(
48+
vscode.Range.create(
49+
document.positionAt(0),
50+
document.positionAt(pugCode.length),
51+
),
52+
prefixes + newPugCode.trim() + suffixes,
53+
);
54+
55+
return [pugEdit];
5656
}
5757

5858
export function css(document: TextDocument, options: vscode.FormattingOptions): vscode.TextEdit[] {
59-
return _css(document, options, 'css');
59+
return _css(document, options, 'css');
6060
}
6161

6262
export function less(document: TextDocument, options: vscode.FormattingOptions): vscode.TextEdit[] {
63-
return _css(document, options, 'less');
63+
return _css(document, options, 'less');
6464
}
6565

6666
export function scss(document: TextDocument, options: vscode.FormattingOptions): vscode.TextEdit[] {
67-
return _css(document, options, 'scss');
67+
return _css(document, options, 'scss');
6868
}
6969

7070
export function postcss(document: TextDocument, options: vscode.FormattingOptions): vscode.TextEdit[] {
71-
return _css(document, options, 'postcss');
71+
return _css(document, options, 'postcss');
7272
}
7373

7474
function _css(document: TextDocument, options: vscode.FormattingOptions, languageId: 'css' | 'less' | 'scss' | 'postcss'): vscode.TextEdit[] {
7575

76-
const newStyleText = prettier.format(document.getText(), {
77-
tabWidth: options.tabSize,
78-
useTabs: !options.insertSpaces,
79-
parser: languageId,
80-
});
81-
const cssEdit = vscode.TextEdit.replace(
82-
vscode.Range.create(
83-
document.positionAt(0),
84-
document.positionAt(document.getText().length),
85-
),
86-
'\n' + newStyleText
87-
);
88-
89-
return [cssEdit];
76+
const newStyleText = prettier.format(document.getText(), {
77+
tabWidth: options.tabSize,
78+
useTabs: !options.insertSpaces,
79+
parser: languageId,
80+
});
81+
const cssEdit = vscode.TextEdit.replace(
82+
vscode.Range.create(
83+
document.positionAt(0),
84+
document.positionAt(document.getText().length),
85+
),
86+
'\n' + newStyleText
87+
);
88+
89+
return [cssEdit];
9090
}

packages/vscode-vue-languageservice/src/commands/convertTagNameCase.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ export async function execute(
1818
const template = desc.template;
1919
const document = sourceFile.getTextDocument();
2020

21-
const virtualDoc = sourceFiles.getTsDocuments('template').get(sourceFile.uri + '.__VLS_template.ts');
21+
const virtualDoc = sourceFile.getTemplateScriptDocument();
2222
if (!virtualDoc) return;
2323

2424
const edits: vscode.TextEdit[] = [];

packages/vscode-vue-languageservice/src/services/diagnostics.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@ export function register({ sourceFiles, getCssLs, jsonLs, templateTsLs, scriptTs
3636
sfcErrors,
3737
sfcTemplate,
3838
descriptor,
39-
vueDoc,
39+
document,
4040
sfcTemplateScript,
4141
templateScriptData,
4242
sfcScriptForTemplateLs,
@@ -379,8 +379,8 @@ export function register({ sourceFiles, getCssLs, jsonLs, templateTsLs, scriptTs
379379
if (!script || script.content === '') continue;
380380
const error = vscode.Diagnostic.create(
381381
{
382-
start: vueDoc.value.positionAt(script.loc.start),
383-
end: vueDoc.value.positionAt(script.loc.end),
382+
start: document.value.positionAt(script.loc.start),
383+
end: document.value.positionAt(script.loc.end),
384384
},
385385
'Virtual script not found, may missing lang="ts" or "allowJs": true.',
386386
vscode.DiagnosticSeverity.Information,

packages/vscode-vue-languageservice/src/sourceFile.ts

Lines changed: 8 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ import { useSfcScript } from './use/useSfcScript';
1313
import { useSfcStyles } from './use/useSfcStyles';
1414
import { useSfcTemplate } from './use/useSfcTemplate';
1515
import { useSfcEntryForTemplateLs } from './use/useSfcEntryForTemplateLs';
16-
import { useSfcScriptForTemplateLs } from './use/useSfcScriptForTemplateLs';
16+
import { useSfcScriptGen } from './use/useSfcScriptGen';
1717
import { useSfcTemplateScript } from './use/useSfcTemplateScript';
1818

1919
export const defaultLanguages = {
@@ -99,8 +99,8 @@ export function createSourceFile(
9999
);
100100
const sfcScript = useSfcScript(untrack(() => document.value), computed(() => descriptor.script));
101101
const sfcScriptSetup = useSfcScript(untrack(() => document.value), computed(() => descriptor.scriptSetup));
102-
const sfcScriptForTemplateLs = useSfcScriptForTemplateLs('template', context.modules.typescript, document, computed(() => descriptor.script), computed(() => descriptor.scriptSetup), computed(() => sfcTemplateData.value?.html));
103-
const sfcScriptForScriptLs = useSfcScriptForTemplateLs('script', context.modules.typescript, document, computed(() => descriptor.script), computed(() => descriptor.scriptSetup), computed(() => sfcTemplateData.value?.html));
102+
const sfcScriptForTemplateLs = useSfcScriptGen('template', context.modules.typescript, document, computed(() => descriptor.script), computed(() => descriptor.scriptSetup), computed(() => sfcTemplateData.value?.html));
103+
const sfcScriptForScriptLs = useSfcScriptGen('script', context.modules.typescript, document, computed(() => descriptor.script), computed(() => descriptor.scriptSetup), computed(() => sfcTemplateData.value?.html));
104104
const sfcEntryForTemplateLs = useSfcEntryForTemplateLs(untrack(() => document.value), computed(() => descriptor.script), computed(() => descriptor.scriptSetup), computed(() => descriptor.template));
105105

106106
// getters
@@ -146,6 +146,7 @@ export function createSourceFile(
146146
getTemplateTagNames: untrack(() => sfcTemplateScript.templateCodeGens.value?.tagNames),
147147
getTemplateAttrNames: untrack(() => sfcTemplateScript.templateCodeGens.value?.attrNames),
148148
getTextDocument: untrack(() => document.value),
149+
getTemplateScriptDocument: untrack(() => sfcTemplateScript.textDocument.value),
149150
update: untrack(update),
150151
updateTemplateScript: untrack(updateTemplateScript),
151152
getScriptTsDocument: untrack(() => sfcScriptForScriptLs.textDocument.value),
@@ -156,16 +157,8 @@ export function createSourceFile(
156157
getHtmlSourceMaps: untrack(() => sfcTemplate.htmlSourceMap.value ? [sfcTemplate.htmlSourceMap.value] : []),
157158
getPugSourceMaps: untrack(() => sfcTemplate.pugSourceMap.value ? [sfcTemplate.pugSourceMap.value] : []),
158159
getTemplateScriptData: untrack(() => templateScriptData),
159-
getTeleports: untrack(() => [
160-
sfcTemplateScript.teleportSourceMap.value,
161-
sfcScriptForTemplateLs.teleportSourceMap.value,
162-
].filter(shared.notEmpty)),
163160
getDescriptor: untrack(() => descriptor),
164161
getVueHtmlDocument: untrack(() => vueHtmlDocument.value),
165-
getVirtualScript: untrack(() => ({
166-
document: sfcScriptForTemplateLs.textDocument.value,
167-
sourceMap: sfcScriptForTemplateLs.sourceMap.value,
168-
})),
169162
getScriptSetupData: untrack(() => sfcScriptForTemplateLs.scriptSetupRanges.value),
170163
docLsScripts: untrack(() => ({
171164
documents: [sfcScript.textDocument.value, sfcScriptSetup.textDocument.value].filter(shared.notEmpty),
@@ -178,7 +171,7 @@ export function createSourceFile(
178171
shouldVerifyTsScript: untrack(shouldVerifyTsScript),
179172

180173
refs: {
181-
vueDoc: document,
174+
document,
182175
descriptor,
183176
lastUpdated,
184177
sfcErrors,
@@ -214,12 +207,13 @@ export function createSourceFile(
214207
updateScriptSetup(newDescriptor);
215208
updateStyles(newDescriptor);
216209
updateCustomBlocks(newDescriptor);
217-
sfcTemplateScript.update(); // TODO
218210

219211
if (newDocument.getText() !== document.value.getText()) {
220212
document.value = newDocument;
221213
}
222214

215+
sfcTemplateScript.update(sfcScriptForScriptLs.lang.value); // TODO
216+
223217
const versionsAfterUpdate = [
224218
sfcScriptForTemplateLs.textDocument.value?.version,
225219
sfcTemplateScript.textDocument.value?.version,
@@ -418,7 +412,7 @@ export function createSourceFile(
418412
templateScriptData.htmlElements = htmlElementNames;
419413
templateScriptData.componentItems = components;
420414
templateScriptData.htmlElementItems = globalEls;
421-
sfcTemplateScript.update(); // TODO
415+
sfcTemplateScript.update(sfcScriptForScriptLs.lang.value); // TODO
422416
return true;
423417
}
424418
function shouldVerifyTsScript(templateTsHost: ts.LanguageServiceHost, tsUri: string, mode: 1 | 2 | 3 | 4): 'all' | 'none' | 'unused' {

packages/vscode-vue-languageservice/src/use/useSfcScriptForTemplateLs.ts renamed to packages/vscode-vue-languageservice/src/use/useSfcScriptGen.ts

Lines changed: 5 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ import { generate as genScript } from '../generators/script';
99
import { generate as genScriptSuggestion } from '../generators/script_suggestion';
1010
import * as templateGen from '../generators/template_scriptSetup';
1111

12-
export function useSfcScriptForTemplateLs(
12+
export function useSfcScriptGen(
1313
lsType: 'template' | 'script',
1414
ts: typeof import('typescript/lib/tsserverlibrary'),
1515
vueDoc: Ref<TextDocument>,
@@ -61,15 +61,9 @@ export function useSfcScriptForTemplateLs(
6161
shared.getValidScriptSyntax('js')
6262
});
6363
const textDocument = computed(() => {
64-
let _lang = lang.value;
65-
if (lsType === 'template') {
66-
// force use TS to support template type-checking with <script lang="js">
67-
if (_lang === 'js') _lang = 'ts';
68-
if (_lang === 'jsx') _lang = 'tsx';
69-
}
7064
return TextDocument.create(
71-
lsType === 'template' ? `${uri}.__VLS_script.${_lang}` : `${uri}.${_lang}`,
72-
shared.syntaxToLanguageId(_lang),
65+
lsType === 'template' ? `${uri}.__VLS_script.${lang.value}` : `${uri}.${lang.value}`,
66+
shared.syntaxToLanguageId(lang.value),
7367
version++,
7468
codeGen.value.getText(),
7569
);
@@ -137,6 +131,7 @@ export function useSfcScriptForTemplateLs(
137131
});
138132

139133
return {
134+
lang,
140135
scriptSetupRanges,
141136
textDocument,
142137
textDocumentForSuggestion,
@@ -147,9 +142,7 @@ export function useSfcScriptForTemplateLs(
147142

148143
function parseMappingSourceRange(data: TsMappingData, sourceRange: Range) {
149144
if (data.vueTag === 'scriptSrc' && script.value?.src) {
150-
const vueStart = script.value.content.length
151-
? vueDoc.value.getText().substring(0, script.value.loc.start).lastIndexOf(script.value.src)
152-
: (vueDoc.value.getText().substring(script.value.loc.start).indexOf(script.value.src) + script.value.loc.start); // TODO: don't use indexOf()
145+
const vueStart = vueDoc.value.getText().substring(0, script.value.loc.start).lastIndexOf(script.value.src);
153146
const vueEnd = vueStart + script.value.src.length;
154147
return {
155148
start: vueStart - 1,

packages/vscode-vue-languageservice/src/use/useSfcTemplateScript.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -348,12 +348,12 @@ export function useSfcTemplateScript(
348348
end: range.end + templateOffset,
349349
};
350350
}
351-
function update() {
351+
function update(lang: string) {
352352
if (data.value?.getText() !== textDoc.value?.getText()) {
353353
if (data.value && templateCodeGens.value) {
354354
const _version = version++;
355-
textDoc.value = TextDocument.create(vueUri + '.__VLS_template.ts', 'typescript', _version, data.value.getText());
356-
formatTextDoc.value = TextDocument.create(vueUri + '.__VLS_template.format.ts', 'typescript', _version, templateCodeGens.value.formatCodeGen.getText());
355+
textDoc.value = TextDocument.create(vueUri + '.__VLS_template.' + lang, shared.syntaxToLanguageId(lang), _version, data.value.getText());
356+
formatTextDoc.value = TextDocument.create(vueUri + '.__VLS_template.format.' + lang, shared.syntaxToLanguageId(lang), _version, templateCodeGens.value.formatCodeGen.getText());
357357

358358
const sourceMap = new SourceMaps.TeleportSourceMap(textDoc.value, true);
359359
for (const maped of data.value.ctxMappings) {

0 commit comments

Comments
 (0)