From 88dbecc4b3c88fb8668a47269123b0516f6228bb Mon Sep 17 00:00:00 2001 From: SerKo Date: Sun, 30 Nov 2025 05:15:22 +0800 Subject: [PATCH 1/4] feat: add `vue.format.takeOver` setting --- extensions/vscode/lib/generated-meta.ts | 19 ++++- extensions/vscode/package.json | 21 ++++++ extensions/vscode/package.nls.json | 1 + packages/language-service/index.ts | 2 + .../lib/plugins/vue-format-takeover.ts | 71 +++++++++++++++++++ 5 files changed, 113 insertions(+), 1 deletion(-) create mode 100644 packages/language-service/lib/plugins/vue-format-takeover.ts diff --git a/extensions/vscode/lib/generated-meta.ts b/extensions/vscode/lib/generated-meta.ts index 0a1c45a05a..00568bbc07 100644 --- a/extensions/vscode/lib/generated-meta.ts +++ b/extensions/vscode/lib/generated-meta.ts @@ -4,7 +4,7 @@ // Meta info export const publisher = 'Vue'; export const name = 'volar'; -export const version = '3.1.0'; +export const version = '3.1.5'; export const displayName = 'Vue (Official)'; export const description = 'Language Support for Vue'; export const extensionId = `${publisher}.${name}`; @@ -56,6 +56,7 @@ export type ConfigKey = | 'vue.format.template.initialIndent' | 'vue.format.script.initialIndent' | 'vue.format.style.initialIndent' + | 'vue.format.takeOver' | 'vue.format.wrapAttributes'; export interface ConfigKeyTypeMap { @@ -79,6 +80,7 @@ export interface ConfigKeyTypeMap { 'vue.format.template.initialIndent': boolean; 'vue.format.script.initialIndent': boolean; 'vue.format.style.initialIndent': boolean; + 'vue.format.takeOver': { 'script'?: boolean; 'template'?: boolean; 'style'?: boolean }; 'vue.format.wrapAttributes': | 'auto' | 'force' @@ -110,6 +112,7 @@ export interface ConfigShorthandMap { formatTemplateInitialIndent: 'vue.format.template.initialIndent'; formatScriptInitialIndent: 'vue.format.script.initialIndent'; formatStyleInitialIndent: 'vue.format.style.initialIndent'; + formatTakeOver: 'vue.format.takeOver'; formatWrapAttributes: 'vue.format.wrapAttributes'; } @@ -134,6 +137,7 @@ export interface ConfigShorthandTypeMap { formatTemplateInitialIndent: boolean; formatScriptInitialIndent: boolean; formatStyleInitialIndent: boolean; + formatTakeOver: { 'script'?: boolean; 'template'?: boolean; 'style'?: boolean }; formatWrapAttributes: | 'auto' | 'force' @@ -333,6 +337,15 @@ export const configs = { key: 'vue.format.style.initialIndent', default: false, } as ConfigItem<'vue.format.style.initialIndent'>, + /** + * @key `vue.format.takeOver` + * @default `{"root":true,"script":true,"template":true,"style":true}` + * @type `object` + */ + formatTakeOver: { + key: 'vue.format.takeOver', + default: { 'root': true, 'script': true, 'template': true, 'style': true }, + } as ConfigItem<'vue.format.takeOver'>, /** * @key `vue.format.wrapAttributes` * @default `"auto"` @@ -365,6 +378,7 @@ export interface ScopedConfigKeyTypeMap { 'format.template.initialIndent': boolean; 'format.script.initialIndent': boolean; 'format.style.initialIndent': boolean; + 'format.takeOver': { 'script'?: boolean; 'template'?: boolean; 'style'?: boolean }; 'format.wrapAttributes': | 'auto' | 'force' @@ -398,6 +412,7 @@ export const scopedConfigs = { 'format.template.initialIndent': true, 'format.script.initialIndent': false, 'format.style.initialIndent': false, + 'format.takeOver': { 'root': true, 'script': true, 'template': true, 'style': true }, 'format.wrapAttributes': 'auto', } satisfies ScopedConfigKeyTypeMap, }; @@ -445,6 +460,7 @@ export interface NestedConfigs { 'style': { 'initialIndent': boolean; }; + 'takeOver': { 'script'?: boolean; 'template'?: boolean; 'style'?: boolean }; 'wrapAttributes': | 'auto' | 'force' @@ -499,6 +515,7 @@ export interface NestedScopedConfigs { 'style': { 'initialIndent': boolean; }; + 'takeOver': { 'script'?: boolean; 'template'?: boolean; 'style'?: boolean }; 'wrapAttributes': | 'auto' | 'force' diff --git a/extensions/vscode/package.json b/extensions/vscode/package.json index 1eacc9c7ff..dee2184b55 100644 --- a/extensions/vscode/package.json +++ b/extensions/vscode/package.json @@ -380,6 +380,27 @@ "default": false, "markdownDescription": "%configuration.format.style.initialIndent%" }, + "vue.format.takeOver": { + "type": "object", + "default": { + "root": true, + "script": true, + "template": true, + "style": true + }, + "properties": { + "script": { + "type": "boolean" + }, + "template": { + "type": "boolean" + }, + "style": { + "type": "boolean" + } + }, + "markdownDescription": "%configuration.format.takeOver%" + }, "vue.format.wrapAttributes": { "type": "string", "default": "auto", diff --git a/extensions/vscode/package.nls.json b/extensions/vscode/package.nls.json index e1d4ca00f4..125f444697 100644 --- a/extensions/vscode/package.nls.json +++ b/extensions/vscode/package.nls.json @@ -17,6 +17,7 @@ "configuration.format.script.initialIndent": "Initial indent for ` +`; + +const units = { + 'vue.format.style.enabled': { + description: 'disable style formatting', + output: ` + + + +`, + }, + 'vue.format.script.enabled': { + description: 'disable script formatting', + output: ` + + + +`, + }, + 'vue.format.template.enabled': { + description: 'disable template formatting', + output: ` + + + +`, + }, +}; + +for (const [setting, { description, output }] of Object.entries(units)) { + const title = '#' + __filename.split('.')[0]; + defineFormatTest({ + title: title + ' (' + description + ')', + languageId: 'vue', + input: snippet.trim(), + output: output.trim(), + settings: { [setting]: false }, + }); +} From ba79a861612004cf1b113bf6b57011601c9c7e7f Mon Sep 17 00:00:00 2001 From: Johnson Chu Date: Sun, 30 Nov 2025 20:29:33 +0800 Subject: [PATCH 4/4] Update vue-format-takeover.ts --- .../lib/plugins/vue-format-takeover.ts | 29 +++++++++---------- 1 file changed, 14 insertions(+), 15 deletions(-) diff --git a/packages/language-service/lib/plugins/vue-format-takeover.ts b/packages/language-service/lib/plugins/vue-format-takeover.ts index d69f700bcf..7736e2b9ad 100644 --- a/packages/language-service/lib/plugins/vue-format-takeover.ts +++ b/packages/language-service/lib/plugins/vue-format-takeover.ts @@ -11,6 +11,20 @@ export function create(): LanguageServicePlugin { }, }, create(context): LanguageServicePluginInstance { + return { + async provideDocumentFormattingEdits(document) { + if (await shouldSkip(document)) { + return []; + } + return undefined; + }, + async provideOnTypeFormattingEdits(document) { + if (await shouldSkip(document)) { + return []; + } + return undefined; + }, + }; async function shouldSkip(document: TextDocument): Promise { const decoded = context.decodeEmbeddedDocumentUri(URI.parse(document.uri)); if (!decoded) { @@ -35,21 +49,6 @@ export function create(): LanguageServicePlugin { return false; } - - return { - async provideDocumentFormattingEdits(document) { - if (await shouldSkip(document)) { - return []; - } - return undefined; - }, - async provideOnTypeFormattingEdits(document) { - if (await shouldSkip(document)) { - return []; - } - return undefined; - }, - }; }, }; }