未验证 提交 d8866608 编写于 作者: A Alex Dima

Split up Cursor.trigger(...)

上级 d41a0010
......@@ -985,7 +985,7 @@ export class CodeEditorWidget extends Disposable implements editorBrowser.ICodeE
if (source === 'keyboard') {
this._onWillType.fire(payload.text);
}
this._modelData.viewModel.cursor.trigger(source, handlerId, payload);
this._modelData.viewModel.cursor.type(payload.text, source);
if (source === 'keyboard') {
this._onDidType.fire(payload.text);
}
......@@ -999,7 +999,7 @@ export class CodeEditorWidget extends Disposable implements editorBrowser.ICodeE
return;
}
const startPosition = this._modelData.viewModel.getSelection().getStartPosition();
this._modelData.viewModel.cursor.trigger(source, handlerId, payload);
this._modelData.viewModel.cursor.paste(<string>payload.text, <boolean>payload.pasteOnNewLine, <string[]>payload.multicursorText, source);
const endPosition = this._modelData.viewModel.getSelection().getStartPosition();
if (source === 'keyboard') {
this._onDidPaste.fire(
......@@ -1026,7 +1026,20 @@ export class CodeEditorWidget extends Disposable implements editorBrowser.ICodeE
return;
}
this._modelData.viewModel.cursor.trigger(source, handlerId, payload);
switch (handlerId) {
case editorCommon.Handler.CompositionStart:
this._modelData.viewModel.cursor.startComposition();
break;
case editorCommon.Handler.CompositionEnd:
this._modelData.viewModel.cursor.endComposition(source);
break;
case editorCommon.Handler.ReplacePreviousChar:
this._modelData.viewModel.cursor.replacePreviousChar(<string>payload.text, <number>payload.replaceCharCnt, source);
break;
case editorCommon.Handler.Cut:
this._modelData.viewModel.cursor.cut(source);
break;
}
if (handlerId === editorCommon.Handler.CompositionStart) {
this._onDidCompositionStart.fire();
......@@ -1102,14 +1115,14 @@ export class CodeEditorWidget extends Disposable implements editorBrowser.ICodeE
if (!this._modelData) {
return;
}
this._modelData.viewModel.cursor.trigger(source, editorCommon.Handler.ExecuteCommand, command);
this._modelData.viewModel.cursor.executeCommand(command, source);
}
public executeCommands(source: string | null | undefined, commands: editorCommon.ICommand[]): void {
if (!this._modelData) {
return;
}
this._modelData.viewModel.cursor.trigger(source, editorCommon.Handler.ExecuteCommands, commands);
this._modelData.viewModel.cursor.executeCommands(commands, source);
}
public changeDecorations(callback: (changeAccessor: IModelDecorationsChangeAccessor) => any): any {
......
......@@ -662,137 +662,109 @@ export class Cursor extends viewEvents.ViewEventEmitter implements ICursors {
}
}
public trigger(source: string | null | undefined, handlerId: string, payload: any): void {
if (handlerId === editorCommon.Handler.CompositionStart) {
this._isDoingComposition = true;
this._selectionsWhenCompositionStarted = this.getSelections().slice(0);
return;
}
if (handlerId === editorCommon.Handler.CompositionEnd) {
this._isDoingComposition = false;
}
private _executeEdit(callback: () => void, source: string | null | undefined, cursorChangeReason: CursorChangeReason = CursorChangeReason.NotSet): void {
if (this._configuration.options.get(EditorOption.readOnly)) {
// All the remaining handlers will try to edit the model,
// but we cannot edit when read only...
// we cannot edit when read only...
this._onDidAttemptReadOnlyEdit.fire(undefined);
return;
}
const oldState = new CursorModelState(this._model, this);
let cursorChangeReason = CursorChangeReason.NotSet;
this._cursors.stopTrackingSelections();
// ensure valid state on all cursors
this._cursors.ensureValidState();
this._isHandling = true;
try {
switch (handlerId) {
case editorCommon.Handler.Type:
this._type(source, <string>payload.text);
break;
case editorCommon.Handler.ReplacePreviousChar:
this._replacePreviousChar(<string>payload.text, <number>payload.replaceCharCnt);
break;
case editorCommon.Handler.Paste:
cursorChangeReason = CursorChangeReason.Paste;
this._paste(<string>payload.text, <boolean>payload.pasteOnNewLine, <string[]>payload.multicursorText || []);
break;
case editorCommon.Handler.Cut:
this._cut();
break;
case editorCommon.Handler.ExecuteCommand:
this._externalExecuteCommand(<editorCommon.ICommand>payload);
break;
case editorCommon.Handler.ExecuteCommands:
this._externalExecuteCommands(<editorCommon.ICommand[]>payload);
break;
case editorCommon.Handler.CompositionEnd:
this._interpretCompositionEnd(source);
break;
}
this._cursors.ensureValidState();
callback();
} catch (err) {
onUnexpectedError(err);
}
this._isHandling = false;
this._cursors.startTrackingSelections();
this._validateAutoClosedActions();
if (this._emitStateChangedIfNecessary(source, cursorChangeReason, oldState)) {
this._revealRange(source, RevealTarget.Primary, viewEvents.VerticalRevealType.Simple, true, editorCommon.ScrollType.Smooth);
}
}
private _interpretCompositionEnd(source: string | null | undefined) {
if (!this._isDoingComposition && source === 'keyboard') {
// composition finishes, let's check if we need to auto complete if necessary.
const autoClosedCharacters = AutoClosedAction.getAllAutoClosedCharacters(this._autoClosedActions);
this._executeEditOperation(TypeOperations.compositionEndWithInterceptors(this._prevEditOperationType, this.context.config, this.context.model, this._selectionsWhenCompositionStarted, this.getSelections(), autoClosedCharacters));
this._selectionsWhenCompositionStarted = null;
}
public startComposition(): void {
this._isDoingComposition = true;
this._selectionsWhenCompositionStarted = this.getSelections().slice(0);
}
private _type(source: string | null | undefined, text: string): void {
if (source === 'keyboard') {
// If this event is coming straight from the keyboard, look for electric characters and enter
public endComposition(source?: string | null | undefined): void {
this._isDoingComposition = false;
this._executeEdit(() => {
if (!this._isDoingComposition && source === 'keyboard') {
// composition finishes, let's check if we need to auto complete if necessary.
const autoClosedCharacters = AutoClosedAction.getAllAutoClosedCharacters(this._autoClosedActions);
this._executeEditOperation(TypeOperations.compositionEndWithInterceptors(this._prevEditOperationType, this.context.config, this.context.model, this._selectionsWhenCompositionStarted, this.getSelections(), autoClosedCharacters));
this._selectionsWhenCompositionStarted = null;
}
}, source);
}
const len = text.length;
let offset = 0;
while (offset < len) {
const charLength = strings.nextCharLength(text, offset);
const chr = text.substr(offset, charLength);
public type(text: string, source?: string | null | undefined): void {
this._executeEdit(() => {
if (source === 'keyboard') {
// If this event is coming straight from the keyboard, look for electric characters and enter
// Here we must interpret each typed character individually
const autoClosedCharacters = AutoClosedAction.getAllAutoClosedCharacters(this._autoClosedActions);
this._executeEditOperation(TypeOperations.typeWithInterceptors(this._isDoingComposition, this._prevEditOperationType, this.context.config, this.context.model, this.getSelections(), autoClosedCharacters, chr));
const len = text.length;
let offset = 0;
while (offset < len) {
const charLength = strings.nextCharLength(text, offset);
const chr = text.substr(offset, charLength);
offset += charLength;
}
// Here we must interpret each typed character individually
const autoClosedCharacters = AutoClosedAction.getAllAutoClosedCharacters(this._autoClosedActions);
this._executeEditOperation(TypeOperations.typeWithInterceptors(this._isDoingComposition, this._prevEditOperationType, this.context.config, this.context.model, this.getSelections(), autoClosedCharacters, chr));
} else {
this._executeEditOperation(TypeOperations.typeWithoutInterceptors(this._prevEditOperationType, this.context.config, this.context.model, this.getSelections(), text));
}
offset += charLength;
}
} else {
this._executeEditOperation(TypeOperations.typeWithoutInterceptors(this._prevEditOperationType, this.context.config, this.context.model, this.getSelections(), text));
}
}, source);
}
private _replacePreviousChar(text: string, replaceCharCnt: number): void {
this._executeEditOperation(TypeOperations.replacePreviousChar(this._prevEditOperationType, this.context.config, this.context.model, this.getSelections(), text, replaceCharCnt));
public replacePreviousChar(text: string, replaceCharCnt: number, source?: string | null | undefined): void {
this._executeEdit(() => {
this._executeEditOperation(TypeOperations.replacePreviousChar(this._prevEditOperationType, this.context.config, this.context.model, this.getSelections(), text, replaceCharCnt));
}, source);
}
private _paste(text: string, pasteOnNewLine: boolean, multicursorText: string[]): void {
this._executeEditOperation(TypeOperations.paste(this.context.config, this.context.model, this.getSelections(), text, pasteOnNewLine, multicursorText));
public paste(text: string, pasteOnNewLine: boolean, multicursorText?: string[] | null | undefined, source?: string | null | undefined): void {
this._executeEdit(() => {
this._executeEditOperation(TypeOperations.paste(this.context.config, this.context.model, this.getSelections(), text, pasteOnNewLine, multicursorText || []));
}, source, CursorChangeReason.Paste);
}
private _cut(): void {
this._executeEditOperation(DeleteOperations.cut(this.context.config, this.context.model, this.getSelections()));
public cut(source?: string | null | undefined): void {
this._executeEdit(() => {
this._executeEditOperation(DeleteOperations.cut(this.context.config, this.context.model, this.getSelections()));
}, source);
}
private _externalExecuteCommand(command: editorCommon.ICommand): void {
this._cursors.killSecondaryCursors();
public executeCommand(command: editorCommon.ICommand, source?: string | null | undefined): void {
this._executeEdit(() => {
this._cursors.killSecondaryCursors();
this._executeEditOperation(new EditOperationResult(EditOperationType.Other, [command], {
shouldPushStackElementBefore: false,
shouldPushStackElementAfter: false
}));
this._executeEditOperation(new EditOperationResult(EditOperationType.Other, [command], {
shouldPushStackElementBefore: false,
shouldPushStackElementAfter: false
}));
}, source);
}
private _externalExecuteCommands(commands: editorCommon.ICommand[]): void {
this._executeEditOperation(new EditOperationResult(EditOperationType.Other, commands, {
shouldPushStackElementBefore: false,
shouldPushStackElementAfter: false
}));
public executeCommands(commands: editorCommon.ICommand[], source?: string | null | undefined): void {
this._executeEdit(() => {
this._executeEditOperation(new EditOperationResult(EditOperationType.Other, commands, {
shouldPushStackElementBefore: false,
shouldPushStackElementAfter: false
}));
}, source);
}
}
......
......@@ -689,7 +689,6 @@ export const EditorType = {
* @internal
*/
export const enum Handler {
ExecuteCommand = 'executeCommand',
ExecuteCommands = 'executeCommands',
Type = 'type',
ReplacePreviousChar = 'replacePreviousChar',
......
......@@ -11,7 +11,6 @@ import { Selection } from 'vs/editor/common/core/selection';
import { deserializePipePositions, serializePipePositions, testRepeatedActionAndExtractPositions } from 'vs/editor/contrib/wordOperations/test/wordTestUtils';
import { CursorWordEndLeft, CursorWordEndLeftSelect, CursorWordEndRight, CursorWordEndRightSelect, CursorWordLeft, CursorWordLeftSelect, CursorWordRight, CursorWordRightSelect, CursorWordStartLeft, CursorWordStartLeftSelect, CursorWordStartRight, CursorWordStartRightSelect, DeleteWordEndLeft, DeleteWordEndRight, DeleteWordLeft, DeleteWordRight, DeleteWordStartLeft, DeleteWordStartRight, CursorWordAccessibilityLeft, CursorWordAccessibilityLeftSelect, CursorWordAccessibilityRight, CursorWordAccessibilityRightSelect } from 'vs/editor/contrib/wordOperations/wordOperations';
import { withTestCodeEditor } from 'vs/editor/test/browser/testCodeEditor';
import { Handler } from 'vs/editor/common/editorCommon';
import { Cursor } from 'vs/editor/common/controller/cursor';
import { CoreEditingCommands } from 'vs/editor/browser/controller/coreCommands';
......@@ -197,13 +196,9 @@ suite('WordOperations', () => {
});
test('issue #51275 - cursorWordStartLeft does not push undo/redo stack element', () => {
function cursorCommand(cursor: Cursor, command: string, extraData?: any, overwriteSource?: string) {
cursor.trigger(overwriteSource || 'tests', command, extraData);
}
function type(cursor: Cursor, text: string) {
for (let i = 0; i < text.length; i++) {
cursorCommand(cursor, Handler.Type, { text: text.charAt(i) }, 'keyboard');
cursor.type(text.charAt(i), 'keyboard');
}
}
......
......@@ -6,7 +6,7 @@
import * as assert from 'assert';
import { IRange } from 'vs/editor/common/core/range';
import { Selection, ISelection } from 'vs/editor/common/core/selection';
import { ICommand, Handler, IEditOperationBuilder } from 'vs/editor/common/editorCommon';
import { ICommand, IEditOperationBuilder } from 'vs/editor/common/editorCommon';
import { IIdentifiedSingleEditOperation, ITextModel } from 'vs/editor/common/model';
import { createTextModel } from 'vs/editor/test/common/editorTestUtils';
import { LanguageIdentifier } from 'vs/editor/common/modes';
......@@ -33,7 +33,7 @@ export function testCommand(
cursor.setSelections('tests', [selection]);
cursor.trigger('tests', Handler.ExecuteCommand, commandFactory(cursor.getSelection()));
cursor.executeCommand(commandFactory(cursor.getSelection()), 'tests');
assert.deepEqual(model.getLinesContent(), expectedLines);
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册