Skip to content

Commit b4631d3

Browse files
committed
Emit ReadOnlyEditAttemptEvent through view model
1 parent 81e71a4 commit b4631d3

4 files changed

Lines changed: 47 additions & 23 deletions

File tree

src/vs/editor/browser/widget/codeEditorWidget.ts

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1473,10 +1473,6 @@ export class CodeEditorWidget extends Disposable implements editorBrowser.ICodeE
14731473
// Someone might destroy the model from under the editor, so prevent any exceptions by setting a null model
14741474
listenersToRemove.push(model.onWillDispose(() => this.setModel(null)));
14751475

1476-
listenersToRemove.push(viewModel.cursor.onDidAttemptReadOnlyEdit(() => {
1477-
this._onDidAttemptReadOnlyEdit.fire(undefined);
1478-
}));
1479-
14801476
listenersToRemove.push(viewModel.onEvent((e) => {
14811477
switch (e.kind) {
14821478
case OutgoingViewModelEventKind.ContentSizeChanged:
@@ -1491,6 +1487,9 @@ export class CodeEditorWidget extends Disposable implements editorBrowser.ICodeE
14911487
case OutgoingViewModelEventKind.ViewZonesChanged:
14921488
this._onDidChangeViewZones.fire();
14931489
break;
1490+
case OutgoingViewModelEventKind.ReadOnlyEditAttempt:
1491+
this._onDidAttemptReadOnlyEdit.fire();
1492+
break;
14941493
case OutgoingViewModelEventKind.CursorStateChanged: {
14951494
if (e.reachedMaxCursorCount) {
14961495
this._notificationService.warn(nls.localize('cursors.maximum', "The number of cursors has been limited to {0}.", Cursor.MAX_CURSOR_COUNT));

src/vs/editor/common/controller/cursor.ts

Lines changed: 5 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,6 @@
44
*--------------------------------------------------------------------------------------------*/
55

66
import { onUnexpectedError } from 'vs/base/common/errors';
7-
import { Emitter, Event } from 'vs/base/common/event';
87
import * as strings from 'vs/base/common/strings';
98
import { CursorCollection } from 'vs/editor/common/controller/cursorCollection';
109
import { CursorColumns, CursorConfiguration, CursorContext, CursorState, EditOperationResult, EditOperationType, IColumnSelectData, PartialCursorState, ICursorSimpleModel } from 'vs/editor/common/controller/cursorCommon';
@@ -124,9 +123,6 @@ export class Cursor extends Disposable {
124123

125124
public static readonly MAX_CURSOR_COUNT = 10000;
126125

127-
private readonly _onDidAttemptReadOnlyEdit: Emitter<void> = this._register(new Emitter<void>());
128-
public readonly onDidAttemptReadOnlyEdit: Event<void> = this._onDidAttemptReadOnlyEdit.event;
129-
130126
private readonly _model: ITextModel;
131127
private _knownModelVersionId: number;
132128
private readonly _viewModel: ICursorSimpleModel;
@@ -598,7 +594,6 @@ export class Cursor extends Disposable {
598594
private _executeEdit(callback: () => void, eventsCollector: ViewModelEventsCollector, source: string | null | undefined, cursorChangeReason: CursorChangeReason = CursorChangeReason.NotSet): void {
599595
if (this.context.cursorConfig.readOnly) {
600596
// we cannot edit when read only...
601-
this._onDidAttemptReadOnlyEdit.fire(undefined);
602597
return;
603598
}
604599

@@ -621,15 +616,17 @@ export class Cursor extends Disposable {
621616
}
622617
}
623618

619+
public setIsDoingComposition(isDoingComposition: boolean): void {
620+
this._isDoingComposition = isDoingComposition;
621+
}
622+
624623
public startComposition(eventsCollector: ViewModelEventsCollector): void {
625-
this._isDoingComposition = true;
626624
this._selectionsWhenCompositionStarted = this.getSelections().slice(0);
627625
}
628626

629627
public endComposition(eventsCollector: ViewModelEventsCollector, source?: string | null | undefined): void {
630-
this._isDoingComposition = false;
631628
this._executeEdit(() => {
632-
if (!this._isDoingComposition && source === 'keyboard') {
629+
if (source === 'keyboard') {
633630
// composition finishes, let's check if we need to auto complete if necessary.
634631
const autoClosedCharacters = AutoClosedAction.getAllAutoClosedCharacters(this._autoClosedActions);
635632
this._executeEditOperation(TypeOperations.compositionEndWithInterceptors(this._prevEditOperationType, this.context.cursorConfig, this._model, this._selectionsWhenCompositionStarted, this.getSelections(), autoClosedCharacters));

src/vs/editor/common/viewModel/viewModelEventDispatcher.ts

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -176,6 +176,7 @@ export const enum OutgoingViewModelEventKind {
176176
FocusChanged,
177177
ScrollChanged,
178178
ViewZonesChanged,
179+
ReadOnlyEditAttempt,
179180
CursorStateChanged,
180181
}
181182

@@ -366,10 +367,27 @@ export class CursorStateChangedEvent {
366367
}
367368
}
368369

370+
export class ReadOnlyEditAttemptEvent {
371+
372+
public readonly kind = OutgoingViewModelEventKind.ReadOnlyEditAttempt;
373+
374+
constructor() {
375+
}
376+
377+
public isNoOp(): boolean {
378+
return false;
379+
}
380+
381+
public merge(other: OutgoingViewModelEvent): ReadOnlyEditAttemptEvent {
382+
return this;
383+
}
384+
}
385+
369386
export type OutgoingViewModelEvent = (
370387
ContentSizeChangedEvent
371388
| FocusChangedEvent
372389
| ScrollChangedEvent
373390
| ViewZonesChangedEvent
391+
| ReadOnlyEditAttemptEvent
374392
| CursorStateChangedEvent
375393
);

src/vs/editor/common/viewModel/viewModelImpl.ts

Lines changed: 21 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ import { Cursor } from 'vs/editor/common/controller/cursor';
3030
import { PartialCursorState, CursorState, IColumnSelectData, EditOperationType, CursorConfiguration } from 'vs/editor/common/controller/cursorCommon';
3131
import { CursorChangeReason } from 'vs/editor/common/controller/cursorEvents';
3232
import { IWhitespaceChangeAccessor } from 'vs/editor/common/viewLayout/linesLayout';
33-
import { ViewModelEventDispatcher, OutgoingViewModelEvent, FocusChangedEvent, ScrollChangedEvent, ViewZonesChangedEvent, ViewModelEventsCollector } from 'vs/editor/common/viewModel/viewModelEventDispatcher';
33+
import { ViewModelEventDispatcher, OutgoingViewModelEvent, FocusChangedEvent, ScrollChangedEvent, ViewZonesChangedEvent, ViewModelEventsCollector, ReadOnlyEditAttemptEvent } from 'vs/editor/common/viewModel/viewModelEventDispatcher';
3434
import { ViewEventHandler } from 'vs/editor/common/viewModel/viewEventHandler';
3535

3636
const USE_IDENTITY_LINES_COLLECTION = true;
@@ -52,7 +52,7 @@ export class ViewModel extends Disposable implements IViewModel {
5252
private readonly lines: IViewModelLinesCollection;
5353
public readonly coordinatesConverter: ICoordinatesConverter;
5454
public readonly viewLayout: ViewLayout;
55-
public readonly cursor: Cursor;
55+
private readonly cursor: Cursor;
5656
private readonly decorations: ViewModelDecorations;
5757

5858
constructor(
@@ -914,32 +914,42 @@ export class ViewModel extends Disposable implements IViewModel {
914914
this._withViewEventsCollector(eventsCollector => this.cursor.restoreState(eventsCollector, states));
915915
}
916916

917+
private _executeCursorEdit(callback: (eventsCollector: ViewModelEventsCollector) => void): void {
918+
if (this.cursor.context.cursorConfig.readOnly) {
919+
// we cannot edit when read only...
920+
this._eventDispatcher.emitOutgoingEvent(new ReadOnlyEditAttemptEvent());
921+
return;
922+
}
923+
this._withViewEventsCollector(callback);
924+
}
917925
public executeEdits(source: string | null | undefined, edits: IIdentifiedSingleEditOperation[], cursorStateComputer: ICursorStateComputer): void {
918-
this._withViewEventsCollector(eventsCollector => this.cursor.executeEdits(eventsCollector, source, edits, cursorStateComputer));
926+
this._executeCursorEdit(eventsCollector => this.cursor.executeEdits(eventsCollector, source, edits, cursorStateComputer));
919927
}
920928
public startComposition(): void {
921-
this._withViewEventsCollector(eventsCollector => this.cursor.startComposition(eventsCollector));
929+
this.cursor.setIsDoingComposition(true);
930+
this._executeCursorEdit(eventsCollector => this.cursor.startComposition(eventsCollector));
922931
}
923932
public endComposition(source?: string | null | undefined): void {
924-
this._withViewEventsCollector(eventsCollector => this.cursor.endComposition(eventsCollector, source));
933+
this.cursor.setIsDoingComposition(false);
934+
this._executeCursorEdit(eventsCollector => this.cursor.endComposition(eventsCollector, source));
925935
}
926936
public type(text: string, source?: string | null | undefined): void {
927-
this._withViewEventsCollector(eventsCollector => this.cursor.type(eventsCollector, text, source));
937+
this._executeCursorEdit(eventsCollector => this.cursor.type(eventsCollector, text, source));
928938
}
929939
public replacePreviousChar(text: string, replaceCharCnt: number, source?: string | null | undefined): void {
930-
this._withViewEventsCollector(eventsCollector => this.cursor.replacePreviousChar(eventsCollector, text, replaceCharCnt, source));
940+
this._executeCursorEdit(eventsCollector => this.cursor.replacePreviousChar(eventsCollector, text, replaceCharCnt, source));
931941
}
932942
public paste(text: string, pasteOnNewLine: boolean, multicursorText?: string[] | null | undefined, source?: string | null | undefined): void {
933-
this._withViewEventsCollector(eventsCollector => this.cursor.paste(eventsCollector, text, pasteOnNewLine, multicursorText, source));
943+
this._executeCursorEdit(eventsCollector => this.cursor.paste(eventsCollector, text, pasteOnNewLine, multicursorText, source));
934944
}
935945
public cut(source?: string | null | undefined): void {
936-
this._withViewEventsCollector(eventsCollector => this.cursor.cut(eventsCollector, source));
946+
this._executeCursorEdit(eventsCollector => this.cursor.cut(eventsCollector, source));
937947
}
938948
public executeCommand(command: ICommand, source?: string | null | undefined): void {
939-
this._withViewEventsCollector(eventsCollector => this.cursor.executeCommand(eventsCollector, command, source));
949+
this._executeCursorEdit(eventsCollector => this.cursor.executeCommand(eventsCollector, command, source));
940950
}
941951
public executeCommands(commands: ICommand[], source?: string | null | undefined): void {
942-
this._withViewEventsCollector(eventsCollector => this.cursor.executeCommands(eventsCollector, commands, source));
952+
this._executeCursorEdit(eventsCollector => this.cursor.executeCommands(eventsCollector, commands, source));
943953
}
944954
public revealPrimaryCursor(source: string | null | undefined, revealHorizontal: boolean): void {
945955
this._withViewEventsCollector(eventsCollector => this.cursor.revealPrimary(eventsCollector, source, revealHorizontal, ScrollType.Smooth));

0 commit comments

Comments
 (0)