Skip to content

Commit 2ae9550

Browse files
committed
Use git-like path sorting in Changes list
1 parent 5a1b464 commit 2ae9550

File tree

2 files changed

+55
-2
lines changed

2 files changed

+55
-2
lines changed

packages/ui/src/components/layout/RightPanel.test.tsx

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -196,4 +196,54 @@ describe('RightPanel - Zed-style Changes list', () => {
196196
expect((API.sessions.getDiff as any).mock.calls.length).toBeGreaterThan(1);
197197
});
198198
});
199+
200+
it('sorts paths in a git-like (codepoint) order', async () => {
201+
(API.sessions.getDiff as any).mockResolvedValue({
202+
success: true,
203+
data: {
204+
workingTree: {
205+
staged: [
206+
{ path: '_config.yml', type: 'modified', additions: 3, deletions: 2 },
207+
],
208+
unstaged: [
209+
{ path: '.github/workflows/pages.yml', type: 'modified', additions: 11, deletions: 5 },
210+
{ path: 'package.json', type: 'modified', additions: 4, deletions: 1 },
211+
{ path: 'source/about/index.md', type: 'modified', additions: 3, deletions: 2 },
212+
],
213+
untracked: [
214+
{ path: 'dd.txt', type: 'added', additions: 6, deletions: 0 },
215+
{ path: 'WORKTREE_TEST.md', type: 'added', additions: 29, deletions: 0 },
216+
],
217+
},
218+
},
219+
});
220+
221+
const { container } = render(<RightPanel {...mockProps} />);
222+
223+
await waitFor(() => {
224+
expect(screen.getByTestId('right-panel-file-tracked-_config.yml')).toBeInTheDocument();
225+
expect(screen.getByTestId('right-panel-file-tracked-.github/workflows/pages.yml')).toBeInTheDocument();
226+
});
227+
228+
const trackedEls = Array.from(
229+
container.querySelectorAll('button[data-testid^="right-panel-file-tracked-"]')
230+
).filter((el) => !el.getAttribute('data-testid')?.endsWith('-checkbox'));
231+
232+
const trackedOrder = trackedEls.map((el) => el.getAttribute('data-testid'));
233+
expect(trackedOrder).toEqual([
234+
'right-panel-file-tracked-.github/workflows/pages.yml',
235+
'right-panel-file-tracked-_config.yml',
236+
'right-panel-file-tracked-package.json',
237+
'right-panel-file-tracked-source/about/index.md',
238+
]);
239+
240+
const untrackedEls = Array.from(
241+
container.querySelectorAll('button[data-testid^="right-panel-file-untracked-"]')
242+
).filter((el) => !el.getAttribute('data-testid')?.endsWith('-checkbox'));
243+
const untrackedOrder = untrackedEls.map((el) => el.getAttribute('data-testid'));
244+
expect(untrackedOrder).toEqual([
245+
'right-panel-file-untracked-WORKTREE_TEST.md',
246+
'right-panel-file-untracked-dd.txt',
247+
]);
248+
});
199249
});

packages/ui/src/components/layout/RightPanel.tsx

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -90,6 +90,9 @@ const StackConnector: React.FC<{ accent?: boolean }> = React.memo(({ accent }) =
9090

9191
StackConnector.displayName = 'StackConnector';
9292

93+
// Zed/Git-like ordering: locale-independent, matches git path sorting.
94+
const compareGitPaths = (a: string, b: string) => (a === b ? 0 : a < b ? -1 : 1);
95+
9396
interface Commit {
9497
id: number;
9598
commit_message: string;
@@ -891,7 +894,7 @@ export const RightPanel: React.FC<RightPanelProps> = React.memo(({
891894
merged.push({ file: { path, type, additions, deletions, isNew }, stageState });
892895
}
893896

894-
merged.sort((a, b) => a.file.path.localeCompare(b.file.path));
897+
merged.sort((a, b) => compareGitPaths(a.file.path, b.file.path));
895898
return merged;
896899
}, [workingTree]);
897900

@@ -908,7 +911,7 @@ export const RightPanel: React.FC<RightPanelProps> = React.memo(({
908911
byPath.set(x.file.path, x);
909912
}
910913

911-
const merged = Array.from(byPath.values()).sort((a, b) => a.file.path.localeCompare(b.file.path));
914+
const merged = Array.from(byPath.values()).sort((a, b) => compareGitPaths(a.file.path, b.file.path));
912915
return merged;
913916
}, [trackedFiles, workingTree]);
914917

0 commit comments

Comments
 (0)