From 0be6912ffe828b3c56fbe91088f854c23d27414d Mon Sep 17 00:00:00 2001 From: Johannes Rieken Date: Tue, 1 Dec 2015 16:57:13 +0100 Subject: [PATCH] command: executeFormatOnTypeProvider --- src/vs/editor/contrib/format/common/format.ts | 31 ++++++++++++++---- .../contrib/format/common/formatActions.ts | 12 +++---- .../common/extHostLanguageFeatureCommands.ts | 32 +++++++++---------- .../api/extHostLanguageFeatures.test.ts | 22 ++++++++++++- 4 files changed, 67 insertions(+), 30 deletions(-) diff --git a/src/vs/editor/contrib/format/common/format.ts b/src/vs/editor/contrib/format/common/format.ts index d0889262cfb..681a9d7d0eb 100644 --- a/src/vs/editor/contrib/format/common/format.ts +++ b/src/vs/editor/contrib/format/common/format.ts @@ -22,29 +22,40 @@ export const FormatOnTypeRegistry = new LanguageFeatureRegistry { - const support = FormatRegistry.ordered(model)[0]; + const [support] = FormatRegistry.ordered(model); if (!support) { - return; + return TPromise.as(undefined); } return support.formatRange(model.getAssociatedResource(), range, options); } export function formatDocument(model: IModel, options: IFormattingOptions): TPromise { - const support = FormatRegistry.ordered(model)[0]; + const [support] = FormatRegistry.ordered(model); if (!support) { - return; + return TPromise.as(undefined); } if (typeof support.formatDocument !== 'function') { if (typeof support.formatRange === 'function') { return formatRange(model, model.getFullModelRange(), options); } else { - return; + return TPromise.as(undefined); } } return support.formatDocument(model.getAssociatedResource(), options); } +export function formatAfterKeystroke(model: IModel, position: IPosition, ch: string, options: IFormattingOptions): TPromise { + const [support] = FormatOnTypeRegistry.ordered(model); + if (!support) { + return TPromise.as(undefined); + } + if (support.autoFormatTriggerCharacters.indexOf(ch) < 0) { + return TPromise.as(undefined); + } + return support.formatAfterKeystroke(model.getAssociatedResource(), position, ch, options); +} + CommonEditorRegistry.registerLanguageCommand('_executeFormatRangeProvider', function(accessor, args) { const {resource, range, options} = args; if (!URI.isURI(resource) || !Range.isIRange(range)) { @@ -68,4 +79,12 @@ CommonEditorRegistry.registerLanguageCommand('_executeFormatDocumentProvider', f } return formatDocument(model, options) -}); \ No newline at end of file +}); + +CommonEditorRegistry.registerDefaultLanguageCommand('_executeFormatOnTypeProvider', function(model, position, args) { + const {ch, options } = args; + if (typeof ch !== 'string') { + throw illegalArgument('ch'); + } + return formatAfterKeystroke(model, position, ch, options); +}); diff --git a/src/vs/editor/contrib/format/common/formatActions.ts b/src/vs/editor/contrib/format/common/formatActions.ts index 25e5c5fce8f..bd5ab2c6b4e 100644 --- a/src/vs/editor/contrib/format/common/formatActions.ts +++ b/src/vs/editor/contrib/format/common/formatActions.ts @@ -15,7 +15,7 @@ import formatCommand = require('./formatCommand'); import {Range} from 'vs/editor/common/core/range'; import {INullService} from 'vs/platform/instantiation/common/instantiation'; import {KeyMod, KeyCode} from 'vs/base/common/keyCodes'; -import {FormatOnTypeRegistry, FormatRegistry, IFormattingSupport, formatRange, formatDocument} from '../common/format'; +import {FormatOnTypeRegistry, FormatRegistry, IFormattingSupport, formatRange, formatDocument, formatAfterKeystroke} from '../common/format'; interface IFormatOnTypeResult { range: EditorCommon.IEditorRange; @@ -66,7 +66,7 @@ class FormatOnType implements EditorCommon.IEditorContribution { var model = this.editor.getModel(); // no support - var support = FormatOnTypeRegistry.ordered(model)[0]; + var [support] = FormatOnTypeRegistry.ordered(model); if (!support || !support.autoFormatTriggerCharacters) { return; } @@ -75,12 +75,12 @@ class FormatOnType implements EditorCommon.IEditorContribution { this.formattingOptions = this.editor.getIndentationOptions(); // register typing listeners that will trigger the format - support.autoFormatTriggerCharacters.forEach(char => { - this.callOnModel.push(this.editor.addTypingListener(char, this.trigger.bind(this, support, char))); + support.autoFormatTriggerCharacters.forEach(ch => { + this.callOnModel.push(this.editor.addTypingListener(ch, this.trigger.bind(this, ch))); }); } - private trigger(support: IFormattingSupport, char: string): void { + private trigger(ch: string): void { if (this.editor.getSelections().length > 1) { return; @@ -116,7 +116,7 @@ class FormatOnType implements EditorCommon.IEditorContribution { } }); - support.formatAfterKeystroke(model.getAssociatedResource(), position, char, this.formattingOptions).then((edits) => { + formatAfterKeystroke(model, position, ch, this.formattingOptions).then(edits => { unbind(); diff --git a/src/vs/workbench/api/common/extHostLanguageFeatureCommands.ts b/src/vs/workbench/api/common/extHostLanguageFeatureCommands.ts index 15cb18343b3..043fcfef2fb 100644 --- a/src/vs/workbench/api/common/extHostLanguageFeatureCommands.ts +++ b/src/vs/workbench/api/common/extHostLanguageFeatureCommands.ts @@ -36,23 +36,6 @@ import {RenameRegistry} from 'vs/editor/contrib/rename/common/rename'; import {FormatRegistry, FormatOnTypeRegistry} from 'vs/editor/contrib/format/common/format'; import {ICodeLensData} from 'vs/editor/contrib/codelens/common/codelens'; - -// vscode.executeWorkspaceSymbolProvider -// vscode.executeDefinitionProvider -// vscode.executeHoverProvider -// vscode.executeDocumentHighlights -// vscode.executeReferenceProvider -// vscode.executeDocumentRenameProvider -// vscode.executeSignatureHelpProvider -// vscode.executeDocumentSymbolProvider -// vscode.executeCompletionItemProvider -// vscode.executeCodeActionProvider -// vscode.executeCodeLensProvider -// vscode.executeFormatDocumentProvider -// vscode.executeFormatRangeProvider - -// vscode.executeFormatOnTypeProvider - export class ExtHostLanguageFeatureCommands { private _commands: PluginHostCommands; @@ -74,6 +57,7 @@ export class ExtHostLanguageFeatureCommands { this._register('vscode.executeCodeLensProvider', this._executeCodeLensProvider); this._register('vscode.executeFormatDocumentProvider', this._executeFormatDocumentProvider); this._register('vscode.executeFormatRangeProvider', this._executeFormatRangeProvider); + this._register('vscode.executeFormatOnTypeProvider', this._executeFormatOnTypeProvider); } private _register(id: string, callback: (...args: any[]) => any): void { @@ -254,4 +238,18 @@ export class ExtHostLanguageFeatureCommands { } }); } + + private _executeFormatOnTypeProvider(resource: URI, position: types.Position, ch:string, options: vscode.FormattingOptions): Thenable { + const args = { + resource, + position: typeConverters.fromPosition(position), + ch, + options + }; + return this._commands.executeCommand('_executeFormatOnTypeProvider', args).then(value => { + if (Array.isArray(value)) { + return value.map(edit => new types.TextEdit(typeConverters.toRange(edit.range), edit.text)); + } + }); + } } \ No newline at end of file diff --git a/src/vs/workbench/test/common/api/extHostLanguageFeatures.test.ts b/src/vs/workbench/test/common/api/extHostLanguageFeatures.test.ts index 4af861e6a00..9a599e3250e 100644 --- a/src/vs/workbench/test/common/api/extHostLanguageFeatures.test.ts +++ b/src/vs/workbench/test/common/api/extHostLanguageFeatures.test.ts @@ -37,7 +37,7 @@ import {getNavigateToItems} from 'vs/workbench/parts/search/common/search'; import {rename} from 'vs/editor/contrib/rename/common/rename'; import {getParameterHints} from 'vs/editor/contrib/parameterHints/common/parameterHints'; import {suggest} from 'vs/editor/contrib/suggest/common/suggest'; -import {formatDocument, formatRange} from 'vs/editor/contrib/format/common/format'; +import {formatDocument, formatRange, formatAfterKeystroke} from 'vs/editor/contrib/format/common/format'; const defaultSelector = { scheme: 'far' }; const model: EditorCommon.IModel = new EditorModel( @@ -970,4 +970,24 @@ suite('ExtHostLanguageFeatures', function() { formatRange(model, { startLineNumber: 1, startColumn: 1, endLineNumber: 1, endColumn: 1 }, { insertSpaces: true, tabSize: 4 }).then(undefined, err => done()); }); }) + + test('Format on Type, data conversion', function(done) { + + disposables.push(extHost.registerOnTypeFormattingEditProvider(defaultSelector, { + provideOnTypeFormattingEdits(): any { + return [new types.TextEdit(new types.Range(0, 0, 0, 0), arguments[2])]; + } + }, [';'])); + + threadService.sync().then(() => { + formatAfterKeystroke(model, { lineNumber: 1, column: 1 }, ';', { insertSpaces: true, tabSize: 2 }).then(value => { + assert.equal(value.length, 1); + let [first] = value; + + assert.equal(first.text, ';'); + assert.deepEqual(first.range, { startLineNumber: 1, startColumn: 1, endLineNumber: 1, endColumn: 1 }); + done(); + }); + }); + }); }); \ No newline at end of file -- GitLab