diff --git a/README.md b/README.md index 0963aeb..3bbb894 100644 --- a/README.md +++ b/README.md @@ -55,6 +55,16 @@ You can disable this with the `highlight-line-changes` setting: git config split-diffs.highlight-line-changes false ``` +### Unified diffs for one-sided files + +A file that only has additions, or only has deletions, leaves one half of a split diff empty. To show such files as unified diffs, and keep split diffs for files that have both, enable the `unify-one-sided-diffs` setting: + +``` +git config split-diffs.unify-one-sided-diffs true +``` + +This decides per file rather than per hunk, so each file's hunks are held back until the whole file has been read. + ### Enable scrolling in the terminal ```sh diff --git a/src/__snapshots__/index.test.ts.snap b/src/__snapshots__/index.test.ts.snap index 8049f4c..39cf995 100644 --- a/src/__snapshots__/index.test.ts.snap +++ b/src/__snapshots__/index.test.ts.snap @@ -215,6 +215,48 @@ Date: Sun Apr 4 19:04:26 2021 -0700 " `; +exports[`inlineChangesHighlighted commit with one-sided and two-sided files 1`] = ` +" +commit 1111111111111111111111111111111111111111 +Author: Shrey Banga +Date: Sun Apr 11 15:25:34 2021 -0700 + + Mix of changes + +──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────── + ■■ added.md +──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────── +@@ -1,2 +1,3 @@ + 1 first 1 first + 2 + inserted + 2 second 3 second +@@ -10,2 +11,3 @@ + 10 tenth 11 tenth + 12 + another insert + 11 eleventh 13 eleventh +──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────── + ■■ mixed.md +──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────── +@@ -1,3 +1,3 @@ + 1 first 1 first + 2 + only inserted in this hunk + 2 second 3 second + 3 - third +@@ -10,3 +10,2 @@ + 10 tenth 10 tenth + 11 - only deleted in this hunk + 11 eleventh 11 eleventh +──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────── + ■■ deleted.md +──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────── +@@ -1,3 +1,2 @@ + 1 first 1 first + 2 - removed + 2 second 2 second + 3 3 +" +`; + exports[`inlineChangesHighlighted commit with tabs 1`] = ` " commit f735de7025c6d626c5ae1a291fe24f143dea0313 @@ -672,6 +714,48 @@ Date: Sun Apr 4 19:04:26 2021 -0700 " `; +exports[`splitWithWrapping commit with one-sided and two-sided files 1`] = ` +" +commit 1111111111111111111111111111111111111111 +Author: Shrey Banga +Date: Sun Apr 11 15:25:34 2021 -0700 + + Mix of changes + +──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────── + ■■ added.md +──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────── +@@ -1,2 +1,3 @@ + 1 first 1 first + 2 + inserted + 2 second 3 second +@@ -10,2 +11,3 @@ + 10 tenth 11 tenth + 12 + another insert + 11 eleventh 13 eleventh +──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────── + ■■ mixed.md +──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────── +@@ -1,3 +1,3 @@ + 1 first 1 first + 2 + only inserted in this hunk + 2 second 3 second + 3 - third +@@ -10,3 +10,2 @@ + 10 tenth 10 tenth + 11 - only deleted in this hunk + 11 eleventh 11 eleventh +──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────── + ■■ deleted.md +──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────── +@@ -1,3 +1,2 @@ + 1 first 1 first + 2 - removed + 2 second 2 second + 3 3 +" +`; + exports[`splitWithWrapping commit with tabs 1`] = ` " commit f735de7025c6d626c5ae1a291fe24f143dea0313 @@ -1178,6 +1262,48 @@ Date: Sun Apr 4 19:04:26 2021 -0700 " `; +exports[`splitWithoutWrapping commit with one-sided and two-sided files 1`] = ` +" +commit 1111111111111111111111111111111111111111 +Author: Shrey Banga +Date: Sun Apr 11 15:25:34 2021 -0700 + + Mix of changes + +──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────── + ■■ added.md +──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────── +@@ -1,2 +1,3 @@ + 1 first 1 first + 2 + inserted + 2 second 3 second +@@ -10,2 +11,3 @@ + 10 tenth 11 tenth + 12 + another insert + 11 eleventh 13 eleventh +──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────── + ■■ mixed.md +──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────── +@@ -1,3 +1,3 @@ + 1 first 1 first + 2 + only inserted in this hunk + 2 second 3 second + 3 - third +@@ -10,3 +10,2 @@ + 10 tenth 10 tenth + 11 - only deleted in this hunk + 11 eleventh 11 eleventh +──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────── + ■■ deleted.md +──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────── +@@ -1,3 +1,2 @@ + 1 first 1 first + 2 - removed + 2 second 2 second + 3 3 +" +`; + exports[`splitWithoutWrapping commit with tabs 1`] = ` " commit f735de7025c6d626c5ae1a291fe24f143dea0313 @@ -1633,6 +1759,48 @@ Date: Sun Apr 4 19:04:26 2021 -0700 " `; +exports[`syntaxHighlighted commit with one-sided and two-sided files 1`] = ` +" +commit 1111111111111111111111111111111111111111 +Author: Shrey Banga +Date: Sun Apr 11 15:25:34 2021 -0700 + + Mix of changes + +──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────── + ■■ added.md +──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────── +@@ -1,2 +1,3 @@ + 1 ░░░░░ 1 ░░░░░ + 2 + ░░░░░░░░ + 2 ░░░░░░ 3 ░░░░░░ +@@ -10,2 +11,3 @@ + 10 ░░░░░ 11 ░░░░░ + 12 + ░░░░░░░░░░░░░░ + 11 ░░░░░░░░ 13 ░░░░░░░░ +──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────── + ■■ mixed.md +──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────── +@@ -1,3 +1,3 @@ + 1 ░░░░░ 1 ░░░░░ + 2 + ░░░░░░░░░░░░░░░░░░░░░░░░░░ + 2 ░░░░░░ 3 ░░░░░░ + 3 - ░░░░░ +@@ -10,3 +10,2 @@ + 10 ░░░░░ 10 ░░░░░ + 11 - ░░░░░░░░░░░░░░░░░░░░░░░░░ + 11 ░░░░░░░░ 11 ░░░░░░░░ +──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────── + ■■ deleted.md +──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────── +@@ -1,3 +1,2 @@ + 1 ░░░░░ 1 ░░░░░ + 2 - ░░░░░░░ + 2 ░░░░░░ 2 ░░░░░░ + 3 3 +" +`; + exports[`syntaxHighlighted commit with tabs 1`] = ` " commit f735de7025c6d626c5ae1a291fe24f143dea0313 @@ -2097,6 +2265,48 @@ Date: Sun Apr 4 19:04:26 2021 -0700 " `; +exports[`unifiedWithInlineChangesHighlighted commit with one-sided and two-sided files 1`] = ` +" +commit 1111111111111111111111111111111111111111 +Author: Shrey Banga +Date: Sun Apr 11 15:25:34 2021 -0700 + + Mix of changes + +──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────── + ■■ added.md +──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────── +@@ -1,2 +1,3 @@ + 1 first + 2 + inserted + 2 second +@@ -10,2 +11,3 @@ + 10 tenth + 12 + another insert + 11 eleventh +──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────── + ■■ mixed.md +──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────── +@@ -1,3 +1,3 @@ + 1 first + 2 + only inserted in this hunk + 2 second + 3 - third +@@ -10,3 +10,2 @@ + 10 tenth + 11 - only deleted in this hunk + 12 eleventh +──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────── + ■■ deleted.md +──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────── +@@ -1,3 +1,2 @@ + 1 first + 2 - removed + 3 second + 4 +" +`; + exports[`unifiedWithInlineChangesHighlighted commit with tabs 1`] = ` " commit f735de7025c6d626c5ae1a291fe24f143dea0313 @@ -2567,6 +2777,48 @@ Date: Sun Apr 4 19:04:26 2021 -0700 " `; +exports[`unifiedWithWrapping commit with one-sided and two-sided files 1`] = ` +" +commit 1111111111111111111111111111111111111111 +Author: Shrey Banga +Date: Sun Apr 11 15:25:34 2021 -0700 + + Mix of changes + +──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────── + ■■ added.md +──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────── +@@ -1,2 +1,3 @@ + 1 first + 2 + inserted + 2 second +@@ -10,2 +11,3 @@ + 10 tenth + 12 + another insert + 11 eleventh +──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────── + ■■ mixed.md +──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────── +@@ -1,3 +1,3 @@ + 1 first + 2 + only inserted in this hunk + 2 second + 3 - third +@@ -10,3 +10,2 @@ + 10 tenth + 11 - only deleted in this hunk + 12 eleventh +──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────── + ■■ deleted.md +──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────── +@@ -1,3 +1,2 @@ + 1 first + 2 - removed + 3 second + 4 +" +`; + exports[`unifiedWithWrapping commit with tabs 1`] = ` " commit f735de7025c6d626c5ae1a291fe24f143dea0313 @@ -2812,3 +3064,500 @@ Date: Sun Apr 11 15:25:34 2021 -0700 14 " `; + +exports[`unifyOneSidedDiffs commit with a small diff 1`] = ` +" +commit 26ca49fb83758bace20a473e231d576aa1bbe115 +Author: Shrey Banga +Date: Tue May 23 16:47:17 2017 -0700 + + sonos to brew + +──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────── + ■■ Brewfile +──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────── +@@ -19,2 +19,3 @@ brew 'python3' + 19 brew 'socat' 19 brew 'socat' + 20 + brew 'sonos' + 20 brew 'terminal-notifier' 21 brew 'terminal-notifier' +@@ -42,3 +43,2 @@ cask 'rescuetime' + 42 cask 'slate' 43 cask 'slate' + 43 - cask 'sonos' + 43 cask 'spotify' 44 cask 'spotify' +" +`; + +exports[`unifyOneSidedDiffs commit with a small diff without a/ and b/ prefixs 1`] = ` +" +commit 26ca49fb83758bace20a473e231d576aa1bbe115 +Author: Shrey Banga +Date: Tue May 23 16:47:17 2017 -0700 + + sonos to brew + +──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────── + ■■ Brewfile +──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────── +@@ -19,2 +19,3 @@ brew 'python3' + 19 brew 'socat' 19 brew 'socat' + 20 + brew 'sonos' + 20 brew 'terminal-notifier' 21 brew 'terminal-notifier' +@@ -42,3 +43,2 @@ cask 'rescuetime' + 42 cask 'slate' 43 cask 'slate' + 43 - cask 'sonos' + 43 cask 'spotify' 44 cask 'spotify' +" +`; + +exports[`unifyOneSidedDiffs commit with addition 1`] = ` +" +commit f735de7025c6d626c5ae1a291fe24f143dea0313 +Author: Shrey Banga +Date: Sun Apr 11 15:25:34 2021 -0700 + + Add theme support + +──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────── + ■■ todo.md +──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────── +@@ -9,2 +9,3 @@ + 9 - [x] Organize code + 10 + - [x] Move visual config to theme + 10 - [ ] Handle empty diffs + 11 +" +`; + +exports[`unifyOneSidedDiffs commit with binary file addition 1`] = ` +" +commit c0ca4394fd55f1709430414f03db3d04cb9cc72c (HEAD -> main) +Author: Shrey Banga +Date: Wed Apr 14 18:24:29 2021 -0700 + + test binary file addition + +──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────── + ■■ screenshots/default.png +──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────── +──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────── + ■■ test dir a/default.png +──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────── +" +`; + +exports[`unifyOneSidedDiffs commit with deletion 1`] = ` +"commit eccfb5a2b3d76ba53df315f977da74b18d50113e +Author: Shrey Banga +Date: Thu Aug 22 10:07:25 2019 -0700 + + Remove deprecated option + +diff --git a/Code/User/settings.json b/Code/User/settings.json +index a33d267..ae58a01 100644 +--- a/Code/User/settings.json ++++ b/Code/User/settings.json +@@ -26,5 +26,4 @@ + // search + "search.location": "panel", +- "search.usePCRE2": true, + + // telemetry +" +`; + +exports[`unifyOneSidedDiffs commit with double-spaced characters 1`] = ` +" +──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────── + ■■ README.ja-JP.md +──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────── +@@ -4 +4 @@ + 4 - このリポジトリは、MS-DOS v1.25 及び MS-DOS v2.0 のオリジナルのソースコード及びコンパイルされたバイナリを含んでいます。 4 + このリポジトリは、MS-DOS 及び MS-DOS v2.0 のオリジナルのソースコード及びコンパイルされたバイナリを含んでいます。 + 4 5 +" +`; + +exports[`unifyOneSidedDiffs commit with file addition 1`] = ` +" +commit e4951eee3b9a8fa471d01dd64075c5fd44879a26 +Author: Shrey Banga +Date: Sat Apr 10 14:35:42 2021 -0700 + + wip + +──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────── + ■■ .gitignore +──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────── +@@ -0,0 +1,2 @@ + 1 + node_modules/** + 2 + build/** + +" +`; + +exports[`unifyOneSidedDiffs commit with file deletion 1`] = ` +" +commit 1e6ebaccc6fadf3390a749e7aa2cc6372b24325e +Author: Shrey Banga +Date: Sun Apr 18 03:17:05 2021 -0700 + + Update main.yml + +──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────── + ■■ +──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────── +──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────── + ■■ scripts/screenshotTheme +──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────── +@@ -1,7 +0,0 @@ + 1 - on run argv + 2 - with timeout of 5 seconds + 3 - tell app "Terminal" + 4 - open "screenshots.sh" + 5 - end tell + 6 - end timeout + 7 - end run + 8 \\ No newline at end of file +" +`; + +exports[`unifyOneSidedDiffs commit with file move 1`] = ` +" +commit 1c76ed4bb05429741fd4a48896bb84b11bc661f5 +Author: Shrey Banga +Date: Sat Apr 10 22:26:15 2021 -0700 + + Move sample diff files + +──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────── + ■■ colors.diff -> test-data/colors.diff +──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────── +" +`; + +exports[`unifyOneSidedDiffs commit with inline line changes 1`] = ` +" +commit 9e424d329800e945e3003c9e275f80bdef69e591 +Author: Shrey Banga +Date: Sun Apr 4 19:04:26 2021 -0700 + + update lockfile + +──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────── + ■■ Brewfile.lock.json +──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────── +@@ -5 +5 @@ + 5 - "revision": null 5 + "revision": "ee2f8d3ba2976e50ef577d517bf175c94fbbb0dd" +@@ -8 +8 @@ + 8 - "revision": null 8 + "revision": "c4cf96857c050dfa4f65f52109862dc68e55f60a" +@@ -11 +11 @@ + 11 - "revision": null 11 + "revision": "504d4b93aa6eaf4fce1bf17c19f55828ad7229a4" +@@ -16 +16 @@ + 16 - "version": "1.14.2_1", 16 + "version": "1.16.3", +@@ -17,0 +18 @@ + 18 + "rebuild": 0, +@@ -19,0 +21 @@ + 21 + "root_url": "https://homebrew.bintray.com/bottles", +@@ -20,0 +23,8 @@ + 23 + "arm64_big_sur": { + 24 + "url": "https://homebrew.bintray.com/bottles/go-1.16.3.arm64_big_sur.bottle.tar.gz", + 25 + "sha256": "e7c1efdd09e951eb46d01a3200b01e7fa55ce285b75470051be7fef34f4233ce" + 26 + }, + 27 + "big_sur": { + 28 + "url": "https://homebrew.bintray.com/bottles/go-1.16.3.big_sur.bottle.tar.gz", + 29 + "sha256": "ea37f33fd27369612a3e4e6db6adc46db0e8bdf6fac1332bf51bafaa66d43969" + 30 + }, +@@ -22,2 +32,2 @@ + 22 - "url": "https://homebrew.bintray.com/bottles/go-1.14.2_1.catalina.bottle.tar.gz", 32 + "url": "https://homebrew.bintray.com/bottles/go-1.16.3.catalina.bottle.tar.gz", + 23 - "sha256": "15b5623471330edcc681d7f9d57b449660e6d4b98c7f67af67f4991fc75d61fc" 33 + "sha256": "69c28f5e60612801c66e51e93d32068f822b245ab83246cb6cb374572eb59e15" +@@ -26,6 +36,2 @@ + 26 - "url": "https://homebrew.bintray.com/bottles/go-1.14.2_1.mojave.bottle.tar.gz", 36 + "url": "https://homebrew.bintray.com/bottles/go-1.16.3.mojave.bottle.tar.gz", + 27 - "sha256": "fa65e7dabe514e65ae625ed3c84a6bf58df01aceffc6e9aa99752ca8c320ce69" 37 + "sha256": "bf1e90ed1680b8ee1acb49f2f99426c8a8ac3e49efd63c7f3b41e57e7214dd19" + 28 - }, + 29 - "high_sierra": { + 30 - "url": "https://homebrew.bintray.com/bottles/go-1.14.2_1.high_sierra.bottle.tar.gz", + 31 - "sha256": "0997f6f5cda0e3bdb7789a80b53621cb588202ab37fd89bcd269f8dfafd23351" + 26 38 +" +`; + +exports[`unifyOneSidedDiffs commit with one-sided and two-sided files 1`] = ` +" +commit 1111111111111111111111111111111111111111 +Author: Shrey Banga +Date: Sun Apr 11 15:25:34 2021 -0700 + + Mix of changes + +──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────── + ■■ added.md +──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────── +@@ -1,2 +1,3 @@ + 1 first + 2 + inserted + 2 second +@@ -10,2 +11,3 @@ + 10 tenth + 12 + another insert + 11 eleventh +──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────── + ■■ mixed.md +──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────── +@@ -1,3 +1,3 @@ + 1 first 1 first + 2 + only inserted in this hunk + 2 second 3 second + 3 - third +@@ -10,3 +10,2 @@ + 10 tenth 10 tenth + 11 - only deleted in this hunk + 11 eleventh 11 eleventh +──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────── + ■■ deleted.md +──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────── +@@ -1,3 +1,2 @@ + 1 first + 2 - removed + 3 second + 4 +" +`; + +exports[`unifyOneSidedDiffs commit with tabs 1`] = ` +" +commit f735de7025c6d626c5ae1a291fe24f143dea0313 +Author: Shrey Banga +Date: Sun Apr 11 15:25:34 2021 -0700 + + Add theme support + +──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────── + ■■ todo.md +──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────── +@@ -9,2 +9,3 @@ + 9 - [x] Organize code + 10 + - [x] Move visual config to theme + 10 - [ ] Handle empty diffs + 11 +" +`; + +exports[`unifyOneSidedDiffs commits without diffs 1`] = ` +" +commit e5f896655402f8cf2d947c528d45e1d56bbf5717 (HEAD -> main) +Author: Shrey Banga +Date: Sun Apr 11 16:23:54 2021 -0700 + + Small refactor to allow testing end-to-end + +commit b637f38029f4a89c6a3b73b2b84a6a5b9e260730 +Author: Shrey Banga +Date: Sun Apr 11 11:53:02 2021 -0700 + + Organize code + +commit f323143e03af95fee5d38c21238a92ffd4461847 +Author: Shrey Banga +Date: Sun Apr 11 10:39:17 2021 -0700 + + more todos + +" +`; + +exports[`unifyOneSidedDiffs diff from issue #50 1`] = ` +" +──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────── + ■■ file1 +──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────── +@@ -1 +1,2 @@ + 1 - This is file1 + 1 \\ No newline at end of file 1 \\ No newline at end of file + 2 + This is file1 + 3 + Experimental change +──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────── + ■■ file2 +──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────── +@@ -1 +1,2 @@ + 1 + All good + 1 This is file2 +" +`; + +exports[`unifyOneSidedDiffs empty 1`] = ` +" +" +`; + +exports[`unifyOneSidedDiffs merge commit with 2 parents 1`] = ` +" +commit 3f504f4fbc1caf9c10814d48d8897a34f8a34dec +Merge: 2439767601 fbcdb8cf4f +Author: Gabriela Araujo Britto +Date: Thu Dec 21 17:57:42 2023 -0800 + + Merge branch 'main' into gabritto/d2 + +──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────── + ■■ src/compiler/binder.ts +──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────── +@@@ -137,9 -136,9 +137,10 @@@ import + 137 isBlock, 136 isBlock, 137 isBlock, + 138 isBlockOrCatchScoped, 137 isBlockOrCatchScoped, 138 isBlockOrCatchScoped, + 139 IsBlockScopedContainer, 138 IsBlockScopedContainer, 139 IsBlockScopedContainer, + 139 + isBooleanLiteral, 140 + isBooleanLiteral, + 140 isCallExpression, 140 isCallExpression, 141 isCallExpression, + 141 isClassStaticBlockDeclaration, 141 isClassStaticBlockDeclaration, 142 isClassStaticBlockDeclaration, + 142 + isConditionalExpression, 143 + isConditionalExpression, + 143 isConditionalTypeNode, 142 isConditionalTypeNode, 144 isConditionalTypeNode, + 144 IsContainer, 143 IsContainer, 145 IsContainer, + 145 isDeclaration, 144 isDeclaration, 146 isDeclaration, +──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────── + ■■ src/compiler/types.ts +──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────── +@@@ -5985,8 -6063,7 +6063,8 @@@ export interface NodeLinks + 5985 decoratorSignature?: Signature; // Signature for decorator as i 6063 decoratorSignature?: Signature; // Signature for decorator as i 6063 decoratorSignature?: Signature; // Signature for decorator as i + 5986 spreadIndices?: { first: number | undefined, last: number | undefin 6064 spreadIndices?: { first: number | undefined, last: number | undefin 6064 spreadIndices?: { first: number | undefined, last: number | undefin + 5987 parameterInitializerContainsUndefined?: boolean; // True if this is 6065 parameterInitializerContainsUndefined?: boolean; // True if this is 6065 parameterInitializerContainsUndefined?: boolean; // True if this is + 5988 - fakeScopeForSignatureDeclaration?: boolean; // True if this is a fa 6066 - fakeScopeForSignatureDeclaration?: boolean; // True if this is a fa + 5988 + contextualReturnType?: Type; // If the node is a return stat 6066 + contextualReturnType?: Type; // If the node is a return stat + 6066 + fakeScopeForSignatureDeclaration?: "params" | "typeParams"; // If p 6067 + fakeScopeForSignatureDeclaration?: "params" | "typeParams"; // If p + 5989 assertionExpressionType?: Type; // Cached type of the expressio 6067 assertionExpressionType?: Type; // Cached type of the expressio 6068 assertionExpressionType?: Type; // Cached type of the expressio + 5990 } 6068 } 6069 } +" +`; + +exports[`unifyOneSidedDiffs merge commit with 3 parents 1`] = ` +" +commit d6d6a4aedfa78794c1b611c13d2ed1d3a66e1798 +Merge: 0dc976df1e 5f16a48236 3eadbf6c96 +Author: Andy Hanson +Date: Thu Sep 1 12:52:42 2016 -0700 + + Merge branch 'goto_definition_super', remote-tracking branch 'origin' into constructor_references + +──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────── + ■■ src/services/services.ts +──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────── +@@@@ -2788,26 -2792,18 -2788,34 +2792,42 @@@@ namespace ts + 2788 return node && node.parent && node.parent.k 2792 return node && node.parent && node.parent.k 2788 return node && node.parent && node.parent.k 2792 return node && node.parent && node.parent.k + 2789 } 2793 } 2789 } 2793 } + 2790 2794 2790 2794 + 2791 + function climbPastPropertyAccess(node: Node) { 2791 + function climbPastPropertyAccess(node: Node) { 2795 + function climbPastPropertyAccess(node: Node) { + 2792 + return isRightSideOfPropertyAccess(node) ? 2792 + return isRightSideOfPropertyAccess(node) ? 2796 + return isRightSideOfPropertyAccess(node) ? + 2793 + } 2793 + } 2797 + } + 2794 + 2794 + 2798 + + 2795 - function climbPastManyPropertyAccesses(node: No 2799 - function climbPastManyPropertyAccesses(node: No + 2796 - return isRightSideOfPropertyAccess(node) ? 2800 - return isRightSideOfPropertyAccess(node) ? + 2799 + /** Get \`C\` given \`N\` if \`N\` is in the position + 2800 + function tryGetClassExtendingIdentifier(node: N + 2801 + return tryGetClassExtendingExpressionWithTy + 2795 + } 2802 + } + 2796 + 2803 + + 2795 function isCallExpressionTarget(node: Node): bo 2795 function isCallExpressionTarget(node: Node): bo 2797 function isCallExpressionTarget(node: Node): bo 2804 function isCallExpressionTarget(node: Node): bo + 2796 - if (isRightSideOfPropertyAccess(node)) { 2805 - if (isRightSideOfPropertyAccess(node)) { + 2797 - node = node.parent; 2806 - node = node.parent; + 2798 - } 2807 - } + 2798 - node = climbPastPropertyAccess(node); 2808 - node = climbPastPropertyAccess(node); + 2796 - return node && node.parent && node.parent.k 2799 - return node && node.parent && node.parent.k 2809 - return node && node.parent && node.parent.k + 2796 + return isCallOrNewExpressionTarget(node, Sy 2805 + return isCallOrNewExpressionTarget(node, Sy + 2797 } 2796 } 2798 } 2806 } + 2798 2797 2799 2807 + 2799 function isNewExpressionTarget(node: Node): boo 2798 function isNewExpressionTarget(node: Node): boo 2800 function isNewExpressionTarget(node: Node): boo 2808 function isNewExpressionTarget(node: Node): boo + 2799 - if (isRightSideOfPropertyAccess(node)) { 2809 - if (isRightSideOfPropertyAccess(node)) { + 2800 - node = node.parent; 2810 - node = node.parent; + 2801 - } 2811 - } + 2801 - node = climbPastPropertyAccess(node); 2812 - node = climbPastPropertyAccess(node); + 2799 - return node && node.parent && node.parent.k 2802 - return node && node.parent && node.parent.k 2813 - return node && node.parent && node.parent.k + 2800 + return isCallOrNewExpressionTarget(node, Sy 2809 + return isCallOrNewExpressionTarget(node, Sy + 2801 + } 2810 + } + 2802 + 2811 + + 2803 + function isCallOrNewExpressionTarget(node: Node 2812 + function isCallOrNewExpressionTarget(node: Node + 2804 + const target = climbPastPropertyAccess(node 2813 + const target = climbPastPropertyAccess(node + 2805 + return target && target.parent && target.pa 2814 + return target && target.parent && target.pa + 2806 + } 2815 + } + 2807 + 2816 + + 2808 - /** Get \`C\` given \`N\` if \`N\` is in the position 2817 - /** Get \`C\` given \`N\` if \`N\` is in the position + 2809 - function tryGetClassExtendingIdentifier(node: N 2818 - function tryGetClassExtendingIdentifier(node: N + 2810 - return tryGetClassExtendingExpressionWithTy 2819 - return tryGetClassExtendingExpressionWithTy + 2817 + function climbPastManyPropertyAccesses(node: No + 2818 + return isRightSideOfPropertyAccess(node) ? + 2801 + } 2819 + } + 2802 + 2820 + + 2803 + /** Returns a CallLikeExpression where \`node\` i 2821 + /** Returns a CallLikeExpression where \`node\` i + 2804 + function getAncestorCallLikeExpression(node: No 2822 + function getAncestorCallLikeExpression(node: No + 2805 + const target = climbPastManyPropertyAccesse 2823 + const target = climbPastManyPropertyAccesse + 2806 + const callLike = target.parent; 2824 + const callLike = target.parent; + 2807 + return callLike && isCallLikeExpression(cal 2825 + return callLike && isCallLikeExpression(cal + 2808 + } 2826 + } + 2809 + 2827 + + 2810 + function tryGetSignatureDeclaration(typeChecker 2828 + function tryGetSignatureDeclaration(typeChecker + 2811 + const callLike = getAncestorCallLikeExpress 2829 + const callLike = getAncestorCallLikeExpress + 2812 + return callLike && typeChecker.getResolvedS 2830 + return callLike && typeChecker.getResolvedS + 2808 } 2799 } 2813 } 2831 } + 2809 2800 2814 2832 + 2810 function isNameOfModuleDeclaration(node: Node) 2801 function isNameOfModuleDeclaration(node: Node) 2815 function isNameOfModuleDeclaration(node: Node) 2833 function isNameOfModuleDeclaration(node: Node) + 2811 2802 2816 2834 +" +`; + +exports[`unifyOneSidedDiffs multiple inserts and deletes in the same hunk 1`] = ` +" +commit e5f896655402f8cf2d947c528d45e1d56bbf5717 +Author: Shrey Banga +Date: Sun Apr 11 16:23:54 2021 -0700 + + Small refactor to allow testing end-to-end + +──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────── + ■■ src/index.ts +──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────── +@@ -1,5 +1,6 @@ + 1 import chalk from 'chalk'; 1 import chalk from 'chalk'; + 2 import * as process from 'process'; 2 import * as process from 'process'; + 3 + import stream from 'stream'; + 3 import terminalSize from 'terminal-size'; 4 import terminalSize from 'terminal-size'; + 4 import { iterlinesFromReadableAsync } from './iterLinesFromReadable'; 5 import { iterlinesFromReadableAsync } from './iterLinesFromReadable'; + 5 import { iterLinesWithoutAnsiColors } from './iterLinesWithoutAnsiColors'; 6 import { iterLinesWithoutAnsiColors } from './iterLinesWithoutAnsiColors'; +@@ -12,15 +13,16 @@ function main() { + 12 const screenWidth = terminalSize().columns; 13 const screenWidth = terminalSize().columns; + 13 const theme = defaultTheme(chalk, screenWidth); 14 const theme = defaultTheme(chalk, screenWidth); + 14 15 + 15 - transformStreamWithIterables( 16 + stream.pipeline( + 16 - process.stdin, 17 + transformStreamWithIterables( + 17 - [ 18 + process.stdin, + 15 iterlinesFromReadableAsync, 19 iterlinesFromReadableAsync, + 16 iterLinesWithoutAnsiColors, 20 iterLinesWithoutAnsiColors, + 17 iterSideBySideDiff(theme), 21 iterSideBySideDiff(theme), + 18 - iterWithNewlines, 22 + iterWithNewlines + 19 - ], 23 + ), + 20 - process.stdout 24 + process.stdout, + 25 + console.error + 18 ); 26 ); + 19 } 27 } + 20 28 +" +`; + +exports[`unifyOneSidedDiffs with ANSI color codes 1`] = ` +" +commit f735de7025c6d626c5ae1a291fe24f143dea0313 +Author: Shrey Banga +Date: Sun Apr 11 15:25:34 2021 -0700 + + Add theme support + +──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────── + ■■ todo.md +──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────── +@@ -7,6 +7,7 @@ + 7 - [x] Handle file addition/deletion properly + 8 - [x] Fix incorrect line positions when a hunk has discontinuous inserts and/or deletes + 9 - [x] Organize code + 10 + - [x] Move visual config to theme + 10 - [ ] Handle empty diffs + 11 - [ ] Handle moves and renames without diffs + 12 - [ ] Highlight changes in lines + 13 + 14 +" +`; diff --git a/src/getConfig.ts b/src/getConfig.ts index b63b5c6..15d6f4a 100644 --- a/src/getConfig.ts +++ b/src/getConfig.ts @@ -6,12 +6,14 @@ export type Config = Theme & { MIN_LINE_WIDTH: number; WRAP_LINES: boolean; HIGHLIGHT_LINE_CHANGES: boolean; + UNIFY_ONE_SIDED_DIFFS: boolean; }; export const CONFIG_DEFAULTS: Omit = { MIN_LINE_WIDTH: 80, WRAP_LINES: true, HIGHLIGHT_LINE_CHANGES: true, + UNIFY_ONE_SIDED_DIFFS: false, }; export function getConfig(gitConfig: GitConfig): Config { diff --git a/src/getGitConfig.test.ts b/src/getGitConfig.test.ts index 559a9f8..bc7d332 100644 --- a/src/getGitConfig.test.ts +++ b/src/getGitConfig.test.ts @@ -9,6 +9,7 @@ import { const DEFAULT_CONFIG: GitConfig = { WRAP_LINES: true, HIGHLIGHT_LINE_CHANGES: true, + UNIFY_ONE_SIDED_DIFFS: false, MIN_LINE_WIDTH: DEFAULT_MIN_LINE_WIDTH, THEME_NAME: DEFAULT_THEME_NAME, THEME_DIRECTORY: DEFAULT_THEME_DIRECTORY, @@ -24,6 +25,7 @@ describe('getGitConfig', () => { getGitConfig(` split-diffs.wrap-lines=false split-diffs.highlight-line-changes=false +split-diffs.unify-one-sided-diffs=true split-diffs.min-line-width=40 split-diffs.theme-name=arctic split-diffs.theme-directory=/tmp @@ -32,6 +34,7 @@ split-diffs.syntax-highlighting-theme=dark-plus ).toEqual({ WRAP_LINES: false, HIGHLIGHT_LINE_CHANGES: false, + UNIFY_ONE_SIDED_DIFFS: true, MIN_LINE_WIDTH: 40, THEME_NAME: 'arctic', THEME_DIRECTORY: '/tmp', @@ -57,6 +60,7 @@ split-diffs.syntax-highlighting-theme=nord getGitConfig(` split-diffs.wrap-lines=1 split-diffs.highlight-line-changes=1 +split-diffs.unify-one-sided-diffs=1 split-diffs.min-line-width=bar split-diffs.syntax-highlighting-theme=foo split-diffs.theme-name=baz diff --git a/src/getGitConfig.ts b/src/getGitConfig.ts index 5c0107c..06bc687 100644 --- a/src/getGitConfig.ts +++ b/src/getGitConfig.ts @@ -5,6 +5,7 @@ export type GitConfig = { MIN_LINE_WIDTH: number; WRAP_LINES: boolean; HIGHLIGHT_LINE_CHANGES: boolean; + UNIFY_ONE_SIDED_DIFFS: boolean; THEME_DIRECTORY: string; THEME_NAME: string; SYNTAX_HIGHLIGHTING_THEME?: string; @@ -53,6 +54,7 @@ export function getGitConfig(configString: string): GitConfig { MIN_LINE_WIDTH: minLineWidth, WRAP_LINES: rawConfig['wrap-lines'] !== 'false', HIGHLIGHT_LINE_CHANGES: rawConfig['highlight-line-changes'] !== 'false', + UNIFY_ONE_SIDED_DIFFS: rawConfig['unify-one-sided-diffs'] === 'true', THEME_DIRECTORY: rawConfig['theme-directory'] ?? DEFAULT_THEME_DIRECTORY, THEME_NAME: rawConfig['theme-name'] ?? DEFAULT_THEME_NAME, diff --git a/src/index.test.ts b/src/index.test.ts index 31025bf..880bf92 100644 --- a/src/index.test.ts +++ b/src/index.test.ts @@ -24,6 +24,7 @@ const TEST_CONFIG: Config = { MIN_LINE_WIDTH: 60, WRAP_LINES: false, HIGHLIGHT_LINE_CHANGES: false, + UNIFY_ONE_SIDED_DIFFS: false, ...TEST_THEME, }; @@ -56,6 +57,10 @@ const CONFIG_OVERRIDES: Record = { DELETED_WORD_COLOR: { color: { r: 255, g: 0, b: 0, a: 255 } }, INSERTED_WORD_COLOR: { color: { r: 0, g: 255, b: 0, a: 255 } }, }, + unifyOneSidedDiffs: { + MIN_LINE_WIDTH: 60, + UNIFY_ONE_SIDED_DIFFS: true, + }, syntaxHighlighted: { MIN_LINE_WIDTH: 60, WRAP_LINES: false, @@ -522,6 +527,55 @@ index 095ee29..439621e 100644 ).toMatchSnapshot(); }); + test('commit with one-sided and two-sided files', async function () { + expect( + await transform( + config, + ` +commit 1111111111111111111111111111111111111111 +Author: Shrey Banga +Date: Sun Apr 11 15:25:34 2021 -0700 + + Mix of changes + +diff --git a/added.md b/added.md +index 1111111..2222222 100644 +--- a/added.md ++++ b/added.md +@@ -1,2 +1,3 @@ + first ++inserted + second +@@ -10,2 +11,3 @@ + tenth ++another insert + eleventh +diff --git a/mixed.md b/mixed.md +index 3333333..4444444 100644 +--- a/mixed.md ++++ b/mixed.md +@@ -1,3 +1,3 @@ + first ++only inserted in this hunk + second +-third +@@ -10,3 +10,2 @@ + tenth +-only deleted in this hunk + eleventh +diff --git a/deleted.md b/deleted.md +index 5555555..6666666 100644 +--- a/deleted.md ++++ b/deleted.md +@@ -1,3 +1,2 @@ + first +-removed + second +` + ) + ).toMatchSnapshot(); + }); + test('merge commit with 2 parents', async function () { // Source: the TypeScript repo expect( diff --git a/src/iterFormatHunk.ts b/src/iterFormatHunk.ts index 276def8..97b714e 100644 --- a/src/iterFormatHunk.ts +++ b/src/iterFormatHunk.ts @@ -18,7 +18,8 @@ export async function* iterFormatHunk( context: Context, diffType: 'unified-diff' | 'combined-diff', hunkHeaderLine: string, - hunkParts: HunkPart[] + hunkParts: HunkPart[], + forceUnified: boolean = false ): AsyncIterable { const { HUNK_HEADER_COLOR, SCREEN_WIDTH, MIN_LINE_WIDTH } = context; @@ -37,7 +38,8 @@ export async function* iterFormatHunk( ); // Only split diffs if there's enough room - const splitDiffs = SCREEN_WIDTH >= MIN_LINE_WIDTH * hunkParts.length; + const splitDiffs = + !forceUnified && SCREEN_WIDTH >= MIN_LINE_WIDTH * hunkParts.length; if (splitDiffs) { yield* iterFormatHunkSplit(context, hunkParts, changes); diff --git a/src/iterSideBySideDiffs.ts b/src/iterSideBySideDiffs.ts index ae38fed..8299a72 100644 --- a/src/iterSideBySideDiffs.ts +++ b/src/iterSideBySideDiffs.ts @@ -38,7 +38,7 @@ async function* iterSideBySideDiffsFormatted( context: Context, lines: AsyncIterable ): AsyncIterable { - const { HORIZONTAL_SEPARATOR } = context; + const { HORIZONTAL_SEPARATOR, UNIFY_ONE_SIDED_DIFFS } = context; let state: State = 'unknown'; @@ -56,6 +56,12 @@ async function* iterSideBySideDiffsFormatted( let hunkParts: HunkPart[] = []; let hunkHeaderLine: string = ''; async function* yieldHunk(diffType: 'unified-diff' | 'combined-diff') { + if (diffType === 'unified-diff' && UNIFY_ONE_SIDED_DIFFS) { + // Whether a file is one-sided is only known once all its hunks + // have been read, so hold them until the file ends. + fileHunks.push({ hunkHeaderLine, hunkParts }); + return; + } yield* iterFormatHunk(context, diffType, hunkHeaderLine, hunkParts); for (const hunkPart of hunkParts) { hunkPart.startLineNo = -1; @@ -63,6 +69,30 @@ async function* iterSideBySideDiffsFormatted( } } + // Hunks of the current file, held back when UNIFY_ONE_SIDED_DIFFS is set + let fileHunks: { hunkHeaderLine: string; hunkParts: HunkPart[] }[] = []; + async function* yieldFileHunks() { + const hasPrefix = (lines: (string | null)[], prefix: string) => + lines.some((line) => line?.startsWith(prefix)); + const hasDeletions = fileHunks.some(({ hunkParts: [partA] }) => + hasPrefix(partA.lines, '-') + ); + const hasInsertions = fileHunks.some(({ hunkParts: [, partB] }) => + hasPrefix(partB.lines, '+') + ); + const isOneSided = !(hasDeletions && hasInsertions); + for (const { hunkHeaderLine, hunkParts } of fileHunks) { + yield* iterFormatHunk( + context, + 'unified-diff', + hunkHeaderLine, + hunkParts, + isOneSided + ); + } + fileHunks = []; + } + async function* flushPending() { if (state === 'unified-diff' || state === 'combined-diff') { yield* yieldFileName(); @@ -108,6 +138,12 @@ async function* iterSideBySideDiffsFormatted( // Handle state starts if (nextState) { yield* flushPending(); + if ( + nextState !== 'unified-diff-hunk-header' && + nextState !== 'unified-diff-hunk-body' + ) { + yield* yieldFileHunks(); + } switch (nextState) { case 'commit-header': @@ -309,6 +345,7 @@ async function* iterSideBySideDiffsFormatted( } yield* flushPending(); + yield* yieldFileHunks(); } export async function* iterSideBySideDiffs( diff --git a/src/previewTheme.ts b/src/previewTheme.ts index 298099f..10eaec9 100644 --- a/src/previewTheme.ts +++ b/src/previewTheme.ts @@ -12,6 +12,7 @@ const CONFIG = { MIN_LINE_WIDTH: 40, WRAP_LINES: true, HIGHLIGHT_LINE_CHANGES: true, + UNIFY_ONE_SIDED_DIFFS: false, }; async function previewTheme(