diff --git a/src/vs/editor/common/commands/replaceCommand.ts b/src/vs/editor/common/commands/replaceCommand.ts index c3c2c765bc412379483a7cec8f5d0b2de2f4ecf0..1083964b0ff6d76e7dd3e99ba91c9f0ad9189e42 100644 --- a/src/vs/editor/common/commands/replaceCommand.ts +++ b/src/vs/editor/common/commands/replaceCommand.ts @@ -10,12 +10,14 @@ import { Range } from 'vs/editor/common/core/range'; export class ReplaceCommand implements editorCommon.ICommand { - private _range: Range; - private _text: string; + private readonly _range: Range; + private readonly _text: string; + public readonly insertsAutoWhitespace: boolean; - constructor(range: Range, text: string) { + constructor(range: Range, text: string, insertsAutoWhitespace: boolean = false) { this._range = range; this._text = text; + this.insertsAutoWhitespace = insertsAutoWhitespace; } public getEditOperations(model: editorCommon.ITokenizedModel, builder: editorCommon.IEditOperationBuilder): void { @@ -36,12 +38,14 @@ export class ReplaceCommand implements editorCommon.ICommand { export class ReplaceCommandWithoutChangingPosition implements editorCommon.ICommand { - private _range: Range; - private _text: string; + private readonly _range: Range; + private readonly _text: string; + public readonly insertsAutoWhitespace: boolean; - constructor(range: Range, text: string) { + constructor(range: Range, text: string, insertsAutoWhitespace: boolean = false) { this._range = range; this._text = text; + this.insertsAutoWhitespace = insertsAutoWhitespace; } public getEditOperations(model: editorCommon.ITokenizedModel, builder: editorCommon.IEditOperationBuilder): void { @@ -62,16 +66,18 @@ export class ReplaceCommandWithoutChangingPosition implements editorCommon.IComm export class ReplaceCommandWithOffsetCursorState implements editorCommon.ICommand { - private _range: Range; - private _text: string; - private _columnDeltaOffset: number; - private _lineNumberDeltaOffset: number; + private readonly _range: Range; + private readonly _text: string; + private readonly _columnDeltaOffset: number; + private readonly _lineNumberDeltaOffset: number; + public readonly insertsAutoWhitespace: boolean; - constructor(range: Range, text: string, lineNumberDeltaOffset: number, columnDeltaOffset: number) { + constructor(range: Range, text: string, lineNumberDeltaOffset: number, columnDeltaOffset: number, insertsAutoWhitespace: boolean = false) { this._range = range; this._text = text; this._columnDeltaOffset = columnDeltaOffset; this._lineNumberDeltaOffset = lineNumberDeltaOffset; + this.insertsAutoWhitespace = insertsAutoWhitespace; } public getEditOperations(model: editorCommon.ITokenizedModel, builder: editorCommon.IEditOperationBuilder): void { diff --git a/src/vs/editor/common/controller/cursor.ts b/src/vs/editor/common/controller/cursor.ts index 2098d553134cb73b8cf275fe0f020bb8a184e599..f080795bf6d845a22a4dcb6c730dd34a4e904b17 100644 --- a/src/vs/editor/common/controller/cursor.ts +++ b/src/vs/editor/common/controller/cursor.ts @@ -14,7 +14,7 @@ import { Position } from 'vs/editor/common/core/position'; import { Range } from 'vs/editor/common/core/range'; import { Selection, SelectionDirection, ISelection } from 'vs/editor/common/core/selection'; import * as editorCommon from 'vs/editor/common/editorCommon'; -import { CursorColumns, CursorConfiguration, EditOperationResult, SingleCursorState, IViewModelHelper, CursorContext, CursorState, RevealTarget, IColumnSelectData, ICursors, CommandResult } from 'vs/editor/common/controller/cursorCommon'; +import { CursorColumns, CursorConfiguration, EditOperationResult, SingleCursorState, IViewModelHelper, CursorContext, CursorState, RevealTarget, IColumnSelectData, ICursors } from 'vs/editor/common/controller/cursorCommon'; import { LanguageConfigurationRegistry } from 'vs/editor/common/modes/languageConfigurationRegistry'; import { DeleteOperations } from 'vs/editor/common/controller/cursorDeleteOperations'; import { TypeOperations } from 'vs/editor/common/controller/cursorTypeOperations'; @@ -423,7 +423,7 @@ export class Cursor extends Disposable implements ICursors { this._cursors.setSelections(cursorState); } - private _getEditOperationsFromCommand(ctx: IExecContext, majorIdentifier: number, command: CommandResult): ICommandData { + private _getEditOperationsFromCommand(ctx: IExecContext, majorIdentifier: number, command: editorCommon.ICommand): ICommandData { // This method acts as a transaction, if the command fails // everything it has done is ignored let operations: editorCommon.IIdentifiedSingleEditOperation[] = []; @@ -442,7 +442,7 @@ export class Cursor extends Disposable implements ICursors { range: selection, text: text, forceMoveMarkers: false, - isAutoWhitespaceEdit: command.isAutoWhitespaceCommand + isAutoWhitespaceEdit: command.insertsAutoWhitespace }); }; @@ -494,7 +494,7 @@ export class Cursor extends Disposable implements ICursors { }; try { - command.command.getEditOperations(this._model, editOperationBuilder); + command.getEditOperations(this._model, editOperationBuilder); } catch (e) { e.friendlyMessage = nls.localize('corrupt.commands', "Unexpected exception while executing command."); onUnexpectedError(e); @@ -510,7 +510,7 @@ export class Cursor extends Disposable implements ICursors { }; } - private _getEditOperations(ctx: IExecContext, commands: CommandResult[]): ICommandsData { + private _getEditOperations(ctx: IExecContext, commands: editorCommon.ICommand[]): ICommandsData { let operations: editorCommon.IIdentifiedSingleEditOperation[] = []; let hadTrackedEditOperation: boolean = false; @@ -576,7 +576,7 @@ export class Cursor extends Disposable implements ICursors { return loserCursorsMap; } - private _arrayIsEmpty(commands: CommandResult[]): boolean { + private _arrayIsEmpty(commands: editorCommon.ICommand[]): boolean { for (let i = 0, len = commands.length; i < len; i++) { if (commands[i]) { return false; @@ -585,7 +585,7 @@ export class Cursor extends Disposable implements ICursors { return true; } - private _innerExecuteCommands(ctx: IExecContext, commands: CommandResult[]): void { + private _innerExecuteCommands(ctx: IExecContext, commands: editorCommon.ICommand[]): void { if (this._configuration.editor.readOnly) { return; @@ -655,7 +655,7 @@ export class Cursor extends Disposable implements ICursors { for (let i = 0; i < selectionsBefore.length; i++) { if (groupedInverseEditOperations[i].length > 0) { groupedInverseEditOperations[i].sort(minorBasedSorter); - cursorSelections[i] = commands[i].command.computeCursorState(this._model, { + cursorSelections[i] = commands[i].computeCursorState(this._model, { getInverseEditOperations: () => { return groupedInverseEditOperations[i]; }, @@ -1012,26 +1012,16 @@ export class Cursor extends Disposable implements ICursors { this._cursors.killSecondaryCursors(); - return new EditOperationResult( - [ - new CommandResult(command, false) - ], - { - shouldPushStackElementBefore: true, - shouldPushStackElementAfter: true - } - ); + return new EditOperationResult([command], { + shouldPushStackElementBefore: true, + shouldPushStackElementAfter: true + }); } private _externalExecuteCommands(args: CursorOperationArgs): EditOperationResult { const commands = args.eventData; - let _commands: CommandResult[] = []; - for (let i = 0, len = commands.length; i < len; i++) { - _commands[i] = new CommandResult(commands[i], false); - } - - return new EditOperationResult(_commands, { + return new EditOperationResult(commands, { shouldPushStackElementBefore: true, shouldPushStackElementAfter: true }); diff --git a/src/vs/editor/common/controller/cursorCommon.ts b/src/vs/editor/common/controller/cursorCommon.ts index 69ff558302f3527e56fcd53af68fe095949010b7..8c37d25a581132f3ab0213757abc8bb5f2e124c0 100644 --- a/src/vs/editor/common/controller/cursorCommon.ts +++ b/src/vs/editor/common/controller/cursorCommon.ts @@ -427,28 +427,16 @@ export class CursorState { } } -export class CommandResult { - _commandResultBrand: void; - - readonly command: ICommand; - readonly isAutoWhitespaceCommand: boolean; - - constructor(command: ICommand, isAutoWhitespaceCommand: boolean) { - this.command = command; - this.isAutoWhitespaceCommand = isAutoWhitespaceCommand; - } -} - export class EditOperationResult { _editOperationResultBrand: void; - readonly commands: CommandResult[]; + readonly commands: ICommand[]; readonly shouldPushStackElementBefore: boolean; readonly shouldPushStackElementAfter: boolean; readonly reason: CursorChangeReason; constructor( - commands: CommandResult[], + commands: ICommand[], opts: { shouldPushStackElementBefore: boolean; shouldPushStackElementAfter: boolean; diff --git a/src/vs/editor/common/controller/cursorDeleteOperations.ts b/src/vs/editor/common/controller/cursorDeleteOperations.ts index 6996f1af6e686ce29f88723d6625cb23dc84e0e3..68b006b107ec36afa8c00b77dc0cf2cefff725c6 100644 --- a/src/vs/editor/common/controller/cursorDeleteOperations.ts +++ b/src/vs/editor/common/controller/cursorDeleteOperations.ts @@ -5,15 +5,16 @@ 'use strict'; import { ReplaceCommand } from 'vs/editor/common/commands/replaceCommand'; -import { SingleCursorState, CursorColumns, CursorConfiguration, ICursorSimpleModel, EditOperationResult, CommandResult } from 'vs/editor/common/controller/cursorCommon'; +import { SingleCursorState, CursorColumns, CursorConfiguration, ICursorSimpleModel, EditOperationResult } from 'vs/editor/common/controller/cursorCommon'; import { Range } from 'vs/editor/common/core/range'; import { MoveOperations } from 'vs/editor/common/controller/cursorMoveOperations'; import * as strings from 'vs/base/common/strings'; +import { ICommand } from "vs/editor/common/editorCommon"; export class DeleteOperations { public static deleteRight(config: CursorConfiguration, model: ICursorSimpleModel, cursors: SingleCursorState[]): EditOperationResult { - let commands: CommandResult[] = []; + let commands: ICommand[] = []; let shouldPushStackElementBefore = false; for (let i = 0, len = cursors.length; i < len; i++) { const cursor = cursors[i]; @@ -41,7 +42,7 @@ export class DeleteOperations { shouldPushStackElementBefore = true; } - commands[i] = new CommandResult(new ReplaceCommand(deleteSelection, ''), false); + commands[i] = new ReplaceCommand(deleteSelection, ''); } return new EditOperationResult(commands, { shouldPushStackElementBefore: shouldPushStackElementBefore, @@ -82,7 +83,7 @@ export class DeleteOperations { } private static _runAutoClosingPairDelete(config: CursorConfiguration, model: ICursorSimpleModel, cursors: SingleCursorState[]): EditOperationResult { - let commands: CommandResult[] = []; + let commands: ICommand[] = []; for (let i = 0, len = cursors.length; i < len; i++) { const cursor = cursors[i]; const position = cursor.position; @@ -92,7 +93,7 @@ export class DeleteOperations { position.lineNumber, position.column + 1 ); - commands[i] = new CommandResult(new ReplaceCommand(deleteSelection, ''), false); + commands[i] = new ReplaceCommand(deleteSelection, ''); } return new EditOperationResult(commands, { shouldPushStackElementBefore: true, @@ -106,7 +107,7 @@ export class DeleteOperations { return this._runAutoClosingPairDelete(config, model, cursors); } - let commands: CommandResult[] = []; + let commands: ICommand[] = []; let shouldPushStackElementBefore = false; for (let i = 0, len = cursors.length; i < len; i++) { const cursor = cursors[i]; @@ -155,7 +156,7 @@ export class DeleteOperations { shouldPushStackElementBefore = true; } - commands[i] = new CommandResult(new ReplaceCommand(deleteSelection, ''), false); + commands[i] = new ReplaceCommand(deleteSelection, ''); } return new EditOperationResult(commands, { shouldPushStackElementBefore: shouldPushStackElementBefore, @@ -164,7 +165,7 @@ export class DeleteOperations { } public static cut(config: CursorConfiguration, model: ICursorSimpleModel, cursors: SingleCursorState[]): EditOperationResult { - let commands: CommandResult[] = []; + let commands: ICommand[] = []; for (let i = 0, len = cursors.length; i < len; i++) { const cursor = cursors[i]; let selection = cursor.selection; @@ -208,7 +209,7 @@ export class DeleteOperations { ); if (!deleteSelection.isEmpty()) { - commands[i] = new CommandResult(new ReplaceCommand(deleteSelection, ''), false); + commands[i] = new ReplaceCommand(deleteSelection, ''); } else { commands[i] = null; } @@ -217,7 +218,7 @@ export class DeleteOperations { commands[i] = null; } } else { - commands[i] = new CommandResult(new ReplaceCommand(selection, ''), false); + commands[i] = new ReplaceCommand(selection, ''); } } return new EditOperationResult(commands, { @@ -225,5 +226,4 @@ export class DeleteOperations { shouldPushStackElementAfter: true }); } - -} \ No newline at end of file +} diff --git a/src/vs/editor/common/controller/cursorTypeOperations.ts b/src/vs/editor/common/controller/cursorTypeOperations.ts index 2f88bb956b49c3b2276e9838240594a20d876674..b231d46d1e4b7086a7e49dbdd8124aed18e681a0 100644 --- a/src/vs/editor/common/controller/cursorTypeOperations.ts +++ b/src/vs/editor/common/controller/cursorTypeOperations.ts @@ -6,7 +6,7 @@ import { onUnexpectedError } from 'vs/base/common/errors'; import { ReplaceCommand, ReplaceCommandWithoutChangingPosition, ReplaceCommandWithOffsetCursorState } from 'vs/editor/common/commands/replaceCommand'; -import { SingleCursorState, CursorColumns, CursorConfiguration, ICursorSimpleModel, EditOperationResult, CommandResult } from 'vs/editor/common/controller/cursorCommon'; +import { SingleCursorState, CursorColumns, CursorConfiguration, ICursorSimpleModel, EditOperationResult } from 'vs/editor/common/controller/cursorCommon'; import { Range } from 'vs/editor/common/core/range'; import { ICommand, ITokenizedModel } from 'vs/editor/common/editorCommon'; import * as strings from 'vs/base/common/strings'; @@ -22,18 +22,15 @@ import { CursorChangeReason } from "vs/editor/common/controller/cursorEvents"; export class TypeOperations { public static indent(config: CursorConfiguration, model: ICursorSimpleModel, cursors: SingleCursorState[]): EditOperationResult { - let commands: CommandResult[] = []; + let commands: ICommand[] = []; for (let i = 0, len = cursors.length; i < len; i++) { const cursor = cursors[i]; - commands[i] = new CommandResult( - new ShiftCommand(cursor.selection, { - isUnshift: false, - tabSize: config.tabSize, - oneIndent: config.oneIndent, - useTabStops: config.useTabStops - }), - false - ); + commands[i] = new ShiftCommand(cursor.selection, { + isUnshift: false, + tabSize: config.tabSize, + oneIndent: config.oneIndent, + useTabStops: config.useTabStops + }); } return new EditOperationResult(commands, { shouldPushStackElementBefore: true, @@ -42,18 +39,15 @@ export class TypeOperations { } public static outdent(config: CursorConfiguration, model: ICursorSimpleModel, cursors: SingleCursorState[]): EditOperationResult { - let commands: CommandResult[] = []; + let commands: ICommand[] = []; for (let i = 0, len = cursors.length; i < len; i++) { const cursor = cursors[i]; - commands[i] = new CommandResult( - new ShiftCommand(cursor.selection, { - isUnshift: true, - tabSize: config.tabSize, - oneIndent: config.oneIndent, - useTabStops: config.useTabStops - }), - false - ); + commands[i] = new ShiftCommand(cursor.selection, { + isUnshift: true, + tabSize: config.tabSize, + oneIndent: config.oneIndent, + useTabStops: config.useTabStops + }); } return new EditOperationResult(commands, { shouldPushStackElementBefore: true, @@ -84,11 +78,11 @@ export class TypeOperations { } public static distributedPaste(config: CursorConfiguration, model: ICursorSimpleModel, cursors: SingleCursorState[], text: string[]): EditOperationResult { - let commands: CommandResult[] = []; + let commands: ICommand[] = []; for (let i = 0, len = cursors.length; i < len; i++) { const cursor = cursors[i]; let selection = cursor.selection; - commands[i] = new CommandResult(new ReplaceCommand(selection, text[i]), false); + commands[i] = new ReplaceCommand(selection, text[i]); } return new EditOperationResult(commands, { shouldPushStackElementBefore: true, @@ -98,7 +92,7 @@ export class TypeOperations { } public static paste(config: CursorConfiguration, model: ICursorSimpleModel, cursors: SingleCursorState[], text: string, pasteOnNewLine: boolean): EditOperationResult { - let commands: CommandResult[] = []; + let commands: ICommand[] = []; for (let i = 0, len = cursors.length; i < len; i++) { const cursor = cursors[i]; let position = cursor.position; @@ -117,9 +111,9 @@ export class TypeOperations { if (pasteOnNewLine) { // Paste entire line at the beginning of line let typeSelection = new Range(position.lineNumber, 1, position.lineNumber, 1); - commands[i] = new CommandResult(new ReplaceCommand(typeSelection, text), false); + commands[i] = new ReplaceCommand(typeSelection, text); } else { - commands[i] = new CommandResult(new ReplaceCommand(selection, text), false); + commands[i] = new ReplaceCommand(selection, text); } } return new EditOperationResult(commands, { @@ -160,7 +154,7 @@ export class TypeOperations { return null; } - private static _replaceJumpToNextIndent(config: CursorConfiguration, model: ICursorSimpleModel, selection: Selection): ReplaceCommand { + private static _replaceJumpToNextIndent(config: CursorConfiguration, model: ICursorSimpleModel, selection: Selection, insertsAutoWhitespace: boolean): ReplaceCommand { let typeText = ''; let position = selection.getStartPosition(); @@ -175,11 +169,11 @@ export class TypeOperations { typeText = '\t'; } - return new ReplaceCommand(selection, typeText); + return new ReplaceCommand(selection, typeText, insertsAutoWhitespace); } public static tab(config: CursorConfiguration, model: ITokenizedModel, cursors: SingleCursorState[]): EditOperationResult { - let commands: CommandResult[] = []; + let commands: ICommand[] = []; for (let i = 0, len = cursors.length; i < len; i++) { const cursor = cursors[i]; let selection = cursor.selection; @@ -193,32 +187,28 @@ export class TypeOperations { goodIndent = goodIndent || '\t'; let possibleTypeText = config.normalizeIndentation(goodIndent); if (!strings.startsWith(lineText, possibleTypeText)) { - let command = new ReplaceCommand(new Range(selection.startLineNumber, 1, selection.startLineNumber, lineText.length + 1), possibleTypeText); - commands[i] = new CommandResult(command, true); + commands[i] = new ReplaceCommand(new Range(selection.startLineNumber, 1, selection.startLineNumber, lineText.length + 1), possibleTypeText, true); continue; } } - commands[i] = new CommandResult(this._replaceJumpToNextIndent(config, model, selection), true); + commands[i] = this._replaceJumpToNextIndent(config, model, selection, true); } else { if (selection.startLineNumber === selection.endLineNumber) { let lineMaxColumn = model.getLineMaxColumn(selection.startLineNumber); if (selection.startColumn !== 1 || selection.endColumn !== lineMaxColumn) { // This is a single line selection that is not the entire line - commands[i] = new CommandResult(this._replaceJumpToNextIndent(config, model, selection), false); + commands[i] = this._replaceJumpToNextIndent(config, model, selection, false); continue; } } - commands[i] = new CommandResult( - new ShiftCommand(selection, { - isUnshift: false, - tabSize: config.tabSize, - oneIndent: config.oneIndent, - useTabStops: config.useTabStops - }), - false - ); + commands[i] = new ShiftCommand(selection, { + isUnshift: false, + tabSize: config.tabSize, + oneIndent: config.oneIndent, + useTabStops: config.useTabStops + }); } } return new EditOperationResult(commands, { @@ -228,7 +218,7 @@ export class TypeOperations { } public static replacePreviousChar(config: CursorConfiguration, model: ITokenizedModel, cursors: SingleCursorState[], txt: string, replaceCharCnt: number): EditOperationResult { - let commands: CommandResult[] = []; + let commands: ICommand[] = []; for (let i = 0, len = cursors.length; i < len; i++) { const cursor = cursors[i]; if (!cursor.selection.isEmpty()) { @@ -241,7 +231,7 @@ export class TypeOperations { let pos = cursor.position; let startColumn = Math.max(1, pos.column - replaceCharCnt); let range = new Range(pos.lineNumber, startColumn, pos.lineNumber, pos.column); - commands[i] = new CommandResult(new ReplaceCommand(range, txt), false); + commands[i] = new ReplaceCommand(range, txt); } return new EditOperationResult(commands, { shouldPushStackElementBefore: false, @@ -249,15 +239,15 @@ export class TypeOperations { }); } - public static typeCommand(range: Range, text: string, keepPosition: boolean): ICommand { + private static _typeCommand(range: Range, text: string, keepPosition: boolean): ICommand { if (keepPosition) { - return new ReplaceCommandWithoutChangingPosition(range, text); + return new ReplaceCommandWithoutChangingPosition(range, text, true); } else { - return new ReplaceCommand(range, text); + return new ReplaceCommand(range, text, true); } } - private static _enter(config: CursorConfiguration, model: ITokenizedModel, keepPosition: boolean, range: Range): CommandResult { + private static _enter(config: CursorConfiguration, model: ITokenizedModel, keepPosition: boolean, range: Range): ICommand { let r = LanguageConfigurationRegistry.getEnterAction(model, range); let enterAction = r.enterAction; let indentation = r.indentation; @@ -286,14 +276,13 @@ export class TypeOperations { indentation = indentation.substring(0, indentation.length - enterAction.removeText); } - let executeCommand: ICommand; if (enterAction.indentAction === IndentAction.None) { // Nothing special - executeCommand = TypeOperations.typeCommand(range, beforeText + '\n' + config.normalizeIndentation(indentation + enterAction.appendText), keepPosition); + return TypeOperations._typeCommand(range, beforeText + '\n' + config.normalizeIndentation(indentation + enterAction.appendText), keepPosition); } else if (enterAction.indentAction === IndentAction.Indent) { // Indent once - executeCommand = TypeOperations.typeCommand(range, beforeText + '\n' + config.normalizeIndentation(indentation + enterAction.appendText), keepPosition); + return TypeOperations._typeCommand(range, beforeText + '\n' + config.normalizeIndentation(indentation + enterAction.appendText), keepPosition); } else if (enterAction.indentAction === IndentAction.IndentOutdent) { // Ultra special @@ -303,16 +292,16 @@ export class TypeOperations { let typeText = beforeText + '\n' + increasedIndent + '\n' + normalIndent; if (keepPosition) { - executeCommand = new ReplaceCommandWithoutChangingPosition(range, typeText); + return new ReplaceCommandWithoutChangingPosition(range, typeText, true); } else { - executeCommand = new ReplaceCommandWithOffsetCursorState(range, typeText, -1, increasedIndent.length - normalIndent.length); + return new ReplaceCommandWithOffsetCursorState(range, typeText, -1, increasedIndent.length - normalIndent.length, true); } } else if (enterAction.indentAction === IndentAction.Outdent) { let actualIndentation = TypeOperations.unshiftIndent(config, indentation); - executeCommand = TypeOperations.typeCommand(range, beforeText + '\n' + config.normalizeIndentation(actualIndentation + enterAction.appendText), keepPosition); + return TypeOperations._typeCommand(range, beforeText + '\n' + config.normalizeIndentation(actualIndentation + enterAction.appendText), keepPosition); } - return new CommandResult(executeCommand, true); + return null; } private static _isAutoClosingCloseCharType(config: CursorConfiguration, model: ITokenizedModel, cursors: SingleCursorState[], ch: string): boolean { @@ -341,12 +330,12 @@ export class TypeOperations { } private static _runAutoClosingCloseCharType(config: CursorConfiguration, model: ITokenizedModel, cursors: SingleCursorState[], ch: string): EditOperationResult { - let commands: CommandResult[] = []; + let commands: ICommand[] = []; for (let i = 0, len = cursors.length; i < len; i++) { const cursor = cursors[i]; const position = cursor.position; const typeSelection = new Range(position.lineNumber, position.column, position.lineNumber, position.column + 1); - commands[i] = new CommandResult(new ReplaceCommand(typeSelection, ch), false); + commands[i] = new ReplaceCommand(typeSelection, ch); } return new EditOperationResult(commands, { shouldPushStackElementBefore: false, @@ -419,15 +408,12 @@ export class TypeOperations { } private static _runAutoClosingOpenCharType(config: CursorConfiguration, model: ITokenizedModel, cursors: SingleCursorState[], ch: string): EditOperationResult { - let commands: CommandResult[] = []; + let commands: ICommand[] = []; for (let i = 0, len = cursors.length; i < len; i++) { const cursor = cursors[i]; const selection = cursor.selection; const closeCharacter = config.autoClosingPairsOpen[ch]; - commands[i] = new CommandResult( - new ReplaceCommandWithOffsetCursorState(selection, ch + closeCharacter, 0, -closeCharacter.length), - false - ); + commands[i] = new ReplaceCommandWithOffsetCursorState(selection, ch + closeCharacter, 0, -closeCharacter.length); } return new EditOperationResult(commands, { shouldPushStackElementBefore: true, @@ -471,12 +457,12 @@ export class TypeOperations { } private static _runSurroundSelectionType(config: CursorConfiguration, model: ITokenizedModel, cursors: SingleCursorState[], ch: string): EditOperationResult { - let commands: CommandResult[] = []; + let commands: ICommand[] = []; for (let i = 0, len = cursors.length; i < len; i++) { const cursor = cursors[i]; const selection = cursor.selection; const closeCharacter = config.surroundingPairs[ch]; - commands[i] = new CommandResult(new SurroundSelectionCommand(selection, ch, closeCharacter), false); + commands[i] = new SurroundSelectionCommand(selection, ch, closeCharacter); } return new EditOperationResult(commands, { shouldPushStackElementBefore: true, @@ -505,7 +491,7 @@ export class TypeOperations { } if (electricAction.appendText) { - const command = new CommandResult(new ReplaceCommandWithOffsetCursorState(cursor.selection, ch + electricAction.appendText, 0, -electricAction.appendText.length), false); + const command = new ReplaceCommandWithOffsetCursorState(cursor.selection, ch + electricAction.appendText, 0, -electricAction.appendText.length); return new EditOperationResult([command], { shouldPushStackElementBefore: false, shouldPushStackElementAfter: true @@ -536,7 +522,7 @@ export class TypeOperations { let typeSelection = new Range(position.lineNumber, 1, position.lineNumber, position.column); - const command = new CommandResult(new ReplaceCommand(typeSelection, typeText), false); + const command = new ReplaceCommand(typeSelection, typeText); return new EditOperationResult([command], { shouldPushStackElementBefore: false, shouldPushStackElementAfter: true @@ -550,7 +536,7 @@ export class TypeOperations { public static typeWithInterceptors(config: CursorConfiguration, model: ITokenizedModel, cursors: SingleCursorState[], ch: string): EditOperationResult { if (ch === '\n') { - let commands: CommandResult[] = []; + let commands: ICommand[] = []; for (let i = 0, len = cursors.length; i < len; i++) { commands[i] = TypeOperations._enter(config, model, false, cursors[i].selection); } @@ -585,10 +571,10 @@ export class TypeOperations { } public static typeWithoutInterceptors(config: CursorConfiguration, model: ITokenizedModel, cursors: SingleCursorState[], str: string): EditOperationResult { - let commands: CommandResult[] = []; + let commands: ICommand[] = []; for (let i = 0, len = cursors.length; i < len; i++) { const cursor = cursors[i]; - commands[i] = new CommandResult(new ReplaceCommand(cursor.selection, str), false); + commands[i] = new ReplaceCommand(cursor.selection, str); } return new EditOperationResult(commands, { shouldPushStackElementBefore: false, @@ -597,13 +583,13 @@ export class TypeOperations { } public static lineInsertBefore(config: CursorConfiguration, model: ITokenizedModel, cursors: SingleCursorState[]): EditOperationResult { - let commands: CommandResult[] = []; + let commands: ICommand[] = []; for (let i = 0, len = cursors.length; i < len; i++) { const cursor = cursors[i]; let lineNumber = cursor.position.lineNumber; if (lineNumber === 1) { - commands[i] = new CommandResult(new ReplaceCommandWithoutChangingPosition(new Range(1, 1, 1, 1), '\n'), false); + commands[i] = new ReplaceCommandWithoutChangingPosition(new Range(1, 1, 1, 1), '\n'); } else { lineNumber--; let column = model.getLineMaxColumn(lineNumber); @@ -618,7 +604,7 @@ export class TypeOperations { } public static lineInsertAfter(config: CursorConfiguration, model: ITokenizedModel, cursors: SingleCursorState[]): EditOperationResult { - let commands: CommandResult[] = []; + let commands: ICommand[] = []; for (let i = 0, len = cursors.length; i < len; i++) { const cursor = cursors[i]; let position = cursor.position; @@ -632,7 +618,7 @@ export class TypeOperations { } public static lineBreakInsert(config: CursorConfiguration, model: ITokenizedModel, cursors: SingleCursorState[]): EditOperationResult { - let commands: CommandResult[] = []; + let commands: ICommand[] = []; for (let i = 0, len = cursors.length; i < len; i++) { const cursor = cursors[i]; commands[i] = this._enter(config, model, true, cursor.selection); diff --git a/src/vs/editor/common/editorCommon.ts b/src/vs/editor/common/editorCommon.ts index d0faa44be8e12321387fc47cec6f34e9c99eb704..b5c1bba3a0a3eca0949a00c69d802ab3b9269ff9 100644 --- a/src/vs/editor/common/editorCommon.ts +++ b/src/vs/editor/common/editorCommon.ts @@ -336,12 +336,20 @@ export interface ICursorStateComputerData { * A command that modifies text / cursor state on a model. */ export interface ICommand { + + /** + * Signal that this command is inserting automatic whitespace that should be trimmed if possible. + * @internal + */ + readonly insertsAutoWhitespace?: boolean; + /** * Get the edit operations needed to execute this command. * @param model The model the command will execute on. * @param builder A helper to collect the needed edit operations and to track selections. */ getEditOperations(model: ITokenizedModel, builder: IEditOperationBuilder): void; + /** * Compute the cursor state after the edit operations were applied. * @param model The model the commad has executed on.