Skip to content

Commit 3177861

Browse files
authored
feat: pug templates support
feat: pug templates support
2 parents a514a32 + cb40865 commit 3177861

File tree

11 files changed

+206
-59
lines changed

11 files changed

+206
-59
lines changed

.github/PULL_REQUEST_TEMPLATE.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ Please carefully read the contribution docs before creating a pull request
55
👉 https://github.com/nuxtrdev/nuxtr-vscode/blob/main/CONTRIBUTING.md
66
-->
77

8-
### 🔗 Linked issue
8+
### 🔗 Linked issue / Discussion
99

1010
<!-- Please ensure there is an open issue and mention its number as #123 -->
1111

README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,7 @@ With just a few clicks or using commands and context menus, you can effortlessly
5151
You can customize Vue file templates using the following settings:
5252

5353
```JSON
54+
"vueFiles.template.defaultLanguage": "html",
5455
"nuxtr.vueFiles.firstTag": "template",
5556
"nuxtr.vueFiles.script.type": "setup",
5657
"nuxtr.vueFiles.script.defaultLanguage": "ts",

package.json

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -264,6 +264,10 @@
264264
"command": "nuxtr.configureLinters",
265265
"when": "nuxtr.isNuxtProject"
266266
},
267+
{
268+
"command": "nuxtr.configurePug",
269+
"when": "nuxtr.isNuxtProject"
270+
},
267271
{
268272
"command": "nuxtr.directToggleDevTools",
269273
"when": "nuxtr.isNuxtProject"
@@ -467,6 +471,15 @@
467471
"title": "Vue Files",
468472
"type": "object",
469473
"properties": {
474+
"nuxtr.vueFiles.template.defaultLanguage": {
475+
"type": "string",
476+
"default": "html",
477+
"enum": [
478+
"html",
479+
"pug"
480+
],
481+
"description": "Default language for script tag"
482+
},
470483
"nuxtr.vueFiles.firstTag": {
471484
"type": "string",
472485
"default": "template",
@@ -863,6 +876,12 @@
863876
"category": "Nuxtr",
864877
"when": "nuxtr.isNuxtProject"
865878
},
879+
{
880+
"command": "nuxtr.configurePug",
881+
"title": "Configure Pug",
882+
"category": "Nuxtr",
883+
"when": "nuxtr.isNuxtProject"
884+
},
866885
{
867886
"command": "nuxtr.createPageTemplate",
868887
"title": "Create Vue Page Template",

src/commands/Templates.ts

Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,72 @@
1+
import { window } from 'vscode'
2+
import { existsSync } from 'fs'
3+
import { projectRootDirectory, runCommand, getInstallationCommand } from '../utils'
4+
import type { TSConfigNuxt } from '../types'
5+
import { writeTSConfig, readTSConfig } from 'pkg-types'
6+
7+
export enum PugConfigurationSteps {
8+
installPug = 'Install Pug',
9+
installLanguagePlugin = 'Install @vue/language-plugin-pug',
10+
addPluginToTSConfig = 'Add @vue/language-plugin-pug to tsconfig.json',
11+
}
12+
13+
const defaultOptions = Object.values(PugConfigurationSteps)
14+
15+
16+
export const configurePug = (options: string[] = defaultOptions) => {
17+
try {
18+
window
19+
.showQuickPick(options, {
20+
canPickMany: true,
21+
placeHolder: 'Select files to create',
22+
})
23+
.then(async (selections) => {
24+
if (selections !== undefined && selections.length > 0) {
25+
if (selections.includes(PugConfigurationSteps.installPug)) {
26+
const moduleName = 'pug'
27+
const command = await getInstallationCommand(moduleName, true)
28+
29+
await runCommand({
30+
command,
31+
message: 'Installing Pug',
32+
successMessage: 'Pug installed successfully',
33+
errorMessage: 'Pug installation failed',
34+
})
35+
}
36+
37+
if (selections.includes(PugConfigurationSteps.installLanguagePlugin)) {
38+
const moduleName = '@vue/language-plugin-pug'
39+
const command = await getInstallationCommand(moduleName, true)
40+
41+
await runCommand({
42+
command,
43+
message: 'Installing @vue/language-plugin-pug',
44+
successMessage: '@vue/language-plugin-pug installed successfully',
45+
errorMessage: '@vue/language-plugin-pug installation failed',
46+
})
47+
}
48+
49+
if (selections.includes(PugConfigurationSteps.addPluginToTSConfig)) {
50+
const path = `${projectRootDirectory()}/tsconfig.json`;
51+
52+
if (!existsSync(path)) {
53+
return;
54+
}
55+
56+
let tsconfig: TSConfigNuxt = await readTSConfig(path);
57+
tsconfig.vueCompilerOptions = {
58+
plugins: [
59+
'@vue/language-plugin-pug'
60+
]
61+
}
62+
63+
await writeTSConfig(path, tsconfig)
64+
65+
window.showInformationMessage('Pug is added to tsconfig.json')
66+
}
67+
}
68+
})
69+
} catch (error) {
70+
console.error(error)
71+
}
72+
}

src/commands/index.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ import { openSettings } from '../utils/navigation'
1414
import { upgradePackage, managePackageVersion } from '../utils/dependency'
1515
import { configureCSS } from './CSS'
1616
import { configureLinters } from './Linters'
17+
import { configurePug } from './Templates'
1718
import { createPageTemplate, createLayoutTemplate, createFileFromTemplate, createEmptyFileTemplate } from './FileTemplates'
1819
import { nuxtConfigWatcher, directToggleDevTools } from './Devtools'
1920
import { createUtil, directCreateUtil } from './Util'
@@ -62,6 +63,7 @@ const commands = {
6263
openSettings,
6364
configureCSS,
6465
configureLinters,
66+
configurePug,
6567
createPageTemplate,
6668
createLayoutTemplate,
6769
searchAndInstallDependencies,

src/extension.ts

Lines changed: 2 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ import { logger, updateDependencies } from './utils';
55
import codelens from './codelens'
66
import { statusBars, activateStatusBarIcons } from './statusBar'
77
import { activateIntellisense } from './intellisense'
8-
import {filesWatcher} from './watchers'
8+
import { filesWatcher } from './watchers'
99

1010
const commandList = [
1111
{ command: 'nuxtr.createPage', function: nuxtrCommands.createPage },
@@ -39,6 +39,7 @@ const commandList = [
3939
{ command: 'nuxtr.openSettings', function: nuxtrCommands.openSettings },
4040
{ command: 'nuxtr.configureCSS', function: nuxtrCommands.configureCSS },
4141
{ command: 'nuxtr.configureLinters', function: nuxtrCommands.configureLinters },
42+
{ command: 'nuxtr.configurePug', function: nuxtrCommands.configurePug },
4243
{ command: 'nuxtr.createPageTemplate', function: nuxtrCommands.createPageTemplate },
4344
{ command: 'nuxtr.createLayoutTemplate', function: nuxtrCommands.createLayoutTemplate },
4445
{ command: 'nuxtr.createEmptyFileTemplate', function: nuxtrCommands.createEmptyFileTemplate },
@@ -77,12 +78,6 @@ export async function activateExtension(context: ExtensionContext) {
7778
// activate codelens
7879
codelens.activateCodelenses(context)
7980

80-
// activate extension config watcher
81-
// context.subscriptions.push(configWatcher)
82-
83-
// snippetsConfigWatcher
84-
// context.subscriptions.push(snippetsConfigWatcher)
85-
8681
// global state command
8782
context.subscriptions.push(commands.registerCommand('nuxtr.globalState', ({ update, name, value }) => {
8883
if (update) {

src/intellisense/completionProviders/nuxtIgnore.ts

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -64,9 +64,7 @@ export class NuxtIgnoreCompletionProvider implements vscode.CompletionItemProvid
6464
}
6565

6666
private getSubDirectories(directory: string): string[] {
67-
console.log('getSubDirectories', directory);
6867
directory = directory.replace(/!/g, '');
69-
console.log('getSubDirectories', directory);
7068

7169
try {
7270
if (fs.existsSync(directory)) {

src/types.d.ts

Lines changed: 43 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
import { TSConfig } from 'pkg-types'
2+
13
export interface ConfigurationProperty {
24
title?: string;
35
description?: string;
@@ -11,42 +13,51 @@ export interface ConfigurationProperty {
1113
}
1214

1315
export interface NuxtrConfiguration {
14-
openItemsAfterCreation: boolean;
15-
defaultPackageManager: "null" | "Yarn" | "NPM" | "pnpm" | "Bun";
16-
monorepoMode: {
17-
DirectoryName: string | null;
18-
};
19-
vueFiles: {
20-
firstTag: "template" | "script";
21-
script: {
22-
type: "setup" | "normal";
23-
defaultLanguage: "js" | "ts";
24-
};
25-
style: {
26-
addStyleTag: boolean;
27-
alwaysScoped: boolean;
28-
defaultLanguage:
29-
| "css"
30-
| "scss"
31-
| "sass"
32-
| "less"
33-
| "stylus"
34-
| "postcss";
16+
openItemsAfterCreation: boolean;
17+
defaultPackageManager: "null" | "Yarn" | "NPM" | "pnpm" | "Bun";
18+
monorepoMode: {
19+
DirectoryName: string | null;
3520
};
36-
pages: {
37-
defaultTemplate: string;
21+
vueFiles: {
22+
template: {
23+
defaultLanguage: "html" | "pug";
24+
}
25+
firstTag: "template" | "script";
26+
script: {
27+
type: "setup" | "normal";
28+
defaultLanguage: "js" | "ts";
29+
};
30+
style: {
31+
addStyleTag: boolean;
32+
alwaysScoped: boolean;
33+
defaultLanguage:
34+
| "css"
35+
| "scss"
36+
| "sass"
37+
| "less"
38+
| "stylus"
39+
| "postcss";
40+
};
41+
pages: {
42+
defaultTemplate: string;
43+
};
44+
layouts: {
45+
defaultTemplate: string;
46+
};
3847
};
39-
layouts: {
40-
defaultTemplate: string;
48+
intellisense: {
49+
vueFiles: boolean;
50+
nuxtignore: boolean;
51+
nuxtrc: boolean;
4152
};
42-
};
43-
intellisense: {
44-
vueFiles: boolean;
45-
nuxtignore: boolean;
46-
nuxtrc: boolean;
47-
};
4853
snippets: {
4954
nuxt: boolean;
5055
nitro: boolean;
51-
}
56+
}
57+
}
58+
59+
interface TSConfigNuxt extends TSConfig {
60+
vueCompilerOptions?: {
61+
plugins?: string[] | undefined;
62+
}
5263
}

src/utils/watchers.ts

Lines changed: 12 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,24 +1,26 @@
11
import { workspace, window, commands, ConfigurationChangeEvent, Disposable } from 'vscode';
22

3-
export function createConfigWatcher(configKey: string, callback?: () => Promise<void>): Disposable {
3+
export function createConfigWatcher(configKey: string, callback?: () => Promise<void>, defaultBehavior?: boolean): Disposable {
44
const watcher = workspace.onDidChangeConfiguration(async (event: ConfigurationChangeEvent) => {
55
if (event.affectsConfiguration(configKey)) {
66
// Execute the provided callback when the configuration changes.
77
if (callback && typeof callback === 'function') {
88
await callback();
99
}
1010

11-
const question = window.showInformationMessage(
12-
`Nuxtr configuration updated.`,
13-
'Reload Window'
14-
);
11+
if (defaultBehavior) {
12+
const question = window.showInformationMessage(
13+
`Nuxtr configuration updated.`,
14+
'Reload Window'
15+
);
1516

16-
question.then((answer) => {
17-
if (answer === 'Reload Window') {
18-
commands.executeCommand('workbench.action.reloadWindow');
17+
question.then((answer) => {
18+
if (answer === 'Reload Window') {
19+
commands.executeCommand('workbench.action.reloadWindow');
1920

20-
}
21-
});
21+
}
22+
});
23+
}
2224
}
2325
});
2426

src/watchers/config.ts

Lines changed: 50 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,57 @@
1-
import { Disposable } from 'vscode';
2-
import { createConfigWatcher, getConfiguration } from '../utils';
1+
import { Disposable, window } from 'vscode';
2+
import { createConfigWatcher, getConfiguration, getProjectDependencies, projectRootDirectory } from '../utils';
3+
import { existsSync } from 'fs';
34
import { toggleSnippets } from '../snippets';
5+
import { TSConfigNuxt } from '../types';
6+
import { readTSConfig } from 'pkg-types'
7+
import nuxtrCommands from '../commands'
8+
import { PugConfigurationSteps } from '../commands/Templates'
49

5-
const snippetsConfig = getConfiguration().snippets
10+
11+
const watcherDefaultBehavior = false
12+
const dependencies = getProjectDependencies() as unknown as Array<string>;
613

714
export const snippetsConfigWatcher: Disposable = createConfigWatcher('nuxtr.snippets', async () => {
8-
console.log('snippets', snippetsConfig);
915
await toggleSnippets()
1016
return Promise.resolve();
1117
});
18+
19+
export const templatesConfigWatcher: Disposable = createConfigWatcher('nuxtr.vueFiles.template.defaultLanguage', async () => {
20+
const options: string[] = [];
21+
22+
if (getConfiguration().vueFiles.template.defaultLanguage === 'pug') {
23+
24+
25+
if (!dependencies.includes('pug')) {
26+
options.push(PugConfigurationSteps.installPug)
27+
}
28+
29+
if (!dependencies.includes('@vue/language-plugin-pug')) {
30+
options.push(PugConfigurationSteps.installLanguagePlugin)
31+
}
32+
33+
const path = `${projectRootDirectory()}/tsconfig.json`;
34+
let tsconfig: TSConfigNuxt = await readTSConfig(path);
35+
36+
if (!existsSync(path)) {
37+
return;
38+
}
39+
40+
const vueCompilerPlugins: string[] = tsconfig.vueCompilerOptions?.plugins ?? [];
41+
if (!vueCompilerPlugins.includes('@vue/language-plugin-pug')) {
42+
options.push(PugConfigurationSteps.addPluginToTSConfig)
43+
}
44+
45+
46+
if (options.length > 0) {
47+
const question = window.showInformationMessage('Pug is not configured properly', 'Configure Pug')
48+
question.then((answer) => {
49+
if (answer === 'Configure Pug') {
50+
nuxtrCommands.configurePug(options);
51+
}
52+
})
53+
54+
55+
}
56+
}
57+
});

0 commit comments

Comments
 (0)