@@ -11,6 +11,9 @@ import type { DiffRow, RenderSpan, SplitLineCell, StackLineCell } from "./pierre
1111import {
1212 diffRailMarker ,
1313 dimRailColor ,
14+ EMPTY_CELL_HATCH_GLYPH ,
15+ emptyHatchBg ,
16+ emptyHatchColor ,
1417 neutralRailColor ,
1518 selectionHighlightBg ,
1619 splitCellPalette ,
@@ -849,6 +852,23 @@ function applySelectionPrefix<P extends { bg: string }>(prefix: P, theme: AppThe
849852 } ;
850853}
851854
855+ /**
856+ * Render the diagonal-hatch content for a split cell that has no line on this side.
857+ *
858+ * Returns a single fixed-width span of {@link EMPTY_CELL_HATCH_GLYPH} so an absent region reads as
859+ * "nothing here" without painting a flat filler background.
860+ */
861+ function renderEmptyHatch ( width : number , theme : AppTheme , keyPrefix : string ) {
862+ if ( width <= 0 ) {
863+ return null ;
864+ }
865+ return (
866+ < span key = { `${ keyPrefix } :hatch` } fg = { emptyHatchColor ( theme ) } bg = { emptyHatchBg ( theme ) } >
867+ { EMPTY_CELL_HATCH_GLYPH . repeat ( width ) }
868+ </ span >
869+ ) ;
870+ }
871+
852872/** Render one split-view cell as prefix + gutter + content spans. */
853873function renderSplitCell (
854874 cell : SplitLineCell ,
@@ -902,16 +922,18 @@ function renderSplitCell(
902922 < span key = { `${ keyPrefix } :gutter` } fg = { palette . numberColor } bg = { palette . gutterBg } >
903923 { gutterText }
904924 </ span >
905- { renderInlineSpans (
906- cell . spans ,
907- contentWidth ,
908- theme . syntaxColors . default ,
909- palette . contentBg ,
910- `${ keyPrefix } :content` ,
911- contentOffset ,
912- selected ? theme : undefined ,
913- localColRange ,
914- ) }
925+ { cell . kind === "empty"
926+ ? renderEmptyHatch ( contentWidth , theme , `${ keyPrefix } :content` )
927+ : renderInlineSpans (
928+ cell . spans ,
929+ contentWidth ,
930+ theme . syntaxColors . default ,
931+ palette . contentBg ,
932+ `${ keyPrefix } :content` ,
933+ contentOffset ,
934+ selected ? theme : undefined ,
935+ localColRange ,
936+ ) }
915937 </ >
916938 ) ;
917939}
@@ -996,6 +1018,7 @@ function renderWrappedSplitCellLine(
9961018 selected = false ,
9971019 selectionColRange ?: CopySelectedRowRange ,
9981020 paneOffset = 0 ,
1021+ isEmptyCell = false ,
9991022) {
10001023 const resolvedPalette = selected ? applySelectionPalette ( palette , theme ) : palette ;
10011024 const resolvedPrefix = selected ? applySelectionPrefix ( prefix , theme ) : prefix ;
@@ -1026,16 +1049,18 @@ function renderWrappedSplitCellLine(
10261049 >
10271050 { line . gutterText }
10281051 </ span >
1029- { renderInlineSpans (
1030- line . spans ,
1031- contentWidth ,
1032- theme . syntaxColors . default ,
1033- resolvedPalette . contentBg ,
1034- `${ keyPrefix } :content` ,
1035- 0 ,
1036- selected ? theme : undefined ,
1037- localColRange ,
1038- ) }
1052+ { isEmptyCell
1053+ ? renderEmptyHatch ( contentWidth , theme , `${ keyPrefix } :content` )
1054+ : renderInlineSpans (
1055+ line . spans ,
1056+ contentWidth ,
1057+ theme . syntaxColors . default ,
1058+ resolvedPalette . contentBg ,
1059+ `${ keyPrefix } :content` ,
1060+ 0 ,
1061+ selected ? theme : undefined ,
1062+ localColRange ,
1063+ ) }
10391064 </ >
10401065 ) ;
10411066}
@@ -1549,6 +1574,7 @@ function renderRow(
15491574 hasLeftSelection ,
15501575 hasLeftSelection ? copySelectedRowRange : undefined ,
15511576 0 ,
1577+ row . left . kind === "empty" ,
15521578 ) }
15531579 { renderWrappedSplitCellLine (
15541580 rightLine ,
@@ -1560,6 +1586,7 @@ function renderRow(
15601586 hasRightSelection ,
15611587 hasRightSelection ? copySelectedRowRange : undefined ,
15621588 leftWidth ,
1589+ row . right . kind === "empty" ,
15631590 ) }
15641591 { guideOnNewSide ? (
15651592 < span key = { `${ row . key } :note-guide:${ index } ` } fg = { theme . noteBorder } >
0 commit comments