6
6
import { CompareResult , equals } from 'vs/base/common/arrays' ;
7
7
import { BugIndicatingError } from 'vs/base/common/errors' ;
8
8
import { autorunHandleChanges , derived , IObservable , IReader , ISettableObservable , ITransaction , keepAlive , observableValue , transaction , waitForState } from 'vs/base/common/observable' ;
9
+ import { URI } from 'vs/base/common/uri' ;
9
10
import { Range } from 'vs/editor/common/core/range' ;
10
11
import { ILanguageService } from 'vs/editor/common/languages/language' ;
11
12
import { ITextModel } from 'vs/editor/common/model' ;
12
13
import { IModelService } from 'vs/editor/common/services/model' ;
14
+ import { localize } from 'vs/nls' ;
15
+ import { IResourceUndoRedoElement , IUndoRedoService , UndoRedoElementType , UndoRedoGroup } from 'vs/platform/undoRedo/common/undoRedo' ;
13
16
import { EditorModel } from 'vs/workbench/common/editor/editorModel' ;
14
17
import { IMergeDiffComputer } from 'vs/workbench/contrib/mergeEditor/browser/model/diffComputer' ;
15
18
import { LineRange } from 'vs/workbench/contrib/mergeEditor/browser/model/lineRange' ;
@@ -58,6 +61,7 @@ export class MergeEditorModel extends EditorModel {
58
61
public readonly telemetry : MergeEditorTelemetry ,
59
62
@IModelService private readonly modelService : IModelService ,
60
63
@ILanguageService private readonly languageService : ILanguageService ,
64
+ @IUndoRedoService private readonly undoRedoService : IUndoRedoService ,
61
65
) {
62
66
super ( ) ;
63
67
@@ -405,9 +409,9 @@ export class MergeEditorModel extends EditorModel {
405
409
public setState (
406
410
baseRange : ModifiedBaseRange ,
407
411
state : ModifiedBaseRangeState ,
408
- markInputAsHandled : boolean | InputNumber ,
409
- transaction : ITransaction ,
410
- pushStackElement : boolean = false
412
+ _markInputAsHandled : boolean | InputNumber ,
413
+ tx : ITransaction ,
414
+ _pushStackElement : boolean = false
411
415
) : void {
412
416
if ( ! this . isUpToDate . get ( ) ) {
413
417
throw new BugIndicatingError ( 'Cannot set state while updating' ) ;
@@ -421,29 +425,36 @@ export class MergeEditorModel extends EditorModel {
421
425
const conflictingDiffs = this . resultTextModelDiffs . findTouchingDiffs (
422
426
baseRange . baseRange
423
427
) ;
428
+ const group = new UndoRedoGroup ( ) ;
424
429
if ( conflictingDiffs ) {
425
- this . resultTextModelDiffs . removeDiffs ( conflictingDiffs , transaction ) ;
430
+ this . resultTextModelDiffs . removeDiffs ( conflictingDiffs , tx , group ) ;
426
431
}
427
432
428
433
const { edit, effectiveState } = baseRange . getEditForBase ( state ) ;
429
434
430
- existingState . accepted . set ( effectiveState , transaction ) ;
435
+ existingState . accepted . set ( effectiveState , tx ) ;
431
436
existingState . previousNonDiffingState = undefined ;
432
437
existingState . computedFromDiffing = false ;
433
438
439
+ const input1Handled = existingState . handledInput1 . get ( ) ;
440
+ const input2Handled = existingState . handledInput2 . get ( ) ;
441
+
442
+ if ( ! input1Handled || ! input2Handled ) {
443
+ this . undoRedoService . pushElement (
444
+ new MarkAsHandledUndoRedoElement ( this . resultTextModel . uri , new WeakRef ( this ) , new WeakRef ( existingState ) , input1Handled , input2Handled ) ,
445
+ group
446
+ ) ;
447
+ }
448
+
434
449
if ( edit ) {
435
- if ( pushStackElement ) {
436
- this . resultTextModel . pushStackElement ( ) ;
437
- }
438
- this . resultTextModelDiffs . applyEditRelativeToOriginal ( edit , transaction ) ;
439
- if ( pushStackElement ) {
440
- this . resultTextModel . pushStackElement ( ) ;
441
- }
450
+ this . resultTextModel . pushStackElement ( ) ;
451
+ this . resultTextModelDiffs . applyEditRelativeToOriginal ( edit , tx , group ) ;
452
+ this . resultTextModel . pushStackElement ( ) ;
442
453
}
443
454
444
455
// always set conflict as handled
445
- existingState . handledInput1 . set ( true , transaction ) ;
446
- existingState . handledInput2 . set ( true , transaction ) ;
456
+ existingState . handledInput1 . set ( true , tx ) ;
457
+ existingState . handledInput2 . set ( true , tx ) ;
447
458
}
448
459
449
460
public resetDirtyConflictsToBase ( ) : void {
@@ -474,6 +485,42 @@ export class MergeEditorModel extends EditorModel {
474
485
return ;
475
486
}
476
487
488
+ const dataRef = new WeakRef ( ModifiedBaseRangeData ) ;
489
+ const modelRef = new WeakRef ( this ) ;
490
+
491
+ this . undoRedoService . pushElement ( {
492
+ type : UndoRedoElementType . Resource ,
493
+ resource : this . resultTextModel . uri ,
494
+ code : 'setInputHandled' ,
495
+ label : localize ( 'setInputHandled' , "Set Input Handled" ) ,
496
+ redo ( ) {
497
+ const model = modelRef . deref ( ) ;
498
+ const data = dataRef . deref ( ) ;
499
+ if ( model && ! model . isDisposed ( ) && data ) {
500
+ transaction ( tx => {
501
+ if ( inputNumber === 1 ) {
502
+ state . handledInput1 . set ( handled , tx ) ;
503
+ } else {
504
+ state . handledInput2 . set ( handled , tx ) ;
505
+ }
506
+ } ) ;
507
+ }
508
+ } ,
509
+ undo ( ) {
510
+ const model = modelRef . deref ( ) ;
511
+ const data = dataRef . deref ( ) ;
512
+ if ( model && ! model . isDisposed ( ) && data ) {
513
+ transaction ( tx => {
514
+ if ( inputNumber === 1 ) {
515
+ state . handledInput1 . set ( ! handled , tx ) ;
516
+ } else {
517
+ state . handledInput2 . set ( ! handled , tx ) ;
518
+ }
519
+ } ) ;
520
+ }
521
+ } ,
522
+ } ) ;
523
+
477
524
if ( inputNumber === 1 ) {
478
525
state . handledInput1 . set ( handled , tx ) ;
479
526
} else {
@@ -723,3 +770,43 @@ export const enum MergeEditorModelState {
723
770
upToDate = 2 ,
724
771
updating = 3 ,
725
772
}
773
+
774
+ class MarkAsHandledUndoRedoElement implements IResourceUndoRedoElement {
775
+ public readonly code = 'undoMarkAsHandled' ;
776
+ public readonly label = localize ( 'undoMarkAsHandled' , 'Undo Mark As Handled' ) ;
777
+
778
+ public readonly type = UndoRedoElementType . Resource ;
779
+
780
+ constructor (
781
+ public readonly resource : URI ,
782
+ private readonly mergeEditorModelRef : WeakRef < MergeEditorModel > ,
783
+ private readonly stateRef : WeakRef < ModifiedBaseRangeData > ,
784
+ private readonly input1Handled : boolean ,
785
+ private readonly input2Handled : boolean ,
786
+ ) { }
787
+
788
+ public redo ( ) {
789
+ const mergeEditorModel = this . mergeEditorModelRef . deref ( ) ;
790
+ if ( ! mergeEditorModel || mergeEditorModel . isDisposed ( ) ) {
791
+ return ;
792
+ }
793
+ const state = this . stateRef . deref ( ) ;
794
+ if ( ! state ) { return ; }
795
+ transaction ( tx => {
796
+ state . handledInput1 . set ( true , tx ) ;
797
+ state . handledInput2 . set ( true , tx ) ;
798
+ } ) ;
799
+ }
800
+ public undo ( ) {
801
+ const mergeEditorModel = this . mergeEditorModelRef . deref ( ) ;
802
+ if ( ! mergeEditorModel || mergeEditorModel . isDisposed ( ) ) {
803
+ return ;
804
+ }
805
+ const state = this . stateRef . deref ( ) ;
806
+ if ( ! state ) { return ; }
807
+ transaction ( tx => {
808
+ state . handledInput1 . set ( this . input1Handled , tx ) ;
809
+ state . handledInput2 . set ( this . input2Handled , tx ) ;
810
+ } ) ;
811
+ }
812
+ }
0 commit comments