Skip to content

Commit

Permalink
feat(language-plugin-pug): support initial indentation
Browse files Browse the repository at this point in the history
close #4774
  • Loading branch information
johnsoncodehk committed Aug 31, 2024
1 parent f12667f commit f883528
Show file tree
Hide file tree
Showing 3 changed files with 71 additions and 7 deletions.
4 changes: 2 additions & 2 deletions packages/language-core/lib/plugins/vue-sfc-template.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ const plugin: VueLanguagePlugin = () => {
version: 2.1,

getEmbeddedCodes(_fileName, sfc) {
if (sfc.template) {
if (sfc.template?.lang === 'html') {
return [{
id: 'template',
lang: sfc.template.lang,
Expand All @@ -18,7 +18,7 @@ const plugin: VueLanguagePlugin = () => {
},

resolveEmbeddedCode(_fileName, sfc, embeddedFile) {
if (embeddedFile.id === 'template' && sfc.template) {
if (embeddedFile.id === 'template' && sfc.template?.lang === 'html') {
embeddedFile.content.push([
sfc.template.content,
sfc.template.name,
Expand Down
67 changes: 62 additions & 5 deletions packages/language-plugin-pug/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,15 +10,60 @@ const plugin: VueLanguagePlugin = ({ modules }) => {

version: 2.1,

getEmbeddedCodes(_fileName, sfc) {
if (sfc.template?.lang === 'pug') {
return [{
id: 'template',
lang: sfc.template.lang,
}];
}
return [];
},

resolveEmbeddedCode(_fileName, sfc, embeddedFile) {
if (embeddedFile.id === 'template' && sfc.template?.lang === 'pug') {
const minIndent = calculateMinIndent(sfc.template.content);
if (minIndent !== 0) {
embeddedFile.content.push(`template\n`);
embeddedFile.content.push([
sfc.template.content,
sfc.template.name,
0,
{
verification: true,
completion: true,
semantic: true,
navigation: true,
structure: true,
format: true,
},
]);
return;
}
}
},

compileSFCTemplate(lang, template, options) {

if (lang === 'pug') {

const pugFile = pug?.baseParse(template);
const map = new SourceMap(pugFile.mappings);
let pugFile: ReturnType<typeof pug.baseParse>;
let baseOffset = 0;

if (pugFile) {
const minIndent = calculateMinIndent(template);
if (minIndent === 0) {
pugFile = pug?.baseParse(template);
}
else {
pugFile = pug?.baseParse(`template\n${template}`);
baseOffset = 'template\n'.length;
pugFile.htmlCode = ' '.repeat('<template>'.length)
+ pugFile.htmlCode.slice('<template>'.length, -'</template>'.length)
+ ' '.repeat('</template>'.length);
}

if (pugFile) {
const map = new SourceMap(pugFile.mappings);
const compiler = modules['@vue/compiler-dom'];
const completed = compiler.compile(pugFile.htmlCode, {
...options,
Expand Down Expand Up @@ -52,7 +97,7 @@ const plugin: VueLanguagePlugin = ({ modules }) => {
}
const value = Reflect.get(target, prop, receiver);
if (typeof value === 'object' && value !== null) {
let proxyed = proxys.get(value)
let proxyed = proxys.get(value);
if (proxyed) {
return proxyed;
}
Expand All @@ -69,7 +114,7 @@ const plugin: VueLanguagePlugin = ({ modules }) => {
const htmlOffset = offset;
const nums: number[] = [];
for (const mapped of map.toSourceLocation(htmlOffset)) {
nums.push(mapped[0]);
nums.push(mapped[0] - baseOffset);
}
return Math.max(-1, ...nums);
}
Expand All @@ -79,3 +124,15 @@ const plugin: VueLanguagePlugin = ({ modules }) => {
};
};
export = plugin;

function calculateMinIndent(s: string) {
const lines = s.split('\n');
const minIndent = lines.reduce(function (minIndent, line) {
if (line.trim() === '') {
return minIndent;
}
const indent = line.match(/^\s*/)?.[0]?.length || 0;
return Math.min(indent, minIndent);
}, Infinity);
return minIndent;
}
7 changes: 7 additions & 0 deletions test-workspace/tsc/passedFixtures/pug/#4774.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
<template lang="pug">
div {{ msg }}
</template>

<script setup lang="ts">
const msg = 'Hello Pug';
</script>

0 comments on commit f883528

Please sign in to comment.