@@ -19,9 +19,8 @@ import { AbstractTextResourceEditorInput } from 'vs/workbench/common/editor/text
19
19
import { EditorWorkerServiceDiffComputer } from 'vs/workbench/contrib/mergeEditor/browser/model/diffComputer' ;
20
20
import { MergeEditorModel } from 'vs/workbench/contrib/mergeEditor/browser/model/mergeEditorModel' ;
21
21
import { IEditorService } from 'vs/workbench/services/editor/common/editorService' ;
22
- import { AutoSaveMode , IFilesConfigurationService } from 'vs/workbench/services/filesConfiguration/common/filesConfigurationService' ;
23
22
import { ILanguageSupport , ITextFileEditorModel , ITextFileService } from 'vs/workbench/services/textfile/common/textfiles' ;
24
- import { assertType } from 'vs/base/common/types ' ;
23
+ import { autorun } from 'vs/base/common/observable ' ;
25
24
26
25
export class MergeEditorInputData {
27
26
constructor (
@@ -32,13 +31,14 @@ export class MergeEditorInputData {
32
31
) { }
33
32
}
34
33
35
- export class MergeEditorInput extends AbstractTextResourceEditorInput implements ILanguageSupport , IEditorCloseHandler {
34
+ export class MergeEditorInput extends AbstractTextResourceEditorInput implements ILanguageSupport {
36
35
37
36
static readonly ID = 'mergeEditor.Input' ;
38
37
39
38
private _model ?: MergeEditorModel ;
40
39
private _outTextModel ?: ITextFileEditorModel ;
41
- private _ignoreUnhandledConflictsForDirtyState ?: true ;
40
+
41
+ override closeHandler : MergeEditorCloseHandler | undefined ;
42
42
43
43
constructor (
44
44
public readonly base : URI ,
@@ -47,8 +47,6 @@ export class MergeEditorInput extends AbstractTextResourceEditorInput implements
47
47
public readonly result : URI ,
48
48
@IInstantiationService private readonly _instaService : IInstantiationService ,
49
49
@ITextModelService private readonly _textModelService : ITextModelService ,
50
- @IDialogService private readonly _dialogService : IDialogService ,
51
- @IFilesConfigurationService private readonly _filesConfigurationService : IFilesConfigurationService ,
52
50
@IEditorService editorService : IEditorService ,
53
51
@ITextFileService textFileService : ITextFileService ,
54
52
@ILabelService labelService : ILabelService ,
@@ -117,6 +115,13 @@ export class MergeEditorInput extends AbstractTextResourceEditorInput implements
117
115
} ,
118
116
) ;
119
117
118
+ // set/unset the closeHandler whenever unhandled conflicts are detected
119
+ const closeHandler = this . _instaService . createInstance ( MergeEditorCloseHandler , this . _model ) ;
120
+ this . _store . add ( autorun ( 'closeHandler' , reader => {
121
+ const value = this . _model ! . hasUnhandledConflicts . read ( reader ) ;
122
+ this . closeHandler = value ? closeHandler : undefined ;
123
+ } ) ) ;
124
+
120
125
await this . _model . onInitialized ;
121
126
122
127
this . _store . add ( this . _model ) ;
@@ -126,7 +131,6 @@ export class MergeEditorInput extends AbstractTextResourceEditorInput implements
126
131
this . _store . add ( result ) ;
127
132
}
128
133
129
- this . _ignoreUnhandledConflictsForDirtyState = undefined ;
130
134
return this . _model ;
131
135
}
132
136
@@ -146,67 +150,54 @@ export class MergeEditorInput extends AbstractTextResourceEditorInput implements
146
150
return Boolean ( this . _outTextModel ?. isDirty ( ) ) ;
147
151
}
148
152
149
- override readonly closeHandler = this ;
153
+ setLanguageId ( languageId : string , _setExplicitly ?: boolean ) : void {
154
+ this . _model ?. setLanguageId ( languageId ) ;
155
+ }
156
+
157
+ // implement get/set languageId
158
+ // implement get/set encoding
159
+ }
160
+
161
+ class MergeEditorCloseHandler implements IEditorCloseHandler {
162
+
163
+ private _ignoreUnhandledConflicts : boolean = false ;
164
+
165
+ constructor (
166
+ private readonly _model : MergeEditorModel ,
167
+ @IDialogService private readonly _dialogService : IDialogService ,
168
+ ) { }
150
169
151
170
showConfirm ( ) : boolean {
152
- if ( this . isDirty ( ) ) {
153
- // text model dirty -> 3wm is dirty
154
- return true ;
155
- }
156
- if ( ! this . _ignoreUnhandledConflictsForDirtyState ) {
157
- // unhandled conflicts -> 3wm asks to confirm UNLESS we explicitly set this input
158
- // to ignore unhandled conflicts. This happens only after confirming to ignore unhandled changes
159
- return Boolean ( this . _model && this . _model . hasUnhandledConflicts . get ( ) ) ;
160
- }
161
- return false ;
171
+ // unhandled conflicts -> 3wm asks to confirm UNLESS we explicitly set this input
172
+ // to ignore unhandled conflicts. This happens only after confirming to ignore unhandled changes
173
+ return ! this . _ignoreUnhandledConflicts && this . _model . hasUnhandledConflicts . get ( ) ;
162
174
}
163
175
164
- async confirm ( editors ?: ReadonlyArray < IEditorIdentifier > ) : Promise < ConfirmResult > {
176
+ async confirm ( editors ?: readonly IEditorIdentifier [ ] | undefined ) : Promise < ConfirmResult > {
165
177
166
- const inputs : MergeEditorInput [ ] = [ this ] ;
167
- if ( editors ) {
168
- for ( const { editor } of editors ) {
169
- if ( editor instanceof MergeEditorInput ) {
170
- inputs . push ( editor ) ;
171
- }
172
- }
173
- }
178
+ const handler : MergeEditorCloseHandler [ ] = [ this ] ;
179
+ editors ?. forEach ( candidate => candidate . editor . closeHandler instanceof MergeEditorCloseHandler && handler . push ( candidate . editor . closeHandler ) ) ;
174
180
175
- const inputsWithUnhandledConflicts = inputs
181
+ const inputsWithUnhandledConflicts = handler
176
182
. filter ( input => input . _model && input . _model . hasUnhandledConflicts . get ( ) ) ;
177
183
178
184
if ( inputsWithUnhandledConflicts . length === 0 ) {
185
+ // shouldn't happen
179
186
return ConfirmResult . SAVE ;
180
187
}
181
188
182
- const actions : string [ ] = [ ] ;
189
+ const actions : string [ ] = [
190
+ localize ( 'unhandledConflicts.ignore' , "Continue with Conflicts" ) ,
191
+ localize ( 'unhandledConflicts.discard' , "Discard Merge Changes" ) ,
192
+ localize ( 'unhandledConflicts.cancel' , "Cancel" ) ,
193
+ ] ;
183
194
const options = {
184
- cancelId : 0 ,
185
- detail : inputs . length > 1
186
- ? localize ( 'unhandledConflicts.detailN' , 'Merge conflicts in {0} editors will remain unhandled.' , inputs . length )
195
+ cancelId : 2 ,
196
+ detail : handler . length > 1
197
+ ? localize ( 'unhandledConflicts.detailN' , 'Merge conflicts in {0} editors will remain unhandled.' , handler . length )
187
198
: localize ( 'unhandledConflicts.detail1' , 'Merge conflicts in this editor will remain unhandled.' )
188
199
} ;
189
200
190
- const isAnyAutoSave = this . _filesConfigurationService . getAutoSaveMode ( ) !== AutoSaveMode . OFF ;
191
- if ( ! isAnyAutoSave ) {
192
- // manual-save: FYI and discard
193
- actions . push (
194
- localize ( 'unhandledConflicts.manualSaveIgnore' , "Save and Continue with Conflicts" ) , // 0
195
- localize ( 'unhandledConflicts.discard' , "Discard Merge Changes" ) , // 1
196
- localize ( 'unhandledConflicts.manualSaveNoSave' , "Don't Save" ) , // 2
197
- ) ;
198
-
199
- } else {
200
- // auto-save: only FYI
201
- actions . push (
202
- localize ( 'unhandledConflicts.ignore' , "Continue with Conflicts" ) , // 0
203
- localize ( 'unhandledConflicts.discard' , "Discard Merge Changes" ) , // 1
204
- ) ;
205
- }
206
-
207
- actions . push ( localize ( 'unhandledConflicts.cancel' , "Cancel" ) ) ;
208
- options . cancelId = actions . length - 1 ;
209
-
210
201
const { choice } = await this . _dialogService . show (
211
202
Severity . Info ,
212
203
localize ( 'unhandledConflicts.msg' , 'Do you want to continue with unhandled conflicts?' ) , // 1
@@ -221,8 +212,8 @@ export class MergeEditorInput extends AbstractTextResourceEditorInput implements
221
212
222
213
// save or revert: in both cases we tell the inputs to ignore unhandled conflicts
223
214
// for the dirty state computation.
224
- for ( const input of inputs ) {
225
- input . _ignoreUnhandledConflictsForDirtyState = true ;
215
+ for ( const input of handler ) {
216
+ input . _ignoreUnhandledConflicts = true ;
226
217
}
227
218
228
219
if ( choice === 0 ) {
@@ -231,7 +222,7 @@ export class MergeEditorInput extends AbstractTextResourceEditorInput implements
231
222
232
223
} else if ( choice === 1 ) {
233
224
// discard: undo all changes and save original (pre-merge) state
234
- for ( const input of inputs ) {
225
+ for ( const input of handler ) {
235
226
input . _discardMergeChanges ( ) ;
236
227
}
237
228
return ConfirmResult . SAVE ;
@@ -243,8 +234,6 @@ export class MergeEditorInput extends AbstractTextResourceEditorInput implements
243
234
}
244
235
245
236
private _discardMergeChanges ( ) : void {
246
- assertType ( this . _model !== undefined ) ;
247
-
248
237
const chunks : string [ ] = [ ] ;
249
238
while ( true ) {
250
239
const chunk = this . _model . resultSnapshot . read ( ) ;
@@ -255,11 +244,4 @@ export class MergeEditorInput extends AbstractTextResourceEditorInput implements
255
244
}
256
245
this . _model . result . setValue ( chunks . join ( ) ) ;
257
246
}
258
-
259
- setLanguageId ( languageId : string , _setExplicitly ?: boolean ) : void {
260
- this . _model ?. setLanguageId ( languageId ) ;
261
- }
262
-
263
- // implement get/set languageId
264
- // implement get/set encoding
265
247
}
0 commit comments