Skip to content

Commit 82395ea

Browse files
committed
sorting through ai belligerancy
1 parent 1fcfd7f commit 82395ea

4 files changed

Lines changed: 409 additions & 57 deletions

File tree

apps/demo/src/main.ts

Lines changed: 26 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -202,6 +202,7 @@ function renderDiff(parsedPatches: ParsedPatch[], manager?: WorkerPoolManager) {
202202
| FileDiff<LineCommentMetadata>
203203
| VirtualizedFileDiff<LineCommentMetadata>;
204204
const options: FileDiffOptions<LineCommentMetadata> = {
205+
expandUnchanged: true,
205206
theme: DEMO_THEME,
206207
themeType,
207208
diffStyle: unified ? 'unified' : 'split',
@@ -226,7 +227,7 @@ function renderDiff(parsedPatches: ParsedPatch[], manager?: WorkerPoolManager) {
226227
// expandUnchanged: true,
227228

228229
// Hover Decoration Snippets
229-
enableGutterUtility: true,
230+
// enableGutterUtility: true,
230231
// onGutterUtilityClick(event) {
231232
// console.log('onGutterUtilityClick', event);
232233
// },
@@ -682,28 +683,40 @@ const DECORATIONS: FileDecorationItem[] = [
682683
];
683684

684685
const DECORATIONS_DIFF: DiffDecorationItem[] = [
685-
{
686-
lineNumber: 1,
687-
side: 'deletions',
688-
bar: true,
689-
/* color: 'red' */
690-
},
691686
{
692687
lineNumber: 2,
693688
endLineNumber: 6,
694689
side: 'additions',
695690
bar: true,
691+
// color: 'red',
696692
background: 'red',
697-
// color: 'blue',
698693
},
699694
{
700695
lineNumber: 5,
701-
endLineNumber: 11,
696+
endLineNumber: 6,
697+
side: 'additions',
698+
bar: true,
699+
background: true,
700+
},
701+
{
702+
lineNumber: 7,
703+
side: 'additions',
704+
bar: true,
705+
background: true,
706+
},
707+
{
708+
lineNumber: 9,
709+
endLineNumber: 15,
710+
side: 'additions',
711+
bar: true,
712+
background: true,
713+
},
714+
{
715+
lineNumber: 12,
716+
endLineNumber: 15,
702717
side: 'additions',
703718
bar: true,
704719
background: true,
705-
// background: '#123456',
706-
// color: 'orange',
707720
},
708721
];
709722

@@ -777,7 +790,7 @@ if (renderFileButton != null) {
777790
// },
778791

779792
// Hover Decoration Snippets
780-
enableGutterUtility: true,
793+
// enableGutterUtility: true,
781794
// onGutterUtilityClick(event) {
782795
// console.log('onGutterUtilityClick', event);
783796
// },
@@ -867,7 +880,7 @@ if (renderFileConflictButton != null) {
867880
overflow: wrap ? 'wrap' : 'scroll',
868881
renderAnnotation,
869882
enableLineSelection: true,
870-
enableGutterUtility: true,
883+
// enableGutterUtility: true,
871884
maxContextLines: 4,
872885

873886
// Token Testing Helpers

packages/diffs/src/utils/getLineDecorationProperties.ts

Lines changed: 48 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -51,13 +51,20 @@ export function getLineDecorationGutterChildren(
5151
return undefined;
5252
}
5353

54+
const visualBarLayers = collapseBarLayersForRendering(barLayers);
55+
5456
return [
5557
createHastElement({
5658
tagName: 'span',
5759
properties: {
5860
'data-decoration-bar-stack': '',
59-
'data-decoration-bar-layer-count': String(barLayers.length),
60-
style: getLineDecorationBarStackStyle(barLayers),
61+
'data-decoration-bar-layer-count': String(visualBarLayers.length),
62+
'data-decoration-bar-overlap':
63+
visualBarLayers.length > 1 ? '' : undefined,
64+
'data-decoration-bar-second':
65+
visualBarLayers.length > 1 ? '' : undefined,
66+
'data-decoration-bar-third':
67+
visualBarLayers.length > 2 ? '' : undefined,
6168
},
6269
}),
6370
];
@@ -131,6 +138,12 @@ export function mergeNormalizedLineDecorations(
131138
second.barLayers
132139
);
133140
const topBar = barLayers?.at(-1);
141+
const topBarDepth =
142+
topBar?.sourceIndex === first.barSourceIndex
143+
? first.barDepth
144+
: topBar?.sourceIndex === second.barSourceIndex
145+
? second.barDepth
146+
: undefined;
134147

135148
return {
136149
barIndices,
@@ -143,7 +156,7 @@ export function mergeNormalizedLineDecorations(
143156
backgroundColor: background?.color,
144157
backgroundLineNumber: background?.lineNumber,
145158
backgroundSourceIndex: background?.sourceIndex,
146-
barDepth: mergeDecorationDepth(first.barDepth, second.barDepth),
159+
barDepth: topBarDepth,
147160
barLayers,
148161
backgroundDepth: mergeDecorationDepth(
149162
first.backgroundDepth,
@@ -155,6 +168,8 @@ export function mergeNormalizedLineDecorations(
155168
function getLineDecorationBarProperties(
156169
decorations: NormalizedLineDecorations | undefined
157170
): Properties | undefined {
171+
const topmostBarEndIndices = getTopmostBarEndIndices(decorations);
172+
158173
return mergeHastProperties(
159174
mergeHastProperties(
160175
getLineDecorationProperties(
@@ -173,42 +188,45 @@ function getLineDecorationBarProperties(
173188
'data-decoration-bar-start',
174189
decorations?.startIndices,
175190
'data-decoration-bar-end',
176-
decorations?.endIndices
191+
topmostBarEndIndices
177192
)
178193
);
179194
}
180195

181-
function getLineDecorationBarStackStyle(barLayers: VisibleBarLayer[]): string {
182-
const serializedLayers = [...barLayers].reverse();
183-
const styles = [
184-
`--diffs-decoration-bar-layer-count:${serializedLayers.length};`,
185-
];
186-
187-
for (const [index, layer] of serializedLayers.entries()) {
188-
const layerNumber = index + 1;
189-
styles.push(`--diffs-decoration-bar-color-${layerNumber}:${layer.color};`);
190-
styles.push(
191-
`--diffs-decoration-bar-tier-${layerNumber}:${getBarVisualTier(layerNumber)};`
192-
);
193-
styles.push(
194-
`--diffs-decoration-bar-start-cap-${layerNumber}:${layer.showStartCap ? 1 : 0};`
195-
);
196-
styles.push(
197-
`--diffs-decoration-bar-end-cap-${layerNumber}:${layer.showEndCap ? 1 : 0};`
198-
);
196+
function getTopmostBarEndIndices(
197+
decorations: NormalizedLineDecorations | undefined
198+
): number[] | undefined {
199+
const topmostBarSourceIndex = decorations?.barSourceIndex;
200+
if (topmostBarSourceIndex == null) {
201+
return undefined;
199202
}
200203

201-
return styles.join('');
204+
return (decorations?.endIndices?.includes(topmostBarSourceIndex) ?? false)
205+
? [topmostBarSourceIndex]
206+
: undefined;
202207
}
203208

204-
function getBarVisualTier(layerNumber: number): 1 | 2 | 3 {
205-
if (layerNumber <= 1) {
206-
return 1;
207-
}
208-
if (layerNumber === 2) {
209-
return 2;
209+
// When adjacent visible layers share the same bar color, render them as one
210+
// continuous visual bar so overlap identity does not create artificial gaps.
211+
function collapseBarLayersForRendering(
212+
barLayers: VisibleBarLayer[]
213+
): VisibleBarLayer[] {
214+
const serializedLayers = [...barLayers].reverse();
215+
const collapsed: VisibleBarLayer[] = [];
216+
217+
for (const layer of serializedLayers) {
218+
const previousLayer = collapsed.at(-1);
219+
if (previousLayer?.color !== layer.color) {
220+
collapsed.push({ ...layer });
221+
continue;
222+
}
223+
224+
previousLayer.showStartCap =
225+
previousLayer.showStartCap && layer.showStartCap;
226+
previousLayer.showEndCap = previousLayer.showEndCap && layer.showEndCap;
210227
}
211-
return 3;
228+
229+
return collapsed.reverse();
212230
}
213231

214232
function getLineDecorationProperties(

packages/diffs/src/utils/normalizeLineDecorations.ts

Lines changed: 77 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -151,6 +151,7 @@ export function normalizeFileDecorations<Metadata>(
151151
for (const [sourceIndex, decoration] of decorations.entries()) {
152152
applyDecorationRange(normalized, decoration, sourceIndex);
153153
}
154+
finalizeBarDepths(normalized);
154155
return normalized;
155156
}
156157

@@ -164,6 +165,8 @@ export function normalizeDiffDecorations<Metadata>(
164165
for (const [sourceIndex, decoration] of decorations.entries()) {
165166
applyDecorationRange(normalized[decoration.side], decoration, sourceIndex);
166167
}
168+
finalizeBarDepths(normalized.additions);
169+
finalizeBarDepths(normalized.deletions);
167170
return normalized;
168171
}
169172

@@ -401,6 +404,80 @@ function cloneVisibleBarLayer(layer: VisibleBarLayer): VisibleBarLayer {
401404
return { ...layer };
402405
}
403406

407+
function finalizeBarDepths(map: NormalizedLineDecorationMap): void {
408+
const priorityBySourceIndex = new Map<
409+
number,
410+
{ lineNumber: number; sourceIndex: number }
411+
>();
412+
const higherNeighborsBySourceIndex = new Map<number, Set<number>>();
413+
414+
for (const lineDecorations of Object.values(map)) {
415+
const barLayers = lineDecorations?.barLayers;
416+
if (barLayers == null || barLayers.length === 0) {
417+
continue;
418+
}
419+
420+
for (const layer of barLayers) {
421+
if (!priorityBySourceIndex.has(layer.sourceIndex)) {
422+
priorityBySourceIndex.set(layer.sourceIndex, {
423+
lineNumber: layer.lineNumber,
424+
sourceIndex: layer.sourceIndex,
425+
});
426+
}
427+
}
428+
429+
for (let index = 0; index < barLayers.length - 1; index++) {
430+
const lowerLayer = barLayers[index];
431+
const higherLayer = barLayers[index + 1];
432+
if (lowerLayer == null || higherLayer == null) {
433+
continue;
434+
}
435+
436+
const higherNeighbors =
437+
higherNeighborsBySourceIndex.get(lowerLayer.sourceIndex) ?? new Set();
438+
higherNeighborsBySourceIndex.set(
439+
lowerLayer.sourceIndex,
440+
higherNeighbors
441+
);
442+
higherNeighbors.add(higherLayer.sourceIndex);
443+
}
444+
}
445+
446+
const coveredDepthBySourceIndex = new Map<number, number>();
447+
const sortedSourceIndices = [...priorityBySourceIndex.values()]
448+
.sort((first, second) => compareDecorationPriority(second, first))
449+
.map(({ sourceIndex }) => sourceIndex);
450+
451+
for (const sourceIndex of sortedSourceIndices) {
452+
const higherNeighbors = higherNeighborsBySourceIndex.get(sourceIndex);
453+
if (higherNeighbors == null || higherNeighbors.size === 0) {
454+
coveredDepthBySourceIndex.set(sourceIndex, 0);
455+
continue;
456+
}
457+
458+
let maxCoveredDepth = 0;
459+
for (const higherSourceIndex of higherNeighbors) {
460+
const higherCoveredDepth = coveredDepthBySourceIndex.get(higherSourceIndex) ?? 0;
461+
if (higherCoveredDepth + 1 > maxCoveredDepth) {
462+
maxCoveredDepth = higherCoveredDepth + 1;
463+
}
464+
}
465+
466+
coveredDepthBySourceIndex.set(sourceIndex, maxCoveredDepth);
467+
}
468+
469+
for (const lineDecorations of Object.values(map)) {
470+
const topBarSourceIndex = lineDecorations?.barSourceIndex;
471+
if (topBarSourceIndex == null || lineDecorations == null) {
472+
continue;
473+
}
474+
475+
const coveredCount = coveredDepthBySourceIndex.get(topBarSourceIndex) ?? 0;
476+
lineDecorations.barDepth =
477+
coveredCount > 0 ? getDecorationDepth(coveredCount) : undefined;
478+
}
479+
}
480+
404481
function incrementDecorationDepth(
405482
current: DecorationOverlapDepth | undefined
406483
): DecorationOverlapDepth {

0 commit comments

Comments
 (0)