Skip to content

Commit 085399f

Browse files
authored
Merge pull request microsoft#185592 from microsoft/hediet/b/horizontal-ladybug
Diff Editor v2 Improvements
2 parents a0fce77 + 813a36e commit 085399f

File tree

12 files changed

+175
-62
lines changed

12 files changed

+175
-62
lines changed

build/lib/stylelint/vscode-known-variables.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -100,6 +100,7 @@
100100
"--vscode-diffEditor-removedLineBackground",
101101
"--vscode-diffEditor-removedTextBackground",
102102
"--vscode-diffEditor-removedTextBorder",
103+
"--vscode-diffEditor-unchangedCodeBackground",
103104
"--vscode-diffEditor-unchangedRegionBackground",
104105
"--vscode-diffEditor-unchangedRegionForeground",
105106
"--vscode-diffEditorGutter-insertedLineBackground",

scripts/playground-server.ts

Lines changed: 15 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -235,10 +235,10 @@ function handleGetFileChangesRequest(watcher: DirWatcher, fileServer: FileServer
235235
function makeLoaderJsHotReloadable(loaderJsCode: string, fileChangesUrl: URL): string {
236236
loaderJsCode = loaderJsCode.replace(
237237
/constructor\(env, scriptLoader, defineFunc, requireFunc, loaderAvailableTimestamp = 0\) {/,
238-
'$&globalThis.$$globalModuleManager = this;'
238+
'$&globalThis.___globalModuleManager = this;'
239239
);
240240

241-
const $$globalModuleManager: any = undefined;
241+
const ___globalModuleManager: any = undefined;
242242

243243
// This code will be appended to loader.js
244244
function $watchChanges(fileChangesUrl: string) {
@@ -266,24 +266,26 @@ function makeLoaderJsHotReloadable(loaderJsCode: string, fileChangesUrl: URL): s
266266
const data = JSON.parse(line);
267267
let handled = false;
268268
if (data.changedPath.endsWith('.css')) {
269-
console.log('css changed', data.changedPath);
270-
const styleSheet = [...document.querySelectorAll(`link[rel='stylesheet']`)].find((l: any) => new URL(l.href, document.location.href).pathname.endsWith(data.changedPath)) as any;
271-
if (styleSheet) {
272-
styleSheet.href = styleSheet.href.replace(/\?.*/, '') + '?' + Date.now();
269+
if (typeof document !== 'undefined') {
270+
console.log('css changed', data.changedPath);
271+
const styleSheet = [...document.querySelectorAll(`link[rel='stylesheet']`)].find((l: any) => new URL(l.href, document.location.href).pathname.endsWith(data.changedPath)) as any;
272+
if (styleSheet) {
273+
styleSheet.href = styleSheet.href.replace(/\?.*/, '') + '?' + Date.now();
274+
}
273275
}
274276
handled = true;
275277
} else if (data.changedPath.endsWith('.js') && data.moduleId) {
276278
console.log('js changed', data.changedPath);
277-
const moduleId = $$globalModuleManager._moduleIdProvider.getModuleId(data.moduleId);
278-
if ($$globalModuleManager._modules2[moduleId]) {
279-
const srcUrl = $$globalModuleManager._config.moduleIdToPaths(data.moduleId);
279+
const moduleId = ___globalModuleManager._moduleIdProvider.getModuleId(data.moduleId);
280+
if (___globalModuleManager._modules2[moduleId]) {
281+
const srcUrl = ___globalModuleManager._config.moduleIdToPaths(data.moduleId);
280282
const newSrc = await (await fetch(srcUrl)).text();
281283
(new Function('define', newSrc))(function (deps, callback) {
282-
const oldModule = $$globalModuleManager._modules2[moduleId];
283-
delete $$globalModuleManager._modules2[moduleId];
284+
const oldModule = ___globalModuleManager._modules2[moduleId];
285+
delete ___globalModuleManager._modules2[moduleId];
284286

285-
$$globalModuleManager.defineModule(data.moduleId, deps, callback);
286-
const newModule = $$globalModuleManager._modules2[moduleId];
287+
___globalModuleManager.defineModule(data.moduleId, deps, callback);
288+
const newModule = ___globalModuleManager._modules2[moduleId];
287289
const oldExports = { ...oldModule.exports };
288290

289291
Object.assign(oldModule.exports, newModule.exports);

src/vs/editor/browser/widget/diffEditorWidget2/diffEditorWidget2.ts

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
* Copyright (c) Microsoft Corporation. All rights reserved.
33
* Licensed under the MIT License. See License.txt in the project root for license information.
44
*--------------------------------------------------------------------------------------------*/
5-
import { h } from 'vs/base/browser/dom';
5+
import { $, h } from 'vs/base/browser/dom';
66
import { IBoundarySashes } from 'vs/base/browser/ui/sash/sash';
77
import { findLast } from 'vs/base/common/arrays';
88
import { onUnexpectedError } from 'vs/base/common/errors';
@@ -25,7 +25,7 @@ import { ViewZoneManager } from 'vs/editor/browser/widget/diffEditorWidget2/line
2525
import { MovedBlocksLinesPart } from 'vs/editor/browser/widget/diffEditorWidget2/movedBlocksLines';
2626
import { OverviewRulerPart } from 'vs/editor/browser/widget/diffEditorWidget2/overviewRulerPart';
2727
import { UnchangedRangesFeature } from 'vs/editor/browser/widget/diffEditorWidget2/unchangedRanges';
28-
import { ObservableElementSizeObserver, applyObservableDecorations, deepMerge, readHotReloadableExport } from 'vs/editor/browser/widget/diffEditorWidget2/utils';
28+
import { ObservableElementSizeObserver, applyObservableDecorations, applyStyle, deepMerge, readHotReloadableExport } from 'vs/editor/browser/widget/diffEditorWidget2/utils';
2929
import { WorkerBasedDocumentDiffProvider } from 'vs/editor/browser/widget/workerBasedDocumentDiffProvider';
3030
import { EditorOptions, IDiffEditorOptions, IEditorOptions, ValidDiffEditorBaseOptions, clampedFloat, clampedInt, boolean as validateBooleanOption, stringSet as validateStringSetOption } from 'vs/editor/common/config/editorOptions';
3131
import { IDimension } from 'vs/editor/common/core/dimension';
@@ -68,6 +68,7 @@ const diffEditorDefaultOptions: ValidDiffEditorBaseOptions = {
6868

6969
export class DiffEditorWidget2 extends DelegatingEditor implements IDiffEditor {
7070
private readonly elements = h('div.monaco-diff-editor.side-by-side', { style: { position: 'relative', height: '100%' } }, [
71+
h('div.noModificationsOverlay@overlay', { style: { position: 'absolute', height: '100%', visibility: 'hidden', } }, [$('span', {}, 'No Changes')]),
7172
h('div.editor.original@original', { style: { position: 'absolute', height: '100%' } }),
7273
h('div.editor.modified@modified', { style: { position: 'absolute', height: '100%' } }),
7374
]);
@@ -190,6 +191,11 @@ export class DiffEditorWidget2 extends DelegatingEditor implements IDiffEditor {
190191
this._originalEditor,
191192
this._modifiedEditor,
192193
));
194+
195+
this._register(applyStyle(this.elements.overlay, {
196+
width: this._layoutInfo.map((i, r) => i.originalEditor.width + (this._options.read(r).renderSideBySide ? 0 : i.modifiedEditor.width)),
197+
visibility: this._diffModel.map((m, r) => (m && m.hideUnchangedRegions.read(r) && m.diff.read(r)?.mappings.length === 0) ? 'visible' : 'hidden'),
198+
}));
193199
}
194200

195201
private readonly _layoutInfo = derived('modifiedEditorLayoutInfo', (reader) => {

src/vs/editor/browser/widget/diffEditorWidget2/diffModel.ts

Lines changed: 25 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -31,8 +31,19 @@ export class DiffModel extends Disposable implements IDiffEditorViewModel {
3131
'unchangedRegion',
3232
{ regions: [], originalDecorationIds: [], modifiedDecorationIds: [] }
3333
);
34-
public readonly unchangedRegions: IObservable<UnchangedRegion[]> = derived('unchangedRegions', r =>
35-
this._hideUnchangedRegions.read(r) ? this._unchangedRegions.read(r).regions : []
34+
public readonly unchangedRegions: IObservable<UnchangedRegion[]> = derived('unchangedRegions', r => {
35+
if (this.hideUnchangedRegions.read(r)) {
36+
return this._unchangedRegions.read(r).regions;
37+
} else {
38+
// Reset state
39+
transaction(tx => {
40+
for (const r of this._unchangedRegions.get().regions) {
41+
r.setState(0, 0, tx);
42+
}
43+
});
44+
return [];
45+
}
46+
}
3647
);
3748

3849
public readonly syncedMovedTexts = observableValue<MovedText | undefined>('syncedMovedText', undefined);
@@ -41,7 +52,7 @@ export class DiffModel extends Disposable implements IDiffEditorViewModel {
4152
public readonly model: IDiffEditorModel,
4253
ignoreTrimWhitespace: IObservable<boolean>,
4354
maxComputationTimeMs: IObservable<number>,
44-
private readonly _hideUnchangedRegions: IObservable<boolean>,
55+
public readonly hideUnchangedRegions: IObservable<boolean>,
4556
private readonly _showMoves: IObservable<boolean>,
4657
documentDiffProvider: IDocumentDiffProvider,
4758
) {
@@ -74,7 +85,7 @@ export class DiffModel extends Disposable implements IDiffEditorViewModel {
7485
}
7586

7687
const textEdits = TextEditInfo.fromModelContentChanges(e.changes);
77-
const result = applyModifiedEdits(this._lastDiff!, textEdits, model.original, model.modified);
88+
const result = applyOriginalEdits(this._lastDiff!, textEdits, model.original, model.modified);
7889
if (result) {
7990
this._lastDiff = result;
8091
this._diff.set(DiffState.fromDiffResult(this._lastDiff), undefined);
@@ -171,6 +182,9 @@ export class DiffModel extends Disposable implements IDiffEditorViewModel {
171182
}
172183

173184
public ensureModifiedLineIsVisible(lineNumber: number, tx: ITransaction): void {
185+
if (this.diff.get()?.mappings.length === 0) {
186+
return;
187+
}
174188
const unchangedRegions = this._unchangedRegions.get().regions;
175189
for (const r of unchangedRegions) {
176190
if (r.getHiddenModifiedRange(undefined).contains(lineNumber)) {
@@ -181,6 +195,9 @@ export class DiffModel extends Disposable implements IDiffEditorViewModel {
181195
}
182196

183197
public ensureOriginalLineIsVisible(lineNumber: number, tx: ITransaction): void {
198+
if (this.diff.get()?.mappings.length === 0) {
199+
return;
200+
}
184201
const unchangedRegions = this._unchangedRegions.get().regions;
185202
for (const r of unchangedRegions) {
186203
if (r.getHiddenOriginalRange(undefined).contains(lineNumber)) {
@@ -251,8 +268,10 @@ export class UnchangedRegion {
251268
let modStart = mapping.modifiedRange.startLineNumber;
252269
let length = mapping.originalRange.length;
253270

254-
if (origStart === 1 && length > minContext + minHiddenLineCount) {
255-
length -= minContext;
271+
if (origStart === 1 && modStart === 1 && length > minContext + minHiddenLineCount) {
272+
if (length < originalLineCount) {
273+
length -= minContext;
274+
}
256275
result.push(new UnchangedRegion(origStart, modStart, length, 0, 0));
257276
} else if (origStart + length === originalLineCount + 1 && length > minContext + minHiddenLineCount) {
258277
origStart += minContext;

src/vs/editor/browser/widget/diffEditorWidget2/lineAlignment.ts

Lines changed: 15 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -335,8 +335,21 @@ export class ViewZoneManager extends Disposable {
335335
scrollState.restore(this._modifiedEditor);
336336
}));
337337

338-
this._register(this._originalEditor.onDidScrollChange(e => { this._modifiedEditor.setScrollLeft(e.scrollLeft); }));
339-
this._register(this._modifiedEditor.onDidScrollChange(e => { this._originalEditor.setScrollLeft(e.scrollLeft); }));
338+
let ignoreChange = false;
339+
this._register(this._originalEditor.onDidScrollChange(e => {
340+
if (e.scrollLeftChanged && !ignoreChange) {
341+
ignoreChange = true;
342+
this._modifiedEditor.setScrollLeft(e.scrollLeft);
343+
ignoreChange = false;
344+
}
345+
}));
346+
this._register(this._modifiedEditor.onDidScrollChange(e => {
347+
if (e.scrollLeftChanged && !ignoreChange) {
348+
ignoreChange = true;
349+
this._originalEditor.setScrollLeft(e.scrollLeft);
350+
ignoreChange = false;
351+
}
352+
}));
340353

341354
this._originalScrollTop = observableFromEvent(this._originalEditor.onDidScrollChange, () => this._originalEditor.getScrollTop());
342355
this._modifiedScrollTop = observableFromEvent(this._modifiedEditor.onDidScrollChange, () => this._modifiedEditor.getScrollTop());

src/vs/editor/browser/widget/diffEditorWidget2/style.css

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,8 @@
88
}
99

1010
.diff-hidden-lines {
11-
transform: translate(0px, -8px);
11+
height: 0px; /* The children each have a fixed height, the transform confuses the browser */
12+
transform: translate(0px, -10px);
1213
font-size: 13px;
1314
line-height: 14px;
1415
}
@@ -35,6 +36,19 @@
3536
transform: translate(0px, -6px);
3637
}
3738

39+
.diff-unchanged-lines {
40+
background: var(--vscode-diffEditor-unchangedCodeBackground);
41+
}
42+
43+
.noModificationsOverlay {
44+
z-index: 1;
45+
background: var(--vscode-editor-background);
46+
47+
display: flex;
48+
justify-content: center;
49+
align-items: center;
50+
}
51+
3852

3953
.diff-hidden-lines .center {
4054
background: var(--vscode-diffEditor-unchangedRegionBackground);

0 commit comments

Comments
 (0)