@@ -10,10 +10,11 @@ import { IAction } from 'vs/base/common/actions';
10
10
import { CancellationToken } from 'vs/base/common/cancellation' ;
11
11
import { Color } from 'vs/base/common/color' ;
12
12
import { BugIndicatingError } from 'vs/base/common/errors' ;
13
- import { DisposableStore } from 'vs/base/common/lifecycle' ;
13
+ import { DisposableStore , MutableDisposable } from 'vs/base/common/lifecycle' ;
14
+ import { isEqual } from 'vs/base/common/resources' ;
14
15
import { URI } from 'vs/base/common/uri' ;
15
16
import 'vs/css!./media/mergeEditor' ;
16
- import { ICodeEditor , isCodeEditor } from 'vs/editor/browser/editorBrowser' ;
17
+ import { ICodeEditor } from 'vs/editor/browser/editorBrowser' ;
17
18
import { CodeEditorWidget } from 'vs/editor/browser/widget/codeEditorWidget' ;
18
19
import { IEditorOptions as ICodeEditorOptions } from 'vs/editor/common/config/editorOptions' ;
19
20
import { ScrollType } from 'vs/editor/common/editorCommon' ;
@@ -32,7 +33,7 @@ import { ITelemetryService } from 'vs/platform/telemetry/common/telemetry';
32
33
import { IThemeService } from 'vs/platform/theme/common/themeService' ;
33
34
import { FloatingClickWidget } from 'vs/workbench/browser/codeeditor' ;
34
35
import { AbstractTextEditor } from 'vs/workbench/browser/parts/editor/textEditor' ;
35
- import { IEditorOpenContext } from 'vs/workbench/common/editor' ;
36
+ import { EditorInputWithOptions , EditorResourceAccessor , IEditorOpenContext } from 'vs/workbench/common/editor' ;
36
37
import { EditorInput } from 'vs/workbench/common/editor/editorInput' ;
37
38
import { applyTextEditorOptions } from 'vs/workbench/common/editor/editorOptions' ;
38
39
import { autorunWithStore , IObservable } from 'vs/workbench/contrib/audioCues/browser/observable' ;
@@ -43,6 +44,7 @@ import { ReentrancyBarrier, thenIfNotDisposed } from 'vs/workbench/contrib/merge
43
44
import { MergeEditorViewModel } from 'vs/workbench/contrib/mergeEditor/browser/view/viewModel' ;
44
45
import { settingsSashBorder } from 'vs/workbench/contrib/preferences/common/settingsEditorColorRegistry' ;
45
46
import { IEditorGroup , IEditorGroupsService } from 'vs/workbench/services/editor/common/editorGroupsService' ;
47
+ import { IEditorResolverService , RegisteredEditorPriority } from 'vs/workbench/services/editor/common/editorResolverService' ;
46
48
import { IEditorService } from 'vs/workbench/services/editor/common/editorService' ;
47
49
import './colors' ;
48
50
import { InputCodeEditorView } from './editors/inputCodeEditorView' ;
@@ -87,7 +89,8 @@ export class MergeEditor extends AbstractTextEditor<any> {
87
89
@IConfigurationService private readonly _configurationService : IConfigurationService ,
88
90
@IEditorService editorService : IEditorService ,
89
91
@IEditorGroupsService editorGroupService : IEditorGroupsService ,
90
- @IFileService fileService : IFileService
92
+ @IFileService fileService : IFileService ,
93
+ @IEditorResolverService private readonly _editorResolverService : IEditorResolverService ,
91
94
) {
92
95
super ( MergeEditor . ID , telemetryService , instantiation , storageService , textResourceConfigurationService , themeService , editorService , editorGroupService , fileService ) ;
93
96
@@ -230,6 +233,8 @@ export class MergeEditor extends AbstractTextEditor<any> {
230
233
await super . setInput ( input , options , context , token ) ;
231
234
232
235
this . _sessionDisposables . clear ( ) ;
236
+ this . _toggleEditorOverwrite ( true ) ;
237
+
233
238
const model = await input . resolve ( ) ;
234
239
this . _model = model ;
235
240
@@ -302,6 +307,7 @@ export class MergeEditor extends AbstractTextEditor<any> {
302
307
super . clearInput ( ) ;
303
308
304
309
this . _sessionDisposables . clear ( ) ;
310
+ this . _toggleEditorOverwrite ( false ) ;
305
311
306
312
for ( const { editor } of [ this . input1View , this . input2View , this . inputResultView ] ) {
307
313
editor . setModel ( null ) ;
@@ -333,24 +339,50 @@ export class MergeEditor extends AbstractTextEditor<any> {
333
339
}
334
340
335
341
this . _ctxIsMergeEditor . set ( visible ) ;
342
+ this . _toggleEditorOverwrite ( visible ) ;
336
343
}
337
344
338
- // ---- interact with "outside world" via `getControl`, `scopedContextKeyService`
345
+ private readonly _editorOverrideHandle = this . _store . add ( new MutableDisposable ( ) ) ;
339
346
340
- override getControl ( ) : ICodeEditor | undefined {
341
- for ( const { editor } of [ this . input1View , this . input2View , this . inputResultView ] ) {
342
- if ( editor . hasWidgetFocus ( ) ) {
343
- return editor ;
344
- }
347
+ private _toggleEditorOverwrite ( haveIt : boolean ) {
348
+ if ( ! haveIt ) {
349
+ this . _editorOverrideHandle . clear ( ) ;
350
+ return ;
345
351
}
346
- return undefined ;
352
+ // this is RATHER UGLY. I dynamically register an editor for THIS (editor,input) so that
353
+ // navigating within the merge editor works, e.g navigating from the outline or breakcrumps
354
+ // or revealing a definition, reference etc
355
+ // TODO@jrieken @bpasero @lramos 15
356
+ const input = this . input ;
357
+ if ( input instanceof MergeEditorInput ) {
358
+ this . _editorOverrideHandle . value = this . _editorResolverService . registerEditor (
359
+ `${ input . result . scheme } :${ input . result . fsPath } ` ,
360
+ {
361
+ id : `${ this . getId ( ) } /fake` ,
362
+ label : this . input ?. getName ( ) ! ,
363
+ priority : RegisteredEditorPriority . exclusive
364
+ } ,
365
+ { } ,
366
+ ( candidate ) : EditorInputWithOptions => {
367
+ const resource = EditorResourceAccessor . getCanonicalUri ( candidate ) ;
368
+ if ( ! isEqual ( resource , this . model ?. result . uri ) ) {
369
+ throw new Error ( `Expected to be called WITH ${ input . result . toString ( ) } ` ) ;
370
+ }
371
+ return { editor : input } ;
372
+ }
373
+ ) ;
374
+ }
375
+ }
376
+
377
+ // ---- interact with "outside world" via`getControl`, `scopedContextKeyService`: we only expose the result-editor keep the others internal
378
+
379
+ override getControl ( ) : ICodeEditor | undefined {
380
+ return this . inputResultView . editor ;
347
381
}
348
382
349
383
override get scopedContextKeyService ( ) : IContextKeyService | undefined {
350
384
const control = this . getControl ( ) ;
351
- return isCodeEditor ( control )
352
- ? control . invokeWithinContext ( accessor => accessor . get ( IContextKeyService ) )
353
- : undefined ;
385
+ return control ?. invokeWithinContext ( accessor => accessor . get ( IContextKeyService ) ) ;
354
386
}
355
387
356
388
// --- layout
0 commit comments