mirror of
https://github.com/Microsoft/vscode
synced 2024-10-02 09:18:59 +00:00
[html] use TextDocument.applyEdit
This commit is contained in:
parent
4d78742a99
commit
7c5f344a2b
|
@ -4,7 +4,6 @@
|
|||
*--------------------------------------------------------------------------------------------*/
|
||||
'use strict';
|
||||
|
||||
import { applyEdits } from '../utils/edits';
|
||||
import { TextDocument, Range, TextEdit, FormattingOptions, Position } from 'vscode-languageserver-types';
|
||||
import { LanguageModes, Settings, LanguageModeRange } from './languageModes';
|
||||
import { pushAll } from '../utils/arrays';
|
||||
|
@ -57,7 +56,7 @@ export function format(languageModes: LanguageModes, document: TextDocument, for
|
|||
// perform a html format and apply changes to a new document
|
||||
let htmlMode = languageModes.getMode('html')!;
|
||||
let htmlEdits = htmlMode.format!(document, formatRange, formattingOptions, settings);
|
||||
let htmlFormattedContent = applyEdits(document, htmlEdits);
|
||||
let htmlFormattedContent = TextDocument.applyEdits(document, htmlEdits);
|
||||
let newDocument = TextDocument.create(document.uri + '.tmp', document.languageId, document.version, htmlFormattedContent);
|
||||
try {
|
||||
// run embedded formatters on html formatted content: - formatters see correct initial indent
|
||||
|
@ -83,7 +82,7 @@ export function format(languageModes: LanguageModes, document: TextDocument, for
|
|||
}
|
||||
|
||||
// apply all embedded format edits and create a single edit for all changes
|
||||
let resultContent = applyEdits(newDocument, embeddedEdits);
|
||||
let resultContent = TextDocument.applyEdits(newDocument, embeddedEdits);
|
||||
let resultReplaceText = resultContent.substring(document.offsetAt(formatRange.start), resultContent.length - afterFormatRangeLength);
|
||||
|
||||
result.push(TextEdit.replace(formatRange, resultReplaceText));
|
||||
|
|
|
@ -10,7 +10,6 @@ import * as path from 'path';
|
|||
import Uri from 'vscode-uri';
|
||||
import { TextDocument, CompletionList, CompletionItemKind, } from 'vscode-languageserver-types';
|
||||
import { getLanguageModes } from '../modes/languageModes';
|
||||
import { applyEdits } from '../utils/edits';
|
||||
import { getPathCompletionParticipant } from '../modes/pathCompletion';
|
||||
import { WorkspaceFolder } from 'vscode-languageserver';
|
||||
|
||||
|
@ -43,7 +42,7 @@ suite('Completions', () => {
|
|||
assert.equal(match.kind, expected.kind);
|
||||
}
|
||||
if (expected.resultText && match.textEdit) {
|
||||
assert.equal(applyEdits(document, [match.textEdit]), expected.resultText);
|
||||
assert.equal(TextDocument.applyEdits(document, [match.textEdit]), expected.resultText);
|
||||
}
|
||||
};
|
||||
|
||||
|
|
|
@ -26,16 +26,16 @@ suite('Emmet Support', () => {
|
|||
const document = TextDocument.create('test://test/test.' + syntax, syntax, 0, value);
|
||||
const position = document.positionAt(offset);
|
||||
const documentRegions = getLanguageModelCache<embeddedSupport.HTMLDocumentRegions>(10, 60, document => embeddedSupport.getDocumentRegions(htmlLanguageService, document));
|
||||
const mode = syntax == 'html' ? getHTMLMode(htmlLanguageService) : getCSSMode(documentRegions);
|
||||
const mode = syntax === 'html' ? getHTMLMode(htmlLanguageService) : getCSSMode(documentRegions);
|
||||
const emmetCompletionList: CompletionList = {
|
||||
isIncomplete: true,
|
||||
items: undefined
|
||||
}
|
||||
mode.setCompletionParticipants([getEmmetCompletionParticipants(document, position, document.languageId, {}, emmetCompletionList)])
|
||||
};
|
||||
mode.setCompletionParticipants([getEmmetCompletionParticipants(document, position, document.languageId, {}, emmetCompletionList)]);
|
||||
|
||||
const list = mode.doComplete!(document, position);
|
||||
assert.ok(list);
|
||||
assert.ok(emmetCompletionList)
|
||||
assert.ok(emmetCompletionList);
|
||||
|
||||
|
||||
if (expectedProposal && expectedProposalDoc) {
|
||||
|
|
|
@ -10,7 +10,7 @@ import * as fs from 'fs';
|
|||
|
||||
import * as assert from 'assert';
|
||||
import { getLanguageModes } from '../modes/languageModes';
|
||||
import { TextDocument, Range, TextEdit, FormattingOptions } from 'vscode-languageserver-types';
|
||||
import { TextDocument, Range, FormattingOptions } from 'vscode-languageserver-types';
|
||||
|
||||
import { format } from '../modes/formatting';
|
||||
|
||||
|
@ -41,7 +41,7 @@ suite('HTML Embedded Formatting', () => {
|
|||
|
||||
let result = format(languageModes, document, range, formatOptions, void 0, { css: true, javascript: true });
|
||||
|
||||
let actual = applyEdits(document, result);
|
||||
let actual = TextDocument.applyEdits(document, result);
|
||||
assert.equal(actual, expected, message);
|
||||
}
|
||||
|
||||
|
@ -111,25 +111,4 @@ suite('HTML Embedded Formatting', () => {
|
|||
assertFormat('<script src="/js/main.js"> </script>', '<script src="/js/main.js"> </script>');
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
function applyEdits(document: TextDocument, edits: TextEdit[]): string {
|
||||
let text = document.getText();
|
||||
let sortedEdits = edits.sort((a, b) => {
|
||||
let startDiff = document.offsetAt(b.range.start) - document.offsetAt(a.range.start);
|
||||
if (startDiff === 0) {
|
||||
return document.offsetAt(b.range.end) - document.offsetAt(a.range.end);
|
||||
}
|
||||
return startDiff;
|
||||
});
|
||||
let lastOffset = text.length;
|
||||
sortedEdits.forEach(e => {
|
||||
let startOffset = document.offsetAt(e.range.start);
|
||||
let endOffset = document.offsetAt(e.range.end);
|
||||
assert.ok(startOffset <= endOffset);
|
||||
assert.ok(endOffset <= lastOffset);
|
||||
text = text.substring(0, startOffset) + e.newText + text.substring(endOffset, text.length);
|
||||
lastOffset = startOffset;
|
||||
});
|
||||
return text;
|
||||
}
|
||||
});
|
|
@ -1,37 +0,0 @@
|
|||
/*---------------------------------------------------------------------------------------------
|
||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
* Licensed under the MIT License. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
'use strict';
|
||||
|
||||
import * as assert from 'assert';
|
||||
import { applyEdits } from '../utils/edits';
|
||||
import { TextDocument, TextEdit, Position, Range } from 'vscode-languageserver-types';
|
||||
|
||||
suite('Edits', () => {
|
||||
|
||||
test('inserts', function (): any {
|
||||
let input = TextDocument.create('foo://bar/f', 'html', 0, '012345678901234567890123456789');
|
||||
assert.equal(applyEdits(input, [TextEdit.insert(Position.create(0, 0), 'Hello')]), 'Hello012345678901234567890123456789');
|
||||
assert.equal(applyEdits(input, [TextEdit.insert(Position.create(0, 1), 'Hello')]), '0Hello12345678901234567890123456789');
|
||||
assert.equal(applyEdits(input, [TextEdit.insert(Position.create(0, 1), 'Hello'), TextEdit.insert(Position.create(0, 1), 'World')]), '0HelloWorld12345678901234567890123456789');
|
||||
assert.equal(applyEdits(input, [TextEdit.insert(Position.create(0, 2), 'One'), TextEdit.insert(Position.create(0, 1), 'Hello'), TextEdit.insert(Position.create(0, 1), 'World'), TextEdit.insert(Position.create(0, 2), 'Two'), TextEdit.insert(Position.create(0, 2), 'Three')]), '0HelloWorld1OneTwoThree2345678901234567890123456789');
|
||||
});
|
||||
|
||||
test('replace', function (): any {
|
||||
let input = TextDocument.create('foo://bar/f', 'html', 0, '012345678901234567890123456789');
|
||||
assert.equal(applyEdits(input, [TextEdit.replace(Range.create(Position.create(0, 3), Position.create(0, 6)), 'Hello')]), '012Hello678901234567890123456789');
|
||||
assert.equal(applyEdits(input, [TextEdit.replace(Range.create(Position.create(0, 3), Position.create(0, 6)), 'Hello'), TextEdit.replace(Range.create(Position.create(0, 6), Position.create(0, 9)), 'World')]), '012HelloWorld901234567890123456789');
|
||||
assert.equal(applyEdits(input, [TextEdit.replace(Range.create(Position.create(0, 3), Position.create(0, 6)), 'Hello'), TextEdit.insert(Position.create(0, 6), 'World')]), '012HelloWorld678901234567890123456789');
|
||||
assert.equal(applyEdits(input, [TextEdit.insert(Position.create(0, 6), 'World'), TextEdit.replace(Range.create(Position.create(0, 3), Position.create(0, 6)), 'Hello')]), '012HelloWorld678901234567890123456789');
|
||||
assert.equal(applyEdits(input, [TextEdit.insert(Position.create(0, 3), 'World'), TextEdit.replace(Range.create(Position.create(0, 3), Position.create(0, 6)), 'Hello')]), '012WorldHello678901234567890123456789');
|
||||
|
||||
});
|
||||
|
||||
test('overlap', function (): any {
|
||||
let input = TextDocument.create('foo://bar/f', 'html', 0, '012345678901234567890123456789');
|
||||
assert.throws(_ => applyEdits(input, [TextEdit.replace(Range.create(Position.create(0, 3), Position.create(0, 6)), 'Hello'), TextEdit.insert(Position.create(0, 3), 'World')]));
|
||||
assert.throws(_ => applyEdits(input, [TextEdit.replace(Range.create(Position.create(0, 3), Position.create(0, 6)), 'Hello'), TextEdit.insert(Position.create(0, 4), 'World')]));
|
||||
});
|
||||
|
||||
});
|
|
@ -1,32 +0,0 @@
|
|||
/*---------------------------------------------------------------------------------------------
|
||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
* Licensed under the MIT License. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
'use strict';
|
||||
|
||||
import { TextDocument, TextEdit } from 'vscode-languageserver-types';
|
||||
import { mergeSort } from './arrays';
|
||||
|
||||
export function applyEdits(document: TextDocument, edits: TextEdit[]): string {
|
||||
let text = document.getText();
|
||||
let sortedEdits = mergeSort(edits, (a, b) => {
|
||||
let diff = a.range.start.line - b.range.start.line;
|
||||
if (diff === 0) {
|
||||
return a.range.start.character - b.range.start.character;
|
||||
}
|
||||
return 0;
|
||||
});
|
||||
let lastModifiedOffset = text.length;
|
||||
for (let i = sortedEdits.length - 1; i >= 0; i--) {
|
||||
let e = sortedEdits[i];
|
||||
let startOffset = document.offsetAt(e.range.start);
|
||||
let endOffset = document.offsetAt(e.range.end);
|
||||
if (endOffset <= lastModifiedOffset) {
|
||||
text = text.substring(0, startOffset) + e.newText + text.substring(endOffset, text.length);
|
||||
} else {
|
||||
throw new Error('Ovelapping edit');
|
||||
}
|
||||
lastModifiedOffset = startOffset;
|
||||
}
|
||||
return text;
|
||||
}
|
Loading…
Reference in a new issue