Skip to content

Commit 442ebb8

Browse files
joaomorenobpasero
andauthored
dirty diff: use IEditorGroupsService instead of IEditorService (microsoft#166634)
* dirty diff: use IEditorGroupsService instead of IEditorService also, do not dispose DirtyDiffItem of non-active tabs fixes microsoft#163499 * address feedback Co-authored-by: Benjamin Pasero <[email protected]>
1 parent c8b4060 commit 442ebb8

File tree

1 file changed

+33
-49
lines changed

1 file changed

+33
-49
lines changed

src/vs/workbench/contrib/scm/browser/dirtydiffDecorator.ts

Lines changed: 33 additions & 49 deletions
Original file line numberDiff line numberDiff line change
@@ -10,18 +10,16 @@ import { ThrottledDelayer, first } from 'vs/base/common/async';
1010
import { IDisposable, dispose, toDisposable, Disposable, DisposableStore } from 'vs/base/common/lifecycle';
1111
import { Event, Emitter } from 'vs/base/common/event';
1212
import * as ext from 'vs/workbench/common/contributions';
13-
import { CodeEditorWidget } from 'vs/editor/browser/widget/codeEditorWidget';
1413
import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation';
1514
import { IResolvedTextEditorModel, ITextModelService } from 'vs/editor/common/services/resolverService';
16-
import { IEditorService } from 'vs/workbench/services/editor/common/editorService';
1715
import { IEditorWorkerService } from 'vs/editor/common/services/editorWorker';
1816
import { IConfigurationService } from 'vs/platform/configuration/common/configuration';
1917
import { URI } from 'vs/base/common/uri';
2018
import { ISCMService, ISCMRepository, ISCMProvider } from 'vs/workbench/contrib/scm/common/scm';
2119
import { ModelDecorationOptions } from 'vs/editor/common/model/textModel';
2220
import { IColorTheme, themeColorFromId, IThemeService, ThemeIcon } from 'vs/platform/theme/common/themeService';
2321
import { editorErrorForeground, registerColor, transparent } from 'vs/platform/theme/common/colorRegistry';
24-
import { ICodeEditor, IEditorMouseEvent, MouseTargetType } from 'vs/editor/browser/editorBrowser';
22+
import { ICodeEditor, IEditorMouseEvent, isCodeEditor, MouseTargetType } from 'vs/editor/browser/editorBrowser';
2523
import { registerEditorAction, registerEditorContribution, ServicesAccessor, EditorAction } from 'vs/editor/browser/editorExtensions';
2624
import { PeekViewWidget, getOuterEditor, peekViewBorder, peekViewTitleBackground, peekViewTitleForeground, peekViewTitleInfoForeground } from 'vs/editor/contrib/peekView/browser/peekView';
2725
import { IContextKeyService, IContextKey, ContextKeyExpr, RawContextKey } from 'vs/platform/contextkey/common/contextkey';
@@ -53,6 +51,10 @@ import { IProgressService, ProgressLocation } from 'vs/platform/progress/common/
5351
import { IChange } from 'vs/editor/common/diff/smartLinesDiffComputer';
5452
import { Color } from 'vs/base/common/color';
5553
import { Iterable } from 'vs/base/common/iterator';
54+
import { ResourceMap } from 'vs/base/common/map';
55+
import { IEditorService } from 'vs/workbench/services/editor/common/editorService';
56+
import { DEFAULT_EDITOR_ASSOCIATION } from 'vs/workbench/common/editor';
57+
import { FILE_EDITOR_INPUT_ID } from 'vs/workbench/contrib/files/common/files';
5658

5759
class DiffActionRunner extends ActionRunner {
5860

@@ -66,7 +68,7 @@ class DiffActionRunner extends ActionRunner {
6668
}
6769

6870
export interface IModelRegistry {
69-
getModel(editorModel: IEditorModel): DirtyDiffModel | null;
71+
getModel(editorModel: IEditorModel): DirtyDiffModel | undefined;
7072
}
7173

7274
export const isDirtyDiffVisible = new RawContextKey<boolean>('dirtyDiffVisible', false);
@@ -1328,7 +1330,10 @@ export class DirtyDiffModel extends Disposable {
13281330

13291331
class DirtyDiffItem {
13301332

1331-
constructor(readonly model: DirtyDiffModel, readonly decorator: DirtyDiffDecorator) { }
1333+
constructor(
1334+
readonly model: DirtyDiffModel,
1335+
readonly decorator: DirtyDiffDecorator
1336+
) { }
13321337

13331338
dispose(): void {
13341339
this.decorator.dispose();
@@ -1345,7 +1350,7 @@ export class DirtyDiffWorkbenchController extends Disposable implements ext.IWor
13451350

13461351
private enabled = false;
13471352
private viewState: IViewState = { width: 3, visibility: 'always' };
1348-
private items = new Map<IResolvedTextFileEditorModel, DirtyDiffItem>();
1353+
private items = new ResourceMap<DirtyDiffItem>();
13491354
private readonly transientDisposables = this._register(new DisposableStore());
13501355
private stylesheet: HTMLStyleElement;
13511356

@@ -1425,7 +1430,7 @@ export class DirtyDiffWorkbenchController extends Disposable implements ext.IWor
14251430
this.disable();
14261431
}
14271432

1428-
this.transientDisposables.add(this.editorService.onDidVisibleEditorsChange(() => this.onEditorsChanged()));
1433+
this.transientDisposables.add(Event.any(this.editorService.onDidCloseEditor, this.editorService.onDidVisibleEditorsChange)(() => this.onEditorsChanged()));
14291434
this.onEditorsChanged();
14301435
this.enabled = true;
14311436
}
@@ -1445,59 +1450,38 @@ export class DirtyDiffWorkbenchController extends Disposable implements ext.IWor
14451450
this.enabled = false;
14461451
}
14471452

1448-
// HACK: This is the best current way of figuring out whether to draw these decorations
1449-
// or not. Needs context from the editor, to know whether it is a diff editor, in place editor
1450-
// etc.
14511453
private onEditorsChanged(): void {
1452-
const models = this.editorService.visibleTextEditorControls
1453-
1454-
// only interested in code editor widgets
1455-
.filter(c => c instanceof CodeEditorWidget)
1454+
for (const editor of this.editorService.visibleTextEditorControls) {
1455+
if (isCodeEditor(editor)) {
1456+
const textModel = editor.getModel();
1457+
const controller = DirtyDiffController.get(editor);
14561458

1457-
// set model registry and map to models
1458-
.map(editor => {
1459-
const codeEditor = editor as CodeEditorWidget;
1460-
const controller = DirtyDiffController.get(codeEditor);
14611459
if (controller) {
14621460
controller.modelRegistry = this;
14631461
}
1464-
return codeEditor.getModel();
1465-
})
1466-
1467-
// remove nulls and duplicates
1468-
.filter((m, i, a) => !!m && !!m.uri && a.indexOf(m, i + 1) === -1)
1469-
1470-
// only want resolved text file service models
1471-
.map(m => this.textFileService.files.get(m!.uri))
1472-
.filter(m => m?.isResolved()) as IResolvedTextFileEditorModel[];
1473-
1474-
const set = new Set(models);
1475-
const newModels = models.filter(o => !this.items.has(o));
1476-
const oldModels = [...this.items.keys()].filter(m => !set.has(m));
1477-
1478-
oldModels.forEach(m => this.onModelInvisible(m));
1479-
newModels.forEach(m => this.onModelVisible(m));
1480-
}
14811462

1482-
private onModelVisible(textFileModel: IResolvedTextFileEditorModel): void {
1483-
const model = this.instantiationService.createInstance(DirtyDiffModel, textFileModel);
1484-
const decorator = new DirtyDiffDecorator(textFileModel.textEditorModel, model, this.configurationService);
1485-
this.items.set(textFileModel, new DirtyDiffItem(model, decorator));
1486-
}
1463+
if (textModel && !this.items.has(textModel.uri)) {
1464+
const textFileModel = this.textFileService.files.get(textModel.uri);
14871465

1488-
private onModelInvisible(textFileModel: IResolvedTextFileEditorModel): void {
1489-
this.items.get(textFileModel)!.dispose();
1490-
this.items.delete(textFileModel);
1491-
}
1466+
if (textFileModel?.isResolved()) {
1467+
const dirtyDiffModel = this.instantiationService.createInstance(DirtyDiffModel, textFileModel);
1468+
const decorator = new DirtyDiffDecorator(textFileModel.textEditorModel, dirtyDiffModel, this.configurationService);
1469+
this.items.set(textModel.uri, new DirtyDiffItem(dirtyDiffModel, decorator));
1470+
}
1471+
}
1472+
}
1473+
}
14921474

1493-
getModel(editorModel: ITextModel): DirtyDiffModel | null {
1494-
for (const [model, diff] of this.items) {
1495-
if (model.textEditorModel.id === editorModel.id) {
1496-
return diff.model;
1475+
for (const [uri, item] of this.items) {
1476+
if (!this.editorService.isOpened({ resource: uri, typeId: FILE_EDITOR_INPUT_ID, editorId: DEFAULT_EDITOR_ASSOCIATION.id })) {
1477+
item.dispose();
1478+
this.items.delete(uri);
14971479
}
14981480
}
1481+
}
14991482

1500-
return null;
1483+
getModel(editorModel: ITextModel): DirtyDiffModel | undefined {
1484+
return this.items.get(editorModel.uri)?.model;
15011485
}
15021486

15031487
override dispose(): void {

0 commit comments

Comments
 (0)