From 4e824dc316e4c85c5d1cd0e55cda72bebe9c5785 Mon Sep 17 00:00:00 2001 From: johnsoncodehk Date: Thu, 2 Jun 2022 14:42:33 +0800 Subject: [PATCH] feat: range formatting close #1370 --- .../src/features/documentFeatures.ts | 5 +++ .../src/registers/registerDocumentFeatures.ts | 1 + .../src/documentFeatures/format.ts | 45 +++++++++++++++---- 3 files changed, 43 insertions(+), 8 deletions(-) diff --git a/packages/vue-language-server/src/features/documentFeatures.ts b/packages/vue-language-server/src/features/documentFeatures.ts index 0b68544ed..8d5ae8b34 100644 --- a/packages/vue-language-server/src/features/documentFeatures.ts +++ b/packages/vue-language-server/src/features/documentFeatures.ts @@ -13,6 +13,11 @@ export function register( return vueDs.format(document, handler.options); }); }); + connection.onDocumentRangeFormatting(handler => { + return worker(handler.textDocument.uri, document => { + return vueDs.format(document, handler.options, handler.range); + }); + }); connection.onSelectionRanges(handler => { return worker(handler.textDocument.uri, document => { return vueDs.getSelectionRanges(document, handler.positions); diff --git a/packages/vue-language-server/src/registers/registerDocumentFeatures.ts b/packages/vue-language-server/src/registers/registerDocumentFeatures.ts index 024b9abd2..8dbceba98 100644 --- a/packages/vue-language-server/src/registers/registerDocumentFeatures.ts +++ b/packages/vue-language-server/src/registers/registerDocumentFeatures.ts @@ -22,5 +22,6 @@ export function register( } if (features.documentFormatting) { server.documentFormattingProvider = true; + server.documentRangeFormattingProvider = true; } } diff --git a/packages/vue-language-service/src/documentFeatures/format.ts b/packages/vue-language-service/src/documentFeatures/format.ts index 4db7b7485..c0e265816 100644 --- a/packages/vue-language-service/src/documentFeatures/format.ts +++ b/packages/vue-language-service/src/documentFeatures/format.ts @@ -6,10 +6,14 @@ import { EmbeddedDocumentSourceMap, VueDocument } from '../vueDocuments'; export function register(context: DocumentServiceRuntimeContext) { - return async (document: TextDocument, options: vscode.FormattingOptions) => { + return async (document: TextDocument, options: vscode.FormattingOptions, range?: vscode.Range) => { + + if (!range) { + range = vscode.Range.create(document.positionAt(0), document.positionAt(document.getText().length)); + } const originalDocument = document; - const rootEdits = await tryFormat(document); + const rootEdits = await tryFormat(document, range); const vueDocument = context.getVueDocument(document); if (!vueDocument) @@ -42,12 +46,41 @@ export function register(context: DocumentServiceRuntimeContext) { const sourceMap = vueDocument.sourceMapsMap.get(embedded.self); + let embeddedRange = sourceMap.getMappedRange(range.start, range.end)?.[0]; + + if (!embeddedRange) { + + let start = sourceMap.getMappedRange(range.start)?.[0].start; + let end = sourceMap.getMappedRange(range.end)?.[0].end; + + if (!start) { + const minSourceStart = Math.min(...sourceMap.mappings.map(m => m.sourceRange.start)); + if (document.offsetAt(range.start) <= minSourceStart) { + start = range.start; + } + } + + if (!end) { + const maxSourceEnd = Math.max(...sourceMap.mappings.map(m => m.sourceRange.end)); + if (document.offsetAt(range.end) >= maxSourceEnd) { + end = range.end; + } + } + + if (start && end) { + embeddedRange = { start, end }; + } + } + + if (!embeddedRange) + continue; + if (embedded.inheritParentIndent) toPatchIndent = { sourceMapEmbeddedDocumentUri: sourceMap.mappedDocument.uri, }; - const _edits = await tryFormat(sourceMap.mappedDocument); + const _edits = await tryFormat(sourceMap.mappedDocument, embeddedRange); if (!_edits) continue; @@ -124,13 +157,9 @@ export function register(context: DocumentServiceRuntimeContext) { } } - async function tryFormat(document: TextDocument) { + async function tryFormat(document: TextDocument, range: vscode.Range) { const plugins = context.getFormatPlugins(); - const range: vscode.Range = { - start: document.positionAt(0), - end: document.positionAt(document.getText().length), - }; context.updateTsLs(document);