Skip to content

Commit cb8ce9a

Browse files
Update DirtyDiffWidget change model when changes change
1 parent 39e0f4c commit cb8ce9a

File tree

5 files changed

+41
-28
lines changed

5 files changed

+41
-28
lines changed

packages/monaco/src/browser/monaco-editor-provider.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -424,7 +424,7 @@ export class MonacoEditorProvider {
424424
fixedOverflowWidgets: true,
425425
minimap: { enabled: false },
426426
renderSideBySide: false,
427-
readOnly: true,
427+
readOnly: false,
428428
renderIndicators: false,
429429
diffAlgorithm: 'advanced',
430430
stickyScroll: { enabled: false },

packages/scm/src/browser/decorations/scm-decorations-service.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -80,7 +80,7 @@ export class ScmDecorationsService {
8080
const previousLines = ContentLines.fromString(previousContent);
8181
const currentLines = ContentLines.fromTextEditorDocument(editor.document);
8282
const dirtyDiff = this.diffComputer.computeDirtyDiff(ContentLines.arrayLike(previousLines), ContentLines.arrayLike(currentLines));
83-
const update = <DirtyDiffUpdate>{ editor, previousRevisionUri: uri, ...dirtyDiff };
83+
const update = { editor, previousRevisionUri: uri, ...dirtyDiff } satisfies DirtyDiffUpdate;
8484
this.decorator.applyDecorations(update);
8585
this.onDirtyDiffUpdateEmitter.fire(update);
8686
} finally {

packages/scm/src/browser/dirty-diff/dirty-diff-navigator.ts

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -136,6 +136,9 @@ export class DirtyDiffController implements Disposable {
136136
handleDirtyDiffUpdate(dirtyDiff: DirtyDiffUpdate): void {
137137
if (dirtyDiff.editor === this.editor) {
138138
this.dirtyDiff = dirtyDiff;
139+
if (this.widget) {
140+
this.widget.changes = dirtyDiff.changes ;
141+
}
139142
}
140143
}
141144

@@ -209,7 +212,8 @@ export class DirtyDiffController implements Disposable {
209212
protected createWidget(): DirtyDiffWidget | undefined {
210213
const { widgetFactory, editor, changes, previousRevisionUri } = this;
211214
if (widgetFactory && editor instanceof MonacoEditor && changes?.length && previousRevisionUri) {
212-
const widget = widgetFactory({ editor, previousRevisionUri, changes });
215+
const widget = widgetFactory({ editor, previousRevisionUri });
216+
widget.changes = changes;
213217
widget.onDidClose(() => {
214218
this.widget = undefined;
215219
});

packages/scm/src/browser/dirty-diff/dirty-diff-widget.ts

Lines changed: 32 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,6 @@ export const DirtyDiffWidgetProps = Symbol('DirtyDiffWidgetProps');
3636
export interface DirtyDiffWidgetProps {
3737
readonly editor: MonacoEditor;
3838
readonly previousRevisionUri: URI;
39-
readonly changes: readonly Change[];
4039
}
4140

4241
export const DirtyDiffWidgetFactory = Symbol('DirtyDiffWidgetFactory');
@@ -50,6 +49,7 @@ export class DirtyDiffWidget implements Disposable {
5049
protected index: number = -1;
5150
private peekView: DirtyDiffPeekView;
5251
private diffEditorPromise: Promise<MonacoDiffEditor>;
52+
protected _changes?: readonly Change[];
5353

5454
constructor(
5555
@inject(DirtyDiffWidgetProps) protected readonly props: DirtyDiffWidgetProps,
@@ -66,6 +66,14 @@ export class DirtyDiffWidget implements Disposable {
6666
this.diffEditorPromise = this.peekView.create();
6767
}
6868

69+
get changes(): readonly Change[] {
70+
return this._changes ?? [];
71+
}
72+
73+
set changes(changes: readonly Change[]) {
74+
this.handleChangedChanges(changes);
75+
}
76+
6977
get editor(): MonacoEditor {
7078
return this.props.editor;
7179
}
@@ -78,10 +86,6 @@ export class DirtyDiffWidget implements Disposable {
7886
return this.props.previousRevisionUri;
7987
}
8088

81-
get changes(): readonly Change[] {
82-
return this.props.changes;
83-
}
84-
8589
get currentChange(): Change | undefined {
8690
return this.changes[this.index];
8791
}
@@ -90,6 +94,16 @@ export class DirtyDiffWidget implements Disposable {
9094
return this.index;
9195
}
9296

97+
protected handleChangedChanges(updated: readonly Change[]): void {
98+
if (this.currentChange) {
99+
const {previousRange: {start, end}} = this.currentChange;
100+
this.index = updated.findIndex(candidate => candidate.previousRange.start === start && candidate.previousRange.end === end);
101+
} else {
102+
this.index = -1;
103+
}
104+
this._changes = updated;
105+
}
106+
93107
async showChange(index: number): Promise<void> {
94108
await this.checkCreated();
95109
if (index >= 0 && index < this.changes.length) {
@@ -99,23 +113,20 @@ export class DirtyDiffWidget implements Disposable {
99113
}
100114

101115
async showNextChange(): Promise<void> {
102-
await this.checkCreated();
103-
const index = this.index;
104-
const length = this.changes.length;
105-
if (length > 0 && (index < 0 || length > 1)) {
106-
this.index = index < 0 ? 0 : cycle(index, 1, length);
107-
this.showCurrentChange();
108-
}
116+
const editor = await this.checkCreated();
117+
editor.diffNavigator.next();
118+
this.updateIndex(editor);
109119
}
110120

111121
async showPreviousChange(): Promise<void> {
112-
await this.checkCreated();
113-
const index = this.index;
114-
const length = this.changes.length;
115-
if (length > 0 && (index < 0 || length > 1)) {
116-
this.index = index < 0 ? length - 1 : cycle(index, -1, length);
117-
this.showCurrentChange();
118-
}
122+
const editor = await this.checkCreated();
123+
editor.diffNavigator.previous();
124+
this.updateIndex(editor);
125+
}
126+
127+
protected updateIndex(editor: MonacoDiffEditor): void {
128+
const line = editor.cursor.line;
129+
this.index = this.changes.findIndex(candidate => candidate.currentRange.start <= line && candidate.currentRange.end >= line);
119130
}
120131

121132
async getContentWithSelectedChanges(predicate: (change: Change, index: number, changes: readonly Change[]) => boolean): Promise<string> {
@@ -174,15 +185,11 @@ export class DirtyDiffWidget implements Disposable {
174185
return Math.min(changeHeightInLines + /* padding */ 8, Math.floor(editorHeightInLines / 3));
175186
}
176187

177-
protected async checkCreated(): Promise<void> {
178-
await this.diffEditorPromise;
188+
protected async checkCreated(): Promise<MonacoDiffEditor> {
189+
return this.diffEditorPromise;
179190
}
180191
}
181192

182-
function cycle(index: number, offset: -1 | 1, length: number): number {
183-
return (index + offset + length) % length;
184-
}
185-
186193
// adapted from https://github.com/microsoft/vscode/blob/823d54f86ee13eb357bc6e8e562e89d793f3c43b/extensions/git/src/staging.ts
187194
function applyChanges(changes: readonly Change[], original: monaco.editor.ITextModel, modified: monaco.editor.ITextModel): string {
188195
const result: string[] = [];

packages/scm/src/browser/scm-contribution.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -204,6 +204,7 @@ export class ScmContribution extends AbstractViewContribution<ScmWidget> impleme
204204
execute: widget => {
205205
if (widget instanceof EditorWidget && widget.editor instanceof MonacoDiffEditor) {
206206
widget.editor.diffNavigator.next();
207+
widget.activate();
207208
} else {
208209
this.dirtyDiffNavigator.gotoNextChange();
209210
}
@@ -219,6 +220,7 @@ export class ScmContribution extends AbstractViewContribution<ScmWidget> impleme
219220
execute: widget => {
220221
if (widget instanceof EditorWidget && widget.editor instanceof MonacoDiffEditor) {
221222
widget.editor.diffNavigator.previous();
223+
widget.activate();
222224
} else {
223225
this.dirtyDiffNavigator.gotoPreviousChange();
224226
}

0 commit comments

Comments
 (0)