Skip to content

Commit

Permalink
Merge pull request #2007 from vuejs/prettier-pug
Browse files Browse the repository at this point in the history
Add prettier-pug and fix region parser. Fix #527
  • Loading branch information
octref authored Jun 24, 2020
2 parents 0ce3676 + ec6f903 commit b46963f
Show file tree
Hide file tree
Showing 10 changed files with 202 additions and 7 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

### 0.25.0

- Add [prettier/plugin-pug](https://github.com/prettier/plugin-pug) as default formatter for `pug`. #527.
- 🙌 Detect tags from @nuxt/components. Thanks to contribution from [pooya parsa](https://github.com/pi0). #1921.
- 🙌 Fix VTI crash by passing correct PID to language server. Thanks to contribution from [Daniil Yastremskiy](@TheBeastOfCaerbannog). #1699 and #1805.
- 🙌 Fix template interpolation hover info of v-for readonly array item. Thanks to contribution from [@yoyo930021](https://github.com/yoyo930021). #1788.
Expand Down
3 changes: 2 additions & 1 deletion docs/formatting.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ Vetur has support for formatting embedded `html/css/scss/less/postcss/stylus/js/

These formatters are available:

- [`prettier`](https://github.com/prettier/prettier): For css/scss/less/js/ts.
- [`prettier`](https://github.com/prettier/prettier): For pug/css/scss/less/js/ts.
- [`prettier-eslint`](https://github.com/prettier/prettier-eslint): For js. Run `prettier` and `eslint --fix`.
- [`prettyhtml`](https://github.com/Prettyhtml/prettyhtml): For html.
- [`stylus-supremacy`](https://github.com/ThisIsManta/stylus-supremacy): For stylus.
Expand All @@ -27,6 +27,7 @@ Current default:
```json
{
"vetur.format.defaultFormatter.html": "prettyhtml",
"vetur.format.defaultFormatter.pug": "prettier",
"vetur.format.defaultFormatter.css": "prettier",
"vetur.format.defaultFormatter.postcss": "prettier",
"vetur.format.defaultFormatter.scss": "prettier",
Expand Down
13 changes: 13 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -285,6 +285,19 @@
],
"description": "Default formatter for <template> region"
},
"vetur.format.defaultFormatter.pug": {
"type": "string",
"default": "prettier",
"enum": [
"none",
"prettier"
],
"enumDescriptions": [
"disable formatting",
"prettier"
],
"description": "Default formatter for <template lang='pug'> region"
},
"vetur.format.defaultFormatter.css": {
"type": "string",
"default": "prettier",
Expand Down
1 change: 1 addition & 0 deletions server/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,7 @@
"vue-onsenui-helper-json": "^1.0.2"
},
"devDependencies": {
"@prettier/plugin-pug": "^1.4.4",
"@types/eslint": "^7.2.0",
"@types/eslint-scope": "^3.7.0",
"@types/eslint-visitor-keys": "^1.0.0",
Expand Down
3 changes: 3 additions & 0 deletions server/src/embeddedSupport/languageModes.ts
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ import { nullMode } from '../modes/nullMode';
import { getServiceHost, IServiceHost } from '../services/typescriptService/serviceHost';
import { VLSFullConfig } from '../config';
import { SassLanguageMode } from '../modes/style/sass/sassLanguageMode';
import { getPugMode } from '../modes/pug';

export interface VLSServices {
infoService?: VueInfoService;
Expand Down Expand Up @@ -130,6 +131,7 @@ export class LanguageModes {
workspacePath,
services.infoService
);

const jsMode = await getJavascriptMode(
this.serviceHost,
this.documentRegions,
Expand All @@ -140,6 +142,7 @@ export class LanguageModes {

this.modes['vue'] = getVueMode(workspacePath, globalSnippetDir);
this.modes['vue-html'] = vueHtmlMode;
this.modes['pug'] = getPugMode();
this.modes['css'] = getCSSMode(this.documentRegions);
this.modes['postcss'] = getPostCSSMode(this.documentRegions);
this.modes['scss'] = getSCSSMode(this.documentRegions);
Expand Down
70 changes: 70 additions & 0 deletions server/src/embeddedSupport/test/embeddedSupport.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -135,3 +135,73 @@ suite('External Source', () => {
assert.equal(importedScripts[0], './external.js');
});
});

suite('Template region positions', () => {
const htmlSrc = `
<template>
<p>Test</p>
</template>
`;

test('vue-html region positions', () => {
const { regions } = parseVueDocumentRegions(TextDocument.create('test://test.vue', 'vue', 0, htmlSrc));

assert.equal(regions[0].languageId, 'vue-html');
assert.equal(
htmlSrc.slice(regions[0].start, regions[0].end),
[
// prettier-ignore
'',
' <p>Test</p>',
''
].join('\n')
);
});

const pugSrc = `
<template lang="pug">
p Test
</template>
`;

test('pug region positions', () => {
const { regions } = parseVueDocumentRegions(TextDocument.create('test://test.vue', 'vue', 0, pugSrc));

assert.equal(regions[0].languageId, 'pug');
assert.equal(
pugSrc.slice(regions[0].start, regions[0].end),
[
// prettier-ignore
'',
'p Test',
''
].join('\n')
);
});
});

suite('Embedded <template> ', () => {
const htmlSrc = `
<template>
<template>
<p>Test</p>
</template>
</template>
`;
test('vue-html region positions', () => {
const { regions } = parseVueDocumentRegions(TextDocument.create('test://test.vue', 'vue', 0, htmlSrc));

assert.equal(regions[0].languageId, 'vue-html');
assert.equal(
htmlSrc.slice(regions[0].start, regions[0].end),
[
// prettier-ignore
'',
' <template>',
' <p>Test</p>',
' </template>',
''
].join('\n')
);
});
});
18 changes: 14 additions & 4 deletions server/src/embeddedSupport/vueDocumentRegionParser.ts
Original file line number Diff line number Diff line change
Expand Up @@ -92,7 +92,7 @@ export function parseVueDocumentRegions(document: TextDocument) {
function scanTemplateRegion(scanner: Scanner, text: string): EmbeddedRegion | null {
let languageId: LanguageId = 'vue-html';

let token: number;
let token = -1;
let start = 0;
let end: number;

Expand All @@ -102,16 +102,26 @@ function scanTemplateRegion(scanner: Scanner, text: string): EmbeddedRegion | nu
let lastAttributeName = null;
while (unClosedTemplate !== 0) {
// skip parsing on non html syntax, just search terminator
if (languageId !== 'vue-html' && start !== 0) {
if (token === TokenType.AttributeValue && languageId !== 'vue-html') {
while (token !== TokenType.StartTagClose) {
token = scanner.scan();
}
start = scanner.getTokenEnd();

token = scanner.scanForRegexp(/<\/template>/);
if (token === TokenType.EOS) {
return null;
}
// forward to endTagStart </
scanner.scan();

// scan to `EndTag`, past `</` to `template`
while (token !== TokenType.EndTag) {
token = scanner.scan();
}
break;
}

token = scanner.scan();

if (token === TokenType.EOS) {
return null;
}
Expand Down
52 changes: 52 additions & 0 deletions server/src/modes/pug/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
import { TextDocument, Position, Range } from 'vscode-languageserver-types';
import { LanguageMode } from '../../embeddedSupport/languageModes';
import { prettierify } from '../../utils/prettier';
import { VLSFormatConfig } from '../../config';
import { getFileFsPath } from '../../utils/paths';

export function getPugMode(): LanguageMode {
let config: any = {};

return {
getId() {
return 'pug';
},
configure(c) {
config = c;
},
format(document, currRange, formattingOptions) {
if (config.vetur.format.defaultFormatter['pug'] === 'none') {
return [];
}

const { value, range } = getValueAndRange(document, currRange);

const foo = prettierify(
value,
getFileFsPath(document.uri),
range,
config.vetur.format as VLSFormatConfig,
'pug',
false
);

return foo;
},
onDocumentRemoved() {},
dispose() {}
};
}

function getValueAndRange(document: TextDocument, currRange: Range): { value: string; range: Range } {
let value = document.getText();
let range = currRange;

if (currRange) {
const startOffset = document.offsetAt(currRange.start);
const endOffset = document.offsetAt(currRange.end);
value = value.substring(startOffset, endOffset);
} else {
range = Range.create(Position.create(0, 0), document.positionAt(value.length));
}
return { value, range };
}
3 changes: 2 additions & 1 deletion server/src/utils/prettier/prettier.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,8 @@ export type ParserOption =
| 'html'
| 'angular'
| 'mdx'
| 'yaml';
| 'yaml'
| 'pug';

type TrailingCommaOption = 'none' | 'es5' | 'all';

Expand Down
45 changes: 44 additions & 1 deletion server/yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -107,6 +107,13 @@
resolved "https://registry.yarnpkg.com/@nodelib/fs.stat/-/fs.stat-1.1.3.tgz#2b5a3ab3f918cca48a8c754c08168e3f03eba61b"
integrity sha512-shAmDyaQC4H92APFoIaVDHCx5bStIocgvbwQyxPRrbUY20V1EYTbSDchWbuwlMG3V17cprZhA6+78JfB+3DTPw==

"@prettier/plugin-pug@^1.4.4":
version "1.4.4"
resolved "https://registry.yarnpkg.com/@prettier/plugin-pug/-/plugin-pug-1.4.4.tgz#252c8dfac574c82d1e95492b9bd4cb59c44d3ee6"
integrity sha512-Lb3cc0a4IwUy9oNeYuN1YHg/+J5JDsJNSKFMGpcp6cq6vnMcNyWn+KNBkTo/ZYEIT2JAsl6X+KKAvjH1p+XGeQ==
dependencies:
pug-lexer "~5.0.0"

"@sindresorhus/is@^0.14.0":
version "0.14.0"
resolved "https://registry.yarnpkg.com/@sindresorhus/is/-/is-0.14.0.tgz#9fb3a3cf3132328151f353de4632e01e52102bea"
Expand Down Expand Up @@ -834,6 +841,13 @@ character-entities@^1.0.0:
resolved "https://registry.yarnpkg.com/character-entities/-/character-entities-1.2.2.tgz#58c8f371c0774ef0ba9b2aca5f00d8f100e6e363"
integrity sha512-sMoHX6/nBiy3KKfC78dnEalnpn0Az0oSNvqUWYTtYrhRI5iUIYsROU48G+E+kMFQzqXaJ8kHJZ85n7y6/PHgwQ==

character-parser@^2.2.0:
version "2.2.0"
resolved "https://registry.yarnpkg.com/character-parser/-/character-parser-2.2.0.tgz#c7ce28f36d4bcd9744e5ffc2c5fcde1c73261fc0"
integrity sha1-x84o821LzZdE5f/CxfzeHHMmH8A=
dependencies:
is-regex "^1.0.3"

character-reference-invalid@^1.0.0:
version "1.1.2"
resolved "https://registry.yarnpkg.com/character-reference-invalid/-/character-reference-invalid-1.1.2.tgz#21e421ad3d84055952dab4a43a04e73cd425d3ed"
Expand Down Expand Up @@ -2366,6 +2380,14 @@ is-empty@^1.0.0:
resolved "https://registry.yarnpkg.com/is-empty/-/is-empty-1.2.0.tgz#de9bb5b278738a05a0b09a57e1fb4d4a341a9f6b"
integrity sha1-3pu1snhzigWgsJpX4ftNSjQan2s=

is-expression@^4.0.0:
version "4.0.0"
resolved "https://registry.yarnpkg.com/is-expression/-/is-expression-4.0.0.tgz#c33155962abf21d0afd2552514d67d2ec16fd2ab"
integrity sha512-zMIXX63sxzG3XrkHkrAPvm/OVZVSCPNkwMHU8oTX7/U3AL78I0QXCEICXUM13BIa8TYGZ68PiTKfQz3yaTNr4A==
dependencies:
acorn "^7.1.1"
object-assign "^4.1.1"

is-extendable@^0.1.0, is-extendable@^0.1.1:
version "0.1.1"
resolved "https://registry.yarnpkg.com/is-extendable/-/is-extendable-0.1.1.tgz#62b110e289a471418e3ec36a617d472e301dfc89"
Expand Down Expand Up @@ -2486,6 +2508,13 @@ is-promise@^2.1.0:
resolved "https://registry.yarnpkg.com/is-promise/-/is-promise-2.1.0.tgz#79a2a9ece7f096e80f36d2b2f3bc16c1ff4bf3fa"
integrity sha1-eaKp7OfwlugPNtKy87wWwf9L8/o=

is-regex@^1.0.3:
version "1.1.0"
resolved "https://registry.yarnpkg.com/is-regex/-/is-regex-1.1.0.tgz#ece38e389e490df0dc21caea2bd596f987f767ff"
integrity sha512-iI97M8KTWID2la5uYXlkbSDQIg4F6o1sYboZKKTDpnDQMLtUL86zxhgDet3Q2SriaYsyGqZ6Mn2SjbRKeLHdqw==
dependencies:
has-symbols "^1.0.1"

is-regex@^1.0.4:
version "1.0.4"
resolved "https://registry.yarnpkg.com/is-regex/-/is-regex-1.0.4.tgz#5517489b547091b0930e095654ced25ee97e9491"
Expand Down Expand Up @@ -3178,7 +3207,7 @@ nyc@^14.1.1:
yargs "^13.2.2"
yargs-parser "^13.0.0"

object-assign@^4.0.1:
object-assign@^4.0.1, object-assign@^4.1.1:
version "4.1.1"
resolved "https://registry.yarnpkg.com/object-assign/-/object-assign-4.1.1.tgz#2109adc7965887cfc05cbbd442cac8bfbb360863"
integrity sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=
Expand Down Expand Up @@ -3623,6 +3652,20 @@ pseudomap@^1.0.2:
resolved "https://registry.yarnpkg.com/pseudomap/-/pseudomap-1.0.2.tgz#f052a28da70e618917ef0a8ac34c1ae5a68286b3"
integrity sha1-8FKijacOYYkX7wqKw0wa5aaChrM=

pug-error@^2.0.0:
version "2.0.0"
resolved "https://registry.yarnpkg.com/pug-error/-/pug-error-2.0.0.tgz#5c62173cb09c34de2a2ce04f17b8adfec74d8ca5"
integrity sha512-sjiUsi9M4RAGHktC1drQfCr5C5eriu24Lfbt4s+7SykztEOwVZtbFk1RRq0tzLxcMxMYTBR+zMQaG07J/btayQ==

pug-lexer@~5.0.0:
version "5.0.0"
resolved "https://registry.yarnpkg.com/pug-lexer/-/pug-lexer-5.0.0.tgz#0b779e7d8cbf0f103803675be96351942fd9a727"
integrity sha512-52xMk8nNpuyQ/M2wjZBN5gXQLIylaGkAoTk5Y1pBhVqaopaoj8Z0iVzpbFZAqitL4RHNVDZRnJDsqEYe99Ti0A==
dependencies:
character-parser "^2.2.0"
is-expression "^4.0.0"
pug-error "^2.0.0"

pump@^3.0.0:
version "3.0.0"
resolved "https://registry.yarnpkg.com/pump/-/pump-3.0.0.tgz#b4a2116815bde2f4e1ea602354e8c75565107a64"
Expand Down

0 comments on commit b46963f

Please sign in to comment.