Skip to content

Commit 5b28c34

Browse files
committed
Fix incorrect display width calculation
Previously we assumed that line numbers always required 4 characters to display (3 digits plus a space). This should be calculated properly and was probably a placeholder value when testing the original implementation. Instead, use the actual width of the rendered line numbers.
1 parent 6b58a62 commit 5b28c34

File tree

3 files changed

+75
-67
lines changed

3 files changed

+75
-67
lines changed

CHANGELOG.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,9 @@ longer affect display.
2222

2323
Improved descriptions of changes to binary files.
2424

25+
Fixed an issue where difftastic would not use the full width of the
26+
terminal on side-by-side diffs when files had more than 1,000 lines.
27+
2528
## 0.65 (released 23rd September 2025)
2629

2730
### Build

sample_files/compare.expected

Lines changed: 66 additions & 66 deletions
Original file line numberDiff line numberDiff line change
@@ -8,10 +8,10 @@ sample_files/added_line_1.txt sample_files/added_line_2.txt
88
8a1587e6b5fc53f2ec2ac665a5d00372 -
99

1010
sample_files/align_footer_1.txt sample_files/align_footer_2.txt
11-
a7ed15e00ccc8094621e2a9d3c29449c -
11+
c7f2c4dee1e99f8196ea7e20f7d77a0a -
1212

1313
sample_files/all_changed_1.js sample_files/all_changed_2.js
14-
6f6cbd4d2ed1045e3883143787dbd75b -
14+
4699b292efa2eb4e52942047f1b45e98 -
1515

1616
sample_files/apex_1.cls sample_files/apex_2.cls
1717
8e477350907734ac4d5201752523dff3 -
@@ -20,76 +20,76 @@ sample_files/b2_math_1.h sample_files/b2_math_2.h
2020
ea7421bd7970a6edf2897f8785053ce4 -
2121

2222
sample_files/bad_combine_1.rs sample_files/bad_combine_2.rs
23-
a6d674bd88d54f085c22c70c2d5a4c80 -
23+
212325b38a05e90c7266161769b38477 -
2424

2525
sample_files/big_text_hunk_1.txt sample_files/big_text_hunk_2.txt
2626
fc26d41a5ff771670e04033b177973d2 -
2727

2828
sample_files/change_outer_1.el sample_files/change_outer_2.el
29-
ae93896664a63c1f0d4a5f9c4d26dd70 -
29+
bbdc641dc39c0f26ec7f23e0558e24f2 -
3030

3131
sample_files/chinese_1.po sample_files/chinese_2.po
32-
582b2c28cca7a60b7c6b0410dfa436bc -
32+
d4b802f31506653916beadf88f628e06 -
3333

3434
sample_files/clojure_1.clj sample_files/clojure_2.clj
35-
f1a045dfa78cac71d355951fe0b363a0 -
35+
36c1ad5c83eda76c62042594eb302131 -
3636

3737
sample_files/comma_1.js sample_files/comma_2.js
38-
dfd18ec953d29545380fa656e54ff70e -
38+
3aa1c67b64bb1d71b0b7b575922e77b9 -
3939

4040
sample_files/comma_and_comment_1.js sample_files/comma_and_comment_2.js
41-
0a5ccbcd368607e62eaff0c4ae25049f -
41+
652b099094968e79706381fc38e82686 -
4242

4343
sample_files/comments_1.rs sample_files/comments_2.rs
44-
d8c3c256de454bc23944cf1a4300c66e -
44+
ce36820fa38dbcb450c1643df1560ed2 -
4545

4646
sample_files/context_1.rs sample_files/context_2.rs
47-
9b84c492d07d125912de77002bcaad9a -
47+
66106fdd1f4c3c2981a46067ece843d1 -
4848

4949
sample_files/contiguous_1.js sample_files/contiguous_2.js
5050
7ac6081dee02e3529a88defca194bc00 -
5151

5252
sample_files/css_1.css sample_files/css_2.css
53-
43a2bbc8dc2f4b4733ecb5a888d10dfc -
53+
0138ec9e44f3b792a7a47d89509c6a1d -
5454

5555
sample_files/dart_1.dart sample_files/dart_2.dart
56-
107d073c2922ff14e9ba66ee0f489592 -
56+
f44f0dffe3617ddafca3d65e94a21613 -
5757

5858
sample_files/devicetree_1.dts sample_files/devicetree_2.dts
59-
100d21f4d762db8991757b489c794db1 -
59+
64b33c6d65dbc85777ee30cf3893fbdb -
6060

6161
sample_files/elisp_1.el sample_files/elisp_2.el
62-
3e8c8abcb65a5141a2fb54bae4a9ca06 -
62+
98571b62f7407e90e9441e4f47ea85ae -
6363

6464
sample_files/elisp_contiguous_1.el sample_files/elisp_contiguous_2.el
65-
4a5a33873a4f84ee055d95e1448fba35 -
65+
4a4daef3b6aadea5d238c5b5c0c3afa0 -
6666

6767
sample_files/elixir_1.ex sample_files/elixir_2.ex
68-
5ab1a845f7cb3ca6db1fdef7bc4a042f -
68+
bb1a88ba037f6ed68040b9691a02ee6f -
6969

7070
sample_files/elm_1.elm sample_files/elm_2.elm
71-
8a67269f2dd2e4913f885b3b6e6d6a07 -
71+
4a6035591e50773f2e9a5931404e42fc -
7272

7373
sample_files/elvish_1.elv sample_files/elvish_2.elv
74-
93af1d46752d57db84011ca7482ae842 -
74+
cd2208fc3a47ecb1a1a04f104eeb8186 -
7575

7676
sample_files/erlang_1.erl sample_files/erlang_2.erl
7777
268056b80b3311309a17a6c5485f68cd -
7878

7979
sample_files/f_sharp_1.fs sample_files/f_sharp_2.fs
80-
f6c90edd5c4fb81b793f3b7c9b367845 -
80+
ce8779ecb5ada66df366fef11dcba490 -
8181

8282
sample_files/hack_1.php sample_files/hack_2.php
8383
c2bb0aa7d7b07d6ced79f6a5363e878b -
8484

8585
sample_files/hare_1.ha sample_files/hare_2.ha
86-
b0d0b2c446b46285c585a8eca75e6dd3 -
86+
84adbdd8f6994e3e7bcde55910dbe119 -
8787

8888
sample_files/haskell_1.hs sample_files/haskell_2.hs
89-
e47ca7a69c6f90d9ed9e8b9d47eb2cd4 -
89+
151ad80d5a9f6558a19eb1e09266ffad -
9090

9191
sample_files/hcl_1.hcl sample_files/hcl_2.hcl
92-
b4de7a8269018e05c0eba247d8097111 -
92+
b85eac8adf20ef74bec9fd5e5358a976 -
9393

9494
sample_files/hello_world_1.smali sample_files/hello_world_2.smali
9595
bb8463618fcb7f263bd2dafeef7a8b06 -
@@ -101,19 +101,19 @@ sample_files/html_1.html sample_files/html_2.html
101101
2b873fd1ea8f77d2463ceb08aa23967c -
102102

103103
sample_files/html_simple_1.html sample_files/html_simple_2.html
104-
4122689b7d2e3d59d822d2a5d93ebdd0 -
104+
6bd7bd0b72504d4c637c7f5aa9ef068d -
105105

106106
sample_files/huge_cpp_1.cpp sample_files/huge_cpp_2.cpp
107107
05d96cce94db8ebdfaf4f2d52239470c -
108108

109109
sample_files/hyphen_subwords_1.json sample_files/hyphen_subwords_2.json
110-
d0728537a824a0404a910b5b8dc05b1b -
110+
7cb9167b72fb98a8f5fa6c67d032edb5 -
111111

112112
sample_files/identical_1.scala sample_files/identical_2.scala
113113
15c5a789e644348cb7e0de051ff4b63e -
114114

115115
sample_files/if_1.py sample_files/if_2.py
116-
a30c2b8952c48c775d7339b35614afd8 -
116+
5a673245452b4cf845ef80c7c75cf480 -
117117

118118
sample_files/insert_blank_1.txt sample_files/insert_blank_2.txt
119119
a5fd75afcc99aa7b2b285f1f9ced8607 -
@@ -122,22 +122,22 @@ sample_files/janet_1.janet sample_files/janet_2.janet
122122
7dc0f1a3ce49f489fa4b64edefebb3c5 -
123123

124124
sample_files/java_1.java sample_files/java_2.java
125-
f4b15ddf3283e6c14d200efd06c0e85a -
125+
79f72d4a8d88540c87a99ce8f294d0e0 -
126126

127127
sample_files/javascript_1.js sample_files/javascript_2.js
128128
7fc853454d1133da215c646732ac67f3 -
129129

130130
sample_files/javascript_simple_1.js sample_files/javascript_simple_2.js
131-
1a2fdfb7210a93c80a7ce7c0768920c3 -
131+
4ae99bc6abbcdd379cd8798f46b288ee -
132132

133133
sample_files/json_1.json sample_files/json_2.json
134-
2ac602e995cdcb4bbbc1be6f4622e296 -
134+
9e95d50269a3d9b23b0e2f20a80f2f18 -
135135

136136
sample_files/jsx_1.jsx sample_files/jsx_2.jsx
137-
89832bde34f9c54c99a1bfb0f68291a9 -
137+
8dd6005aa6fbe816bef3fdd89908f1c0 -
138138

139139
sample_files/julia_1.jl sample_files/julia_2.jl
140-
10ac32ea1bd1d48b20386f1deeca40a0 -
140+
4301a933fbd272df7d05cef357533ae6 -
141141

142142
sample_files/load_1.js sample_files/load_2.js
143143
2e47b7908951ff8390058856edbaf715 -
@@ -146,7 +146,7 @@ sample_files/long_line_1.txt sample_files/long_line_2.txt
146146
7fc50bd547f0c20fda89a1931e5eb61e -
147147

148148
sample_files/lua_1.lua sample_files/lua_2.lua
149-
11693bb34168541f2ac9f4154d246038 -
149+
5182b3ce10f680f8d506af6e4dfb2dc1 -
150150

151151
sample_files/makefile_1.mk sample_files/makefile_2.mk
152152
1a132d165294d0325f9b0dae5569a4d0 -
@@ -158,37 +158,37 @@ sample_files/metadata_1.clj sample_files/metadata_2.clj
158158
b788a546c4ccc5662e98ed30473dd776 -
159159

160160
sample_files/modules_1.ml sample_files/modules_2.ml
161-
d0a10fce6354902c0a1708571ab17ffc -
161+
fabe617d18d24317bf38557b1455fb6e -
162162

163163
sample_files/multibyte_1.py sample_files/multibyte_2.py
164-
222fad0d771916afb86dfede9906895b -
164+
3d14774cd9d92968ce0b3be1b26ccaa1 -
165165

166166
sample_files/multiline_string_1.ml sample_files/multiline_string_2.ml
167-
ed80815053ba156505d156277d0f4195 -
167+
f0f106fac68313863fe78a6e8ba03e30 -
168168

169169
sample_files/multiline_string_eof_1.yml sample_files/multiline_string_eof_2.yml
170-
79f24009a062f256054cf36e0317dc5d -
170+
ce9de81e32672d245991446b72c8cd15 -
171171

172172
sample_files/nest_1.rs sample_files/nest_2.rs
173173
bb3c526d9400776ffae5bf78631fa0c3 -
174174

175175
sample_files/nested_slider_1.el sample_files/nested_slider_2.el
176-
7691443ec4ab9d35837f7caa5bfad2de -
176+
81f2384d51c952b78294470d7bf205d7 -
177177

178178
sample_files/nested_slider_1.rs sample_files/nested_slider_2.rs
179179
342df46db959e8c90925ff4400c0fa63 -
180180

181181
sample_files/nesting_1.el sample_files/nesting_2.el
182-
cf32f6b798a080a2bf14a430337ac4a6 -
182+
f5c878d2f4db639c1180cc62977962d3 -
183183

184184
sample_files/newick_1.nwk sample_files/newick_2.nwk
185185
bbc830fc20d60c5fdca7a99edc3fde78 -
186186

187187
sample_files/nix_1.nix sample_files/nix_2.nix
188-
5f591ced7633a07f13cdda9766110715 -
188+
6ba9f4016488b70ccb88fc3fa930d069 -
189189

190190
sample_files/nullable_1.kt sample_files/nullable_2.kt
191-
d0a51e7201cc16dc6bcb99cbad64f6be -
191+
ec439ca9b48e2db90d96fdfa01f060c2 -
192192

193193
sample_files/objc_header_1.h sample_files/objc_header_2.h
194194
37267814a3d241a8f1497ef3239b360c -
@@ -197,16 +197,16 @@ sample_files/objc_module_1.m sample_files/objc_module_2.m
197197
63d3b15c53dfcb54c5cf6ff10c22a965 -
198198

199199
sample_files/ocaml_1.ml sample_files/ocaml_2.ml
200-
e99bb9f1f789bce0e9a1d4e5205b8139 -
200+
1c13a1d098aca58e04fad56240d0676f -
201201

202202
sample_files/outer_delimiter_1.el sample_files/outer_delimiter_2.el
203203
971c3ddebfae222ded24f7a97ec7b5d7 -
204204

205205
sample_files/pascal_1.pascal sample_files/pascal_2.pascal
206-
de04f7fdb7af7bd70ca62f1868504f11 -
206+
c292c1128698aa0f41b1c5cc443c6246 -
207207

208208
sample_files/perl_1.pl sample_files/perl_2.pl
209-
2cd2638b2b6d07248911f1f2e5ad1b25 -
209+
487bc10eb2915c2ede654e747d0598a0 -
210210

211211
sample_files/prefer_outer_1.el sample_files/prefer_outer_2.el
212212
991038c9988cccc2c824652e33f772a2 -
@@ -215,13 +215,13 @@ sample_files/preprocessor_1.h sample_files/preprocessor_2.h
215215
d94f452bbf7cb3accc8d538fdd7ab5e4 -
216216

217217
sample_files/qml_1.qml sample_files/qml_2.qml
218-
ec69003436e7780633b6224861c3cccf -
218+
81680162af9cf1502fcf91c8d74f6a30 -
219219

220220
sample_files/r_1.R sample_files/r_2.R
221-
f86f4d5f494756079a4ccfdc17521ef3 -
221+
77c29d0589e7f97fabcaa1e044d7b72b -
222222

223223
sample_files/racket_1.rkt sample_files/racket_2.rkt
224-
4debb7e7af49678aa19726acb5c55d7d -
224+
6cdfb181c2e78ec7802ec717fd346e54 -
225225

226226
sample_files/repeated_line_no_eol_1.txt sample_files/repeated_line_no_eol_2.txt
227227
b63c743f2133480de3ba42ecdec5eb93 -
@@ -230,19 +230,19 @@ sample_files/ruby_1.rb sample_files/ruby_2.rb
230230
a0a7121421e3d57acadc08519275dcce -
231231

232232
sample_files/scala_1.scala sample_files/scala_2.scala
233-
2304bea82a6dae573964afdaeb47f845 -
233+
ceb94b1cd83e469ad6d33e4dc04a181f -
234234

235235
sample_files/scheme_1.scm sample_files/scheme_2.scm
236236
2d18a48f788361085a05812c2446de91 -
237237

238238
sample_files/simple_1.js sample_files/simple_2.js
239-
1d49d0e440067284015eb5621f4a6adf -
239+
d9ac04ab946e1da5907b2a1bcaceefd2 -
240240

241241
sample_files/simple_1.scss sample_files/simple_2.scss
242242
265261e79df78abfc09392d72a0273d8 -
243243

244244
sample_files/simple_1.txt sample_files/simple_2.txt
245-
7df04bd5dbc68a2392b2f0b375c4413e -
245+
f1881e5482f1ccfd8f3f45c7c63454e8 -
246246

247247
sample_files/slider_1.rs sample_files/slider_2.rs
248248
ebdc9db32892d1d74f7e745f45fbaba6 -
@@ -254,43 +254,43 @@ sample_files/slow_1.rs sample_files/slow_2.rs
254254
4eabdb287f5fa31f5765117f4874d218 -
255255

256256
sample_files/small_1.js sample_files/small_2.js
257-
86b1132b6c17fcc2cbec65b1c248baa9 -
257+
52f1691c1584f45317bfe3f650b91c78 -
258258

259259
sample_files/sql_1.sql sample_files/sql_2.sql
260-
ee54ee3f974aa54c8bdfc2b9075824f2 -
260+
801c1ca96eeb9ed8ed1ec7ebd1848ca0 -
261261

262262
sample_files/string_subwords_1.el sample_files/string_subwords_2.el
263-
5c72eae6a018e26189868bcc28747c72 -
263+
0bd477e796f418d0a6d66445d2b16e99 -
264264

265265
sample_files/strings_1.el sample_files/strings_2.el
266266
ae3b58de9c115cac8a1044e6cdf77723 -
267267

268268
sample_files/swift_1.swift sample_files/swift_2.swift
269-
73830b14bd8aacac8d4590a3bed61c40 -
269+
7fb0c9ebfc5f50b4936e224b089315d2 -
270270

271271
sample_files/syntax_error_1.js sample_files/syntax_error_2.js
272-
c3b918adc3e37f06c65e76fdd4f967e3 -
272+
bccd98e073dbc059c5ca7cadaa20166f -
273273

274274
sample_files/tab_1.c sample_files/tab_2.c
275-
3e19a5dfb37bcda0fbc20e0446c65692 -
275+
8b078aa89c662cc6fb9dabf6230ed5e7 -
276276

277277
sample_files/tab_1.txt sample_files/tab_2.txt
278278
10e9a853917dc9d92d2867e3453269b2 -
279279

280280
sample_files/tailwind_1.css sample_files/tailwind_2.css
281-
132f217659bf9dac8b82feabf5643f47 -
281+
8f0a090a15ab889a011003586d49153f -
282282

283283
sample_files/text_1.txt sample_files/text_2.txt
284-
caa98983e0fc26ae2bc833ae90fb0a1c -
284+
94c6a7e71c05ddc501c6961d5b833188 -
285285

286286
sample_files/todomvc_1.gleam sample_files/todomvc_2.gleam
287-
6b3b8c9f1e813617819b97144cc5cc4a -
287+
725bb793f219e13cee199f18ffaed872 -
288288

289289
sample_files/toml_1.toml sample_files/toml_2.toml
290-
e1002ceba14d973fcc8abc23619e65b0 -
290+
99fbf305557f02635bbbcee82eb79cb7 -
291291

292292
sample_files/trailling_newline_1.yaml sample_files/trailling_newline_2.yaml
293-
8e37febfec957288576f9c2020cfc4f2 -
293+
4b5c2b18de01c637e1d618b9132f8af8 -
294294

295295
sample_files/typescript_1.ts sample_files/typescript_2.ts
296296
e15ceae53da7cfb308960f8c3f30b891 -
@@ -299,26 +299,26 @@ sample_files/typing_1.ml sample_files/typing_2.ml
299299
ae41c3f5aa1ba13c2a424d3afa7ece6c -
300300

301301
sample_files/utf16_1.py sample_files/utf16_2.py
302-
58f2fd906a5ed1b7c5d933bb380c5a1c -
302+
b1325e96c07b1e02c043b511e5a628cb -
303303

304304
sample_files/verilog_1.sv sample_files/verilog_2.sv
305-
0fbb9bd8ff99b8ee852741860d2c25d0 -
305+
6d7e8ce7170de5a22a25c13d79d1f9b4 -
306306

307307
sample_files/vhdl_1.vhd sample_files/vhdl_2.vhd
308-
d23ea3d27a4cba037729adf485c84afa -
308+
5cfe89ec17acce6bf4c70be434678417 -
309309

310310
sample_files/whitespace_1.tsx sample_files/whitespace_2.tsx
311311
789689b170b80ef280a322b3a6c7363b -
312312

313313
sample_files/windows1251_1.txt sample_files/windows1251_2.txt
314-
28cb8832f6b172c34a28082012512269 -
314+
bd958b46e63436e5af93ab1304cffffb -
315315

316316
sample_files/xml_1.xml sample_files/xml_2.xml
317-
d943cb3ae6ea5a5b933ceb1b9987c06b -
317+
8d5309af57457c2d56e96a09b697b609 -
318318

319319
sample_files/yaml_1.yaml sample_files/yaml_2.yaml
320-
a539973fd87b6f1fe1391ce73a9b9f90 -
320+
f02cabd5170b39f6bad5cfc4d8e84205 -
321321

322322
sample_files/zig_1.zig sample_files/zig_2.zig
323-
f548aaa131854792fe3b72bc283f1280 -
323+
f3f718b83570f3245b4464b50d711a3d -
324324

src/display/side_by_side.rs

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -205,7 +205,12 @@ impl SourceDimensions {
205205
// This naively assumes that byte length is the same as
206206
// display length, which is generally OK because byte length
207207
// will tend to be larger than the display length.
208-
let display_width = min(terminal_width, (content_max_width + 4) * 2 + SPACER.len());
208+
let width_without_truncation = lhs_line_nums_width
209+
+ content_max_width
210+
+ SPACER.len()
211+
+ rhs_line_nums_width
212+
+ content_max_width;
213+
let display_width = min(terminal_width, width_without_truncation);
209214

210215
assert!(
211216
display_width > SPACER.len(),

0 commit comments

Comments
 (0)