提交 0b21524f 编写于 作者: J Johannes Rieken

prep for #41882

上级 0e93f650
......@@ -8,12 +8,14 @@ import { URI } from 'vs/base/common/uri';
import { isNonEmptyArray } from 'vs/base/common/arrays';
import { Range } from 'vs/editor/common/core/range';
import { ITextModel } from 'vs/editor/common/model';
import { registerDefaultLanguageCommand, registerLanguageCommand } from 'vs/editor/browser/editorExtensions';
import { registerLanguageCommand } from 'vs/editor/browser/editorExtensions';
import { DocumentFormattingEditProviderRegistry, DocumentRangeFormattingEditProviderRegistry, OnTypeFormattingEditProviderRegistry, FormattingOptions, TextEdit } from 'vs/editor/common/modes';
import { IModelService } from 'vs/editor/common/services/modelService';
import { first } from 'vs/base/common/async';
import { Position } from 'vs/editor/common/core/position';
import { CancellationToken } from 'vs/base/common/cancellation';
import { IEditorWorkerService } from 'vs/editor/common/services/editorWorkerService';
import { ITelemetryService } from 'vs/platform/telemetry/common/telemetry';
export class NoProviderError extends Error {
......@@ -32,44 +34,114 @@ export class NoProviderError extends Error {
}
}
export function getDocumentRangeFormattingEdits(model: ITextModel, range: Range, options: FormattingOptions, token: CancellationToken): Promise<TextEdit[] | undefined | null> {
const providers = DocumentRangeFormattingEditProviderRegistry.ordered(model);
if (providers.length === 0) {
export function getDocumentRangeFormattingEdits(
telemetryService: ITelemetryService,
workerService: IEditorWorkerService,
model: ITextModel,
range: Range,
options: FormattingOptions,
token: CancellationToken
): Promise<TextEdit[] | undefined | null> {
const allProvider = DocumentRangeFormattingEditProviderRegistry.ordered(model);
/* __GDPR__
"formatterInfo" : {
"type" : { "classification": "SystemMetaData", "purpose": "FeatureInsight" },
"language" : { "classification": "SystemMetaData", "purpose": "FeatureInsight" },
"count" : { "classification": "SystemMetaData", "purpose": "FeatureInsight", "isMeasurement": true }
}
*/
telemetryService.publicLog('formatterInfo', {
type: 'range',
language: model.getLanguageIdentifier().language,
count: allProvider.length,
});
if (allProvider.length === 0) {
return Promise.reject(new NoProviderError());
}
return first(providers.map(provider => () => {
return Promise.resolve(provider.provideDocumentRangeFormattingEdits(model, range, options, token))
.then(undefined, onUnexpectedExternalError);
}), isNonEmptyArray);
return first(allProvider.map(provider => () => {
return Promise.resolve(provider.provideDocumentRangeFormattingEdits(model, range, options, token)).catch(onUnexpectedExternalError);
}), isNonEmptyArray).then(edits => {
// break edits into smaller edits
return workerService.computeMoreMinimalEdits(model.uri, edits);
});
}
export function getDocumentFormattingEdits(model: ITextModel, options: FormattingOptions, token: CancellationToken): Promise<TextEdit[] | null | undefined> {
export function getDocumentFormattingEdits(
telemetryService: ITelemetryService,
workerService: IEditorWorkerService,
model: ITextModel,
options: FormattingOptions,
token: CancellationToken
): Promise<TextEdit[] | null | undefined> {
const providers = DocumentFormattingEditProviderRegistry.ordered(model);
/* __GDPR__
"formatterInfo" : {
"type" : { "classification": "SystemMetaData", "purpose": "FeatureInsight" },
"language" : { "classification": "SystemMetaData", "purpose": "FeatureInsight" },
"count" : { "classification": "SystemMetaData", "purpose": "FeatureInsight", "isMeasurement": true }
}
*/
telemetryService.publicLog('formatterInfo', {
type: 'document',
language: model.getLanguageIdentifier().language,
count: providers.length,
});
// try range formatters when no document formatter is registered
if (providers.length === 0) {
return getDocumentRangeFormattingEdits(model, model.getFullModelRange(), options, token);
return getDocumentRangeFormattingEdits(telemetryService, workerService, model, model.getFullModelRange(), options, token);
}
return first(providers.map(provider => () => {
return Promise.resolve(provider.provideDocumentFormattingEdits(model, options, token))
.then(undefined, onUnexpectedExternalError);
}), isNonEmptyArray);
// first with result wins...
return Promise.resolve(provider.provideDocumentFormattingEdits(model, options, token)).catch(onUnexpectedExternalError);
}), isNonEmptyArray).then(edits => {
// break edits into smaller edits
return workerService.computeMoreMinimalEdits(model.uri, edits);
});
}
export function getOnTypeFormattingEdits(model: ITextModel, position: Position, ch: string, options: FormattingOptions): Promise<TextEdit[] | null | undefined> {
const [support] = OnTypeFormattingEditProviderRegistry.ordered(model);
if (!support) {
export function getOnTypeFormattingEdits(
telemetryService: ITelemetryService,
workerService: IEditorWorkerService,
model: ITextModel,
position: Position,
ch: string,
options: FormattingOptions
): Promise<TextEdit[] | null | undefined> {
const providers = OnTypeFormattingEditProviderRegistry.ordered(model);
/* __GDPR__
"formatterInfo" : {
"type" : { "classification": "SystemMetaData", "purpose": "FeatureInsight" },
"language" : { "classification": "SystemMetaData", "purpose": "FeatureInsight" },
"count" : { "classification": "SystemMetaData", "purpose": "FeatureInsight", "isMeasurement": true }
}
*/
telemetryService.publicLog('formatterInfo', {
type: 'ontype',
language: model.getLanguageIdentifier().language,
count: providers.length,
});
if (providers.length === 0) {
return Promise.resolve(undefined);
}
if (support.autoFormatTriggerCharacters.indexOf(ch) < 0) {
if (providers[0].autoFormatTriggerCharacters.indexOf(ch) < 0) {
return Promise.resolve(undefined);
}
return Promise.resolve(support.provideOnTypeFormattingEdits(model, position, ch, options, CancellationToken.None)).then(r => r, onUnexpectedExternalError);
return Promise.resolve(providers[0].provideOnTypeFormattingEdits(model, position, ch, options, CancellationToken.None)).catch(onUnexpectedExternalError).then(edits => {
return workerService.computeMoreMinimalEdits(model.uri, edits);
});
}
registerLanguageCommand('_executeFormatRangeProvider', function (accessor, args) {
......@@ -81,7 +153,7 @@ registerLanguageCommand('_executeFormatRangeProvider', function (accessor, args)
if (!model) {
throw illegalArgument('resource');
}
return getDocumentRangeFormattingEdits(model, Range.lift(range), options, CancellationToken.None);
return getDocumentRangeFormattingEdits(accessor.get(ITelemetryService), accessor.get(IEditorWorkerService), model, Range.lift(range), options, CancellationToken.None);
});
registerLanguageCommand('_executeFormatDocumentProvider', function (accessor, args) {
......@@ -94,13 +166,18 @@ registerLanguageCommand('_executeFormatDocumentProvider', function (accessor, ar
throw illegalArgument('resource');
}
return getDocumentFormattingEdits(model, options, CancellationToken.None);
return getDocumentFormattingEdits(accessor.get(ITelemetryService), accessor.get(IEditorWorkerService), model, options, CancellationToken.None);
});
registerDefaultLanguageCommand('_executeFormatOnTypeProvider', function (model, position, args) {
const { ch, options } = args;
if (typeof ch !== 'string') {
throw illegalArgument('ch');
registerLanguageCommand('_executeFormatOnTypeProvider', function (accessor, args) {
const { resource, position, ch, options } = args;
if (!(resource instanceof URI) || !Position.isIPosition(position) || typeof ch !== 'string') {
throw illegalArgument();
}
return getOnTypeFormattingEdits(model, position, ch, options);
const model = accessor.get(IModelService).getModel(resource);
if (!model) {
throw illegalArgument('resource');
}
return getOnTypeFormattingEdits(accessor.get(ITelemetryService), accessor.get(IEditorWorkerService), model, Position.lift(position), ch, options);
});
......@@ -5,7 +5,6 @@
import { alert } from 'vs/base/browser/ui/aria/aria';
import { isNonEmptyArray } from 'vs/base/common/arrays';
import { sequence } from 'vs/base/common/async';
import { CancellationToken } from 'vs/base/common/cancellation';
import { KeyChord, KeyCode, KeyMod } from 'vs/base/common/keyCodes';
import { dispose, IDisposable } from 'vs/base/common/lifecycle';
......@@ -20,7 +19,7 @@ import { EditorContextKeys } from 'vs/editor/common/editorContextKeys';
import { ISingleEditOperation } from 'vs/editor/common/model';
import { DocumentFormattingEditProviderRegistry, DocumentRangeFormattingEditProviderRegistry, FormattingOptions, OnTypeFormattingEditProviderRegistry } from 'vs/editor/common/modes';
import { IEditorWorkerService } from 'vs/editor/common/services/editorWorkerService';
import { getOnTypeFormattingEdits, NoProviderError } from 'vs/editor/contrib/format/format';
import { getOnTypeFormattingEdits, NoProviderError, getDocumentFormattingEdits, getDocumentRangeFormattingEdits } from 'vs/editor/contrib/format/format';
import { FormattingEdit } from 'vs/editor/contrib/format/formattingEdit';
import * as nls from 'vs/nls';
import { CommandsRegistry } from 'vs/platform/commands/common/commands';
......@@ -62,38 +61,16 @@ export const enum FormatRangeType {
Selection,
}
export function formatDocumentRange(telemetryService: ITelemetryService, workerService: IEditorWorkerService, editor: IActiveCodeEditor, rangeOrRangeType: Range | FormatRangeType, options: FormattingOptions, token: CancellationToken): Promise<void> {
export function formatDocumentRange(
telemetryService: ITelemetryService,
workerService: IEditorWorkerService,
editor: IActiveCodeEditor,
rangeOrRangeType: Range | FormatRangeType,
options: FormattingOptions,
token: CancellationToken
): Promise<void> {
const provider = DocumentRangeFormattingEditProviderRegistry.ordered(editor.getModel());
if (provider.length === 0) {
return Promise.reject(new NoProviderError());
}
// Know how often multiple providers clash and (for now)
// continue picking the 'first' provider
if (provider.length !== 1) {
/* __GDPR__
"manyformatters" : {
"type" : { "classification": "SystemMetaData", "purpose": "FeatureInsight" },
"language" : { "classification": "SystemMetaData", "purpose": "FeatureInsight" },
"count" : { "classification": "SystemMetaData", "purpose": "FeatureInsight", "isMeasurement": true }
}
*/
telemetryService.publicLog('manyformatters', {
type: 'range',
language: editor.getModel().getLanguageIdentifier().language,
count: provider.length,
});
provider.length = 1;
}
let allEdits: ISingleEditOperation[] = [];
editor.pushUndoStop();
return sequence(provider.map(provider => {
// create a formatting task per provider. they run sequentially,
// potentially undoing the working of a previous formatter
return () => {
const state = new EditorState(editor, CodeEditorStateFlag.Value | CodeEditorStateFlag.Position);
const model = editor.getModel();
......@@ -112,76 +89,36 @@ export function formatDocumentRange(telemetryService: ITelemetryService, workerS
// as is
range = rangeOrRangeType;
}
return Promise.resolve(provider.provideDocumentRangeFormattingEdits(model, range, options, token)).then(edits => {
// break edits into smaller edits
return workerService.computeMoreMinimalEdits(editor.getModel().uri, edits);
}).then(edits => {
return getDocumentRangeFormattingEdits(telemetryService, workerService, model, range, options, token).then(edits => {
// make edit only when the editor didn't change while
// computing and only when there are edits
if (state.validate(editor) && isNonEmptyArray(edits)) {
FormattingEdit.execute(editor, edits);
allEdits = allEdits.concat(edits);
}
});
};
})).then(() => {
alertFormattingEdits(allEdits);
editor.pushUndoStop();
alertFormattingEdits(edits);
editor.focus();
editor.revealPositionInCenterIfOutsideViewport(editor.getPosition(), editorCommon.ScrollType.Immediate);
}
});
}
export function formatDocument(telemetryService: ITelemetryService, workerService: IEditorWorkerService, editor: IActiveCodeEditor, options: FormattingOptions, token: CancellationToken): Promise<void> {
const provider = DocumentFormattingEditProviderRegistry.ordered(editor.getModel());
if (provider.length === 0) {
return formatDocumentRange(telemetryService, workerService, editor, FormatRangeType.Full, options, token);
}
// Know how often multiple providers clash and (for now)
// continue picking the 'first' provider
if (provider.length !== 1) {
/* __GDPR__
"manyformatters" : {
"type" : { "classification": "SystemMetaData", "purpose": "FeatureInsight" },
"language" : { "classification": "SystemMetaData", "purpose": "FeatureInsight" },
"count" : { "classification": "SystemMetaData", "purpose": "FeatureInsight", "isMeasurement": true }
}
*/
telemetryService.publicLog('manyformatters', {
type: 'document',
language: editor.getModel().getLanguageIdentifier().language,
count: provider.length,
});
provider.length = 1;
}
let allEdits: ISingleEditOperation[] = [];
editor.pushUndoStop();
return sequence(provider.map(provider => {
// create a formatting task per provider. they run sequentially,
// potentially undoing the working of a previous formatter
return () => {
const allEdits: ISingleEditOperation[] = [];
const state = new EditorState(editor, CodeEditorStateFlag.Value | CodeEditorStateFlag.Position);
const model = editor.getModel();
return Promise.resolve(provider.provideDocumentFormattingEdits(model, options, token)).then(edits => {
// break edits into smaller edits
return workerService.computeMoreMinimalEdits(editor.getModel().uri, edits);
}).then(edits => {
return getDocumentFormattingEdits(telemetryService, workerService, editor.getModel(), options, token).then(edits => {
// make edit only when the editor didn't change while
// computing and only when there are edits
if (state.validate(editor) && isNonEmptyArray(edits)) {
FormattingEdit.execute(editor, edits);
allEdits = allEdits.concat(edits);
}
});
};
})).then(() => {
alertFormattingEdits(allEdits);
editor.pushUndoStop();
editor.focus();
editor.revealPositionInCenterIfOutsideViewport(editor.getPosition(), editorCommon.ScrollType.Immediate);
}
});
}
......@@ -189,39 +126,38 @@ class FormatOnType implements editorCommon.IEditorContribution {
private static readonly ID = 'editor.contrib.autoFormat';
private editor: ICodeEditor;
private workerService: IEditorWorkerService;
private callOnDispose: IDisposable[];
private callOnModel: IDisposable[];
constructor(editor: ICodeEditor, @IEditorWorkerService workerService: IEditorWorkerService) {
this.editor = editor;
this.workerService = workerService;
this.callOnDispose = [];
this.callOnModel = [];
private readonly _editor: ICodeEditor;
private _callOnDispose: IDisposable[] = [];
private _callOnModel: IDisposable[] = [];
this.callOnDispose.push(editor.onDidChangeConfiguration(() => this.update()));
this.callOnDispose.push(editor.onDidChangeModel(() => this.update()));
this.callOnDispose.push(editor.onDidChangeModelLanguage(() => this.update()));
this.callOnDispose.push(OnTypeFormattingEditProviderRegistry.onDidChange(this.update, this));
constructor(
editor: ICodeEditor,
@ITelemetryService private readonly _telemetryService: ITelemetryService,
@IEditorWorkerService private readonly _workerService: IEditorWorkerService
) {
this._editor = editor;
this._callOnDispose.push(editor.onDidChangeConfiguration(() => this.update()));
this._callOnDispose.push(editor.onDidChangeModel(() => this.update()));
this._callOnDispose.push(editor.onDidChangeModelLanguage(() => this.update()));
this._callOnDispose.push(OnTypeFormattingEditProviderRegistry.onDidChange(this.update, this));
}
private update(): void {
// clean up
this.callOnModel = dispose(this.callOnModel);
this._callOnModel = dispose(this._callOnModel);
// we are disabled
if (!this.editor.getConfiguration().contribInfo.formatOnType) {
if (!this._editor.getConfiguration().contribInfo.formatOnType) {
return;
}
// no model
if (!this.editor.hasModel()) {
if (!this._editor.hasModel()) {
return;
}
const model = this.editor.getModel();
const model = this._editor.getModel();
// no support
const [support] = OnTypeFormattingEditProviderRegistry.ordered(model);
......@@ -234,7 +170,7 @@ class FormatOnType implements editorCommon.IEditorContribution {
for (let ch of support.autoFormatTriggerCharacters) {
triggerChars.add(ch.charCodeAt(0));
}
this.callOnModel.push(this.editor.onDidType((text: string) => {
this._callOnModel.push(this._editor.onDidType((text: string) => {
let lastCharCode = text.charCodeAt(text.length - 1);
if (triggerChars.has(lastCharCode)) {
this.trigger(String.fromCharCode(lastCharCode));
......@@ -243,22 +179,22 @@ class FormatOnType implements editorCommon.IEditorContribution {
}
private trigger(ch: string): void {
if (!this.editor.hasModel()) {
if (!this._editor.hasModel()) {
return;
}
if (this.editor.getSelections().length > 1) {
if (this._editor.getSelections().length > 1) {
return;
}
const model = this.editor.getModel();
const position = this.editor.getPosition();
const model = this._editor.getModel();
const position = this._editor.getPosition();
let canceled = false;
// install a listener that checks if edits happens before the
// position on which we format right now. If so, we won't
// apply the format edits
const unbind = this.editor.onDidChangeModelContent((e) => {
const unbind = this._editor.onDidChangeModelContent((e) => {
if (e.isFlush) {
// a model.setValue() was called
// cancel only once
......@@ -281,12 +217,16 @@ class FormatOnType implements editorCommon.IEditorContribution {
let modelOpts = model.getOptions();
getOnTypeFormattingEdits(model, position, ch, {
getOnTypeFormattingEdits(
this._telemetryService,
this._workerService,
model,
position,
ch,
{
tabSize: modelOpts.tabSize,
insertSpaces: modelOpts.insertSpaces
}).then(edits => {
return this.workerService.computeMoreMinimalEdits(model.uri, edits);
}).then(edits => {
unbind.dispose();
......@@ -295,7 +235,7 @@ class FormatOnType implements editorCommon.IEditorContribution {
}
if (isNonEmptyArray(edits)) {
FormattingEdit.execute(this.editor, edits);
FormattingEdit.execute(this._editor, edits);
alertFormattingEdits(edits);
}
......@@ -310,8 +250,8 @@ class FormatOnType implements editorCommon.IEditorContribution {
}
public dispose(): void {
this.callOnDispose = dispose(this.callOnDispose);
this.callOnModel = dispose(this.callOnModel);
this._callOnDispose = dispose(this._callOnDispose);
this._callOnModel = dispose(this._callOnModel);
}
}
......
......@@ -36,6 +36,7 @@ import { extHostCustomer } from 'vs/workbench/api/electron-browser/extHostCustom
import { TextFileEditorModel } from 'vs/workbench/services/textfile/common/textFileEditorModel';
import { ISaveParticipant, ITextFileEditorModel, SaveReason } from 'vs/workbench/services/textfile/common/textfiles';
import { ExtHostContext, ExtHostDocumentSaveParticipantShape, IExtHostContext } from '../node/extHost.protocol';
import { ITelemetryService } from 'vs/platform/telemetry/common/telemetry';
export interface ISaveParticipantParticipant extends ISaveParticipant {
// progressMessage: string;
......@@ -215,7 +216,8 @@ class FormatOnSaveParticipant implements ISaveParticipantParticipant {
constructor(
@ICodeEditorService private readonly _editorService: ICodeEditorService,
@IEditorWorkerService private readonly _editorWorkerService: IEditorWorkerService,
@IConfigurationService private readonly _configurationService: IConfigurationService
@IConfigurationService private readonly _configurationService: IConfigurationService,
@ITelemetryService private readonly _telemetryService: ITelemetryService,
) {
// Nothing
}
......@@ -235,14 +237,14 @@ class FormatOnSaveParticipant implements ISaveParticipantParticipant {
return new Promise<ISingleEditOperation[] | null | undefined>((resolve, reject) => {
let source = new CancellationTokenSource();
let request = getDocumentFormattingEdits(model, { tabSize, insertSpaces }, source.token);
let request = getDocumentFormattingEdits(this._telemetryService, this._editorWorkerService, model, { tabSize, insertSpaces }, source.token);
setTimeout(() => {
reject(localize('timeout.formatOnSave', "Aborted format on save after {0}ms", timeout));
source.cancel();
}, timeout);
request.then(edits => this._editorWorkerService.computeMoreMinimalEdits(model.uri, edits)).then(resolve, err => {
request.then(resolve, err => {
if (!NoProviderError.is(err)) {
reject(err);
} else {
......
......@@ -46,6 +46,9 @@ import { getColors } from 'vs/editor/contrib/colorPicker/color';
import { CancellationToken } from 'vs/base/common/cancellation';
import { nullExtensionDescription as defaultExtension } from 'vs/workbench/services/extensions/common/extensions';
import { provideSelectionRanges } from 'vs/editor/contrib/smartSelect/smartSelect';
import { NullTelemetryService } from 'vs/platform/telemetry/common/telemetryUtils';
import { mock } from 'vs/workbench/test/electron-browser/api/mock';
import { IEditorWorkerService } from 'vs/editor/common/services/editorWorkerService';
const defaultSelector = { scheme: 'far' };
const model: ITextModel = EditorModel.createFromString(
......@@ -64,6 +67,8 @@ let disposables: vscode.Disposable[] = [];
let rpcProtocol: TestRPCProtocol;
let originalErrorHandler: (e: any) => any;
suite('ExtHostLanguageFeatures', function () {
suiteSetup(() => {
......@@ -906,6 +911,12 @@ suite('ExtHostLanguageFeatures', function () {
// --- format
const NullWorkerService = new class extends mock<IEditorWorkerService>() {
computeMoreMinimalEdits(resource: URI, edits: modes.TextEdit[] | null | undefined): Promise<modes.TextEdit[] | null | undefined> {
return Promise.resolve(edits);
}
};
test('Format Doc, data conversion', async () => {
disposables.push(extHost.registerDocumentFormattingEditProvider(defaultExtension, defaultSelector, new class implements vscode.DocumentFormattingEditProvider {
provideDocumentFormattingEdits(): any {
......@@ -914,7 +925,7 @@ suite('ExtHostLanguageFeatures', function () {
}));
await rpcProtocol.sync();
let value = await getDocumentFormattingEdits(model, { insertSpaces: true, tabSize: 4 }, CancellationToken.None);
let value = await getDocumentFormattingEdits(NullTelemetryService, NullWorkerService, model, { insertSpaces: true, tabSize: 4 }, CancellationToken.None);
assert.equal(value.length, 2);
let [first, second] = value;
assert.equal(first.text, 'testing');
......@@ -932,7 +943,7 @@ suite('ExtHostLanguageFeatures', function () {
}));
await rpcProtocol.sync();
return getDocumentFormattingEdits(model, { insertSpaces: true, tabSize: 4 }, CancellationToken.None);
return getDocumentFormattingEdits(NullTelemetryService, NullWorkerService, model, { insertSpaces: true, tabSize: 4 }, CancellationToken.None);
});
test('Format Doc, order', async () => {
......@@ -956,7 +967,7 @@ suite('ExtHostLanguageFeatures', function () {
}));
await rpcProtocol.sync();
let value = await getDocumentFormattingEdits(model, { insertSpaces: true, tabSize: 4 }, CancellationToken.None);
let value = await getDocumentFormattingEdits(NullTelemetryService, NullWorkerService, model, { insertSpaces: true, tabSize: 4 }, CancellationToken.None);
assert.equal(value.length, 1);
let [first] = value;
assert.equal(first.text, 'testing');
......@@ -971,7 +982,7 @@ suite('ExtHostLanguageFeatures', function () {
}));
await rpcProtocol.sync();
let value = await getDocumentRangeFormattingEdits(model, new EditorRange(1, 1, 1, 1), { insertSpaces: true, tabSize: 4 }, CancellationToken.None);
let value = await getDocumentRangeFormattingEdits(NullTelemetryService, NullWorkerService, model, new EditorRange(1, 1, 1, 1), { insertSpaces: true, tabSize: 4 }, CancellationToken.None);
assert.equal(value.length, 1);
let [first] = value;
assert.equal(first.text, 'testing');
......@@ -995,7 +1006,7 @@ suite('ExtHostLanguageFeatures', function () {
}
}));
await rpcProtocol.sync();
let value = await getDocumentRangeFormattingEdits(model, new EditorRange(1, 1, 1, 1), { insertSpaces: true, tabSize: 4 }, CancellationToken.None);
let value = await getDocumentRangeFormattingEdits(NullTelemetryService, NullWorkerService, model, new EditorRange(1, 1, 1, 1), { insertSpaces: true, tabSize: 4 }, CancellationToken.None);
assert.equal(value.length, 1);
let [first] = value;
assert.equal(first.text, 'range2');
......@@ -1013,7 +1024,7 @@ suite('ExtHostLanguageFeatures', function () {
}));
await rpcProtocol.sync();
return getDocumentRangeFormattingEdits(model, new EditorRange(1, 1, 1, 1), { insertSpaces: true, tabSize: 4 }, CancellationToken.None);
return getDocumentRangeFormattingEdits(NullTelemetryService, NullWorkerService, model, new EditorRange(1, 1, 1, 1), { insertSpaces: true, tabSize: 4 }, CancellationToken.None);
});
test('Format on Type, data conversion', async () => {
......@@ -1025,7 +1036,7 @@ suite('ExtHostLanguageFeatures', function () {
}, [';']));
await rpcProtocol.sync();
let value = await getOnTypeFormattingEdits(model, new EditorPosition(1, 1), ';', { insertSpaces: true, tabSize: 2 });
let value = await getOnTypeFormattingEdits(NullTelemetryService, NullWorkerService, model, new EditorPosition(1, 1), ';', { insertSpaces: true, tabSize: 2 });
assert.equal(value.length, 1);
let [first] = value;
assert.equal(first.text, ';');
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册