Skip to content

Commit a01c563

Browse files
support extend render for cli component
1 parent a0b43cd commit a01c563

File tree

9 files changed

+548
-162
lines changed

9 files changed

+548
-162
lines changed
Lines changed: 122 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,122 @@
1+
import { Box, Text } from "ink";
2+
import * as React from "react";
3+
4+
import { SplitSide } from "..";
5+
6+
import { diffEmptyContent } from "./color";
7+
import { useDiffViewContext } from "./DiffViewContext";
8+
9+
import type { DiffFile } from "@git-diff-view/core";
10+
11+
const InternalDiffSplitExtendLine = ({
12+
index,
13+
columns,
14+
theme,
15+
diffFile,
16+
lineNumber,
17+
oldLineExtend,
18+
newLineExtend,
19+
}: {
20+
index: number;
21+
columns: number;
22+
theme: "light" | "dark";
23+
diffFile: DiffFile;
24+
lineNumber: number;
25+
oldLineExtend: { data: any };
26+
newLineExtend: { data: any };
27+
}) => {
28+
const { useDiffContext } = useDiffViewContext();
29+
30+
const oldLine = diffFile.getSplitLeftLine(index);
31+
32+
const newLine = diffFile.getSplitRightLine(index);
33+
34+
// 需要显示的时候才进行方法订阅,可以大幅度提高性能
35+
const renderExtendLine = useDiffContext.useShallowStableSelector((s) => s.renderExtendLine);
36+
37+
if (!renderExtendLine) return null;
38+
39+
const oldExtendRendered =
40+
oldLineExtend?.data &&
41+
renderExtendLine?.({
42+
diffFile,
43+
side: SplitSide.old,
44+
lineNumber: oldLine.lineNumber,
45+
data: oldLineExtend.data,
46+
onUpdate: diffFile.notifyAll,
47+
});
48+
49+
const newExtendRendered =
50+
newLineExtend?.data &&
51+
renderExtendLine?.({
52+
diffFile,
53+
side: SplitSide.new,
54+
lineNumber: newLine.lineNumber,
55+
data: newLineExtend.data,
56+
onUpdate: diffFile.notifyAll,
57+
});
58+
59+
const bgColor = theme === "light" ? diffEmptyContent.light : diffEmptyContent.dark;
60+
61+
return (
62+
<Box data-line={`${lineNumber}-extend`} data-state="extend">
63+
<Box width={columns / 2} flexShrink={0} flexGrow={0} backgroundColor={oldExtendRendered ? undefined : bgColor}>
64+
{React.isValidElement(oldExtendRendered) ? oldExtendRendered : <Text>{oldExtendRendered}</Text>}
65+
</Box>
66+
<Box width={columns / 2} flexShrink={0} flexGrow={0} backgroundColor={newExtendRendered ? undefined : bgColor}>
67+
{React.isValidElement(newExtendRendered) ? newExtendRendered : <Text>{newExtendRendered}</Text>}
68+
</Box>
69+
</Box>
70+
);
71+
};
72+
73+
export const DiffSplitExtendLine = ({
74+
index,
75+
columns,
76+
theme,
77+
diffFile,
78+
lineNumber,
79+
}: {
80+
index: number;
81+
columns: number;
82+
theme: "light" | "dark";
83+
diffFile: DiffFile;
84+
lineNumber: number;
85+
}) => {
86+
const { useDiffContext } = useDiffViewContext();
87+
88+
const oldLine = diffFile.getSplitLeftLine(index);
89+
90+
const newLine = diffFile.getSplitRightLine(index);
91+
92+
const { oldLineExtend, newLineExtend } = useDiffContext(
93+
React.useCallback(
94+
(s) => ({
95+
oldLineExtend: s.extendData?.oldFile?.[oldLine?.lineNumber],
96+
newLineExtend: s.extendData?.newFile?.[newLine?.lineNumber],
97+
}),
98+
[oldLine?.lineNumber, newLine?.lineNumber]
99+
)
100+
);
101+
102+
const hasExtend = oldLineExtend?.data || newLineExtend?.data;
103+
104+
// if the expand action not enabled, the `isHidden` property will never change
105+
const enableExpand = diffFile.getExpandEnabled();
106+
107+
const currentIsShow = hasExtend && ((!oldLine?.isHidden && !newLine?.isHidden) || !enableExpand);
108+
109+
if (!currentIsShow) return null;
110+
111+
return (
112+
<InternalDiffSplitExtendLine
113+
index={index}
114+
theme={theme}
115+
columns={columns}
116+
diffFile={diffFile}
117+
lineNumber={lineNumber}
118+
oldLineExtend={oldLineExtend}
119+
newLineExtend={newLineExtend}
120+
/>
121+
);
122+
};

packages/cli/src/components/DiffSplitView.tsx

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ import { useSyncExternalStore } from "use-sync-external-store/shim/index.js";
66
import { useTerminalSize } from "../hooks/useTerminalSize";
77

88
import { DiffSplitContentLine } from "./DiffSplitContentLine";
9+
import { DiffSplitExtendLine } from "./DiffSplitExtendLine";
910
import { DiffSplitHunkLine } from "./DiffSplitHunkLine";
1011
import { useDiffViewContext } from "./DiffViewContext";
1112

@@ -49,6 +50,13 @@ export const DiffSplitView = memo(({ diffFile }: { diffFile: DiffFile }) => {
4950
lineNumber={line.lineNumber}
5051
enableHighlight={enableHighlight}
5152
/>
53+
<DiffSplitExtendLine
54+
theme={theme}
55+
columns={columns}
56+
index={line.index}
57+
diffFile={diffFile}
58+
lineNumber={line.lineNumber}
59+
/>
5260
</Fragment>
5361
))}
5462
<DiffSplitHunkLine
Lines changed: 115 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,115 @@
1+
import { Box, Text } from "ink";
2+
import * as React from "react";
3+
import { useCallback } from "react";
4+
5+
import { SplitSide } from "..";
6+
7+
import { useDiffViewContext } from "./DiffViewContext";
8+
9+
import type { DiffFile } from "@git-diff-view/core";
10+
11+
const InternalDiffUnifiedExtendLine = ({
12+
index,
13+
columns,
14+
diffFile,
15+
lineNumber,
16+
oldLineExtend,
17+
newLineExtend,
18+
}: {
19+
index: number;
20+
columns: number;
21+
diffFile: DiffFile;
22+
lineNumber: number;
23+
theme: "light" | "dark";
24+
oldLineExtend: { data: any };
25+
newLineExtend: { data: any };
26+
}) => {
27+
const { useDiffContext } = useDiffViewContext();
28+
29+
const renderExtendLine = useDiffContext.useShallowStableSelector((s) => s.renderExtendLine);
30+
31+
const unifiedItem = diffFile.getUnifiedLine(index);
32+
33+
if (!renderExtendLine) return null;
34+
35+
const oldExtendRendered =
36+
oldLineExtend?.data !== null &&
37+
oldLineExtend?.data !== undefined &&
38+
renderExtendLine?.({
39+
diffFile,
40+
side: SplitSide.old,
41+
lineNumber: unifiedItem.oldLineNumber,
42+
data: oldLineExtend.data,
43+
onUpdate: diffFile.notifyAll,
44+
});
45+
46+
const newExtendRendered =
47+
newLineExtend?.data !== null &&
48+
newLineExtend?.data !== undefined &&
49+
renderExtendLine?.({
50+
diffFile,
51+
side: SplitSide.new,
52+
lineNumber: unifiedItem.newLineNumber,
53+
data: newLineExtend.data,
54+
onUpdate: diffFile.notifyAll,
55+
});
56+
57+
return (
58+
<Box data-line={`${lineNumber}-extend`} data-state="extend" width={columns}>
59+
{oldExtendRendered && (
60+
<Box width={columns} flexShrink={0} flexGrow={0}>
61+
{!React.isValidElement(oldExtendRendered) ? <Text>{oldExtendRendered}</Text> : oldExtendRendered}
62+
</Box>
63+
)}
64+
{newExtendRendered && (
65+
<Box width={columns} flexShrink={0} flexGrow={0}>
66+
{!React.isValidElement(newExtendRendered) ? <Text>{newExtendRendered}</Text> : newExtendRendered}
67+
</Box>
68+
)}
69+
</Box>
70+
);
71+
};
72+
73+
export const DiffUnifiedExtendLine = ({
74+
index,
75+
theme,
76+
columns,
77+
diffFile,
78+
lineNumber,
79+
}: {
80+
index: number;
81+
columns: number;
82+
theme: "light" | "dark";
83+
diffFile: DiffFile;
84+
lineNumber: number;
85+
}) => {
86+
const { useDiffContext } = useDiffViewContext();
87+
88+
const unifiedItem = diffFile.getUnifiedLine(index);
89+
90+
const { oldLineExtend, newLineExtend } = useDiffContext(
91+
useCallback(
92+
(s) => ({
93+
oldLineExtend: s.extendData?.oldFile?.[unifiedItem?.oldLineNumber],
94+
newLineExtend: s.extendData?.newFile?.[unifiedItem?.newLineNumber],
95+
}),
96+
[unifiedItem.oldLineNumber, unifiedItem.newLineNumber]
97+
)
98+
);
99+
100+
const hasExtend = oldLineExtend?.data || newLineExtend?.data;
101+
102+
if (!hasExtend || !unifiedItem || unifiedItem.isHidden) return null;
103+
104+
return (
105+
<InternalDiffUnifiedExtendLine
106+
index={index}
107+
theme={theme}
108+
columns={columns}
109+
diffFile={diffFile}
110+
lineNumber={lineNumber}
111+
oldLineExtend={oldLineExtend}
112+
newLineExtend={newLineExtend}
113+
/>
114+
);
115+
};

packages/cli/src/components/DiffUnifiedView.tsx

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ import { useSyncExternalStore } from "use-sync-external-store/shim/index.js";
77
import { useTerminalSize } from "../hooks/useTerminalSize";
88

99
import { DiffUnifiedContentLine } from "./DiffUnifiedContentLine";
10+
import { DiffUnifiedExtendLine } from "./DiffUnifiedExtendLine";
1011
import { DiffUnifiedHunkLine } from "./DiffUnifiedHunkLine";
1112
import { useDiffViewContext } from "./DiffViewContext";
1213

@@ -52,6 +53,13 @@ export const DiffUnifiedView = memo(({ diffFile }: { diffFile: DiffFile }) => {
5253
lineNumber={item.lineNumber}
5354
enableHighlight={enableHighlight}
5455
/>
56+
<DiffUnifiedExtendLine
57+
index={item.index}
58+
theme={theme}
59+
columns={columns}
60+
diffFile={diffFile}
61+
lineNumber={item.lineNumber}
62+
/>
5563
</Fragment>
5664
))}
5765
<DiffUnifiedHunkLine

0 commit comments

Comments
 (0)