@@ -22,6 +22,7 @@ use tui::{
22
22
widgets:: { Block , Borders , Paragraph , Text } ,
23
23
Frame ,
24
24
} ;
25
+ use unicode_width:: UnicodeWidthStr ;
25
26
26
27
const ELEMENTS_PER_LINE : usize = 10 ;
27
28
@@ -182,6 +183,7 @@ impl CommitList {
182
183
txt : & mut Vec < Text < ' a > > ,
183
184
tags : Option < String > ,
184
185
theme : & Theme ,
186
+ width : usize ,
185
187
) {
186
188
txt. reserve ( ELEMENTS_PER_LINE ) ;
187
189
@@ -205,9 +207,13 @@ impl CommitList {
205
207
206
208
txt. push ( splitter. clone ( ) ) ;
207
209
210
+ let author_width =
211
+ ( width. saturating_sub ( 19 ) / 3 ) . max ( 3 ) . min ( 20 ) ;
212
+ let author = string_width_align ( & e. author , author_width) ;
213
+
208
214
// commit author
209
215
txt. push ( Text :: Styled (
210
- Cow :: from ( e . author . as_str ( ) ) ,
216
+ author. into ( ) ,
211
217
theme. commit_author ( selected) ,
212
218
) ) ;
213
219
@@ -233,7 +239,7 @@ impl CommitList {
233
239
txt. push ( Text :: Raw ( Cow :: from ( "\n " ) ) ) ;
234
240
}
235
241
236
- fn get_text ( & self , height : usize ) -> Vec < Text > {
242
+ fn get_text ( & self , height : usize , width : usize ) -> Vec < Text > {
237
243
let selection = self . relative_selection ( ) ;
238
244
239
245
let mut txt = Vec :: with_capacity ( height * ELEMENTS_PER_LINE ) ;
@@ -259,6 +265,7 @@ impl CommitList {
259
265
& mut txt,
260
266
tags,
261
267
& self . theme ,
268
+ width,
262
269
) ;
263
270
}
264
271
@@ -277,10 +284,11 @@ impl DrawableComponent for CommitList {
277
284
f : & mut Frame < B > ,
278
285
area : Rect ,
279
286
) -> Result < ( ) > {
280
- self . current_size . set ( (
287
+ let current_size = (
281
288
area. width . saturating_sub ( 2 ) ,
282
289
area. height . saturating_sub ( 2 ) ,
283
- ) ) ;
290
+ ) ;
291
+ self . current_size . set ( current_size) ;
284
292
285
293
let height_in_lines = self . current_size . get ( ) . 1 as usize ;
286
294
let selection = self . relative_selection ( ) ;
@@ -303,15 +311,21 @@ impl DrawableComponent for CommitList {
303
311
) ;
304
312
305
313
f. render_widget (
306
- Paragraph :: new ( self . get_text ( height_in_lines) . iter ( ) )
307
- . block (
308
- Block :: default ( )
309
- . borders ( Borders :: ALL )
310
- . title ( title. as_str ( ) )
311
- . border_style ( self . theme . block ( true ) )
312
- . title_style ( self . theme . title ( true ) ) ,
314
+ Paragraph :: new (
315
+ self . get_text (
316
+ height_in_lines,
317
+ current_size. 0 as usize ,
313
318
)
314
- . alignment ( Alignment :: Left ) ,
319
+ . iter ( ) ,
320
+ )
321
+ . block (
322
+ Block :: default ( )
323
+ . borders ( Borders :: ALL )
324
+ . title ( title. as_str ( ) )
325
+ . border_style ( self . theme . block ( true ) )
326
+ . title_style ( self . theme . title ( true ) ) ,
327
+ )
328
+ . alignment ( Alignment :: Left ) ,
315
329
area,
316
330
) ;
317
331
@@ -363,3 +377,53 @@ impl Component for CommitList {
363
377
CommandBlocking :: PassingOn
364
378
}
365
379
}
380
+
381
+ #[ inline]
382
+ fn string_width_align ( s : & str , width : usize ) -> String {
383
+ static POSTFIX : & str = ".." ;
384
+
385
+ let len = UnicodeWidthStr :: width ( s) ;
386
+ let width_wo_postfix = width. saturating_sub ( POSTFIX . len ( ) ) ;
387
+
388
+ if ( len >= width_wo_postfix && len <= width)
389
+ || ( len <= width_wo_postfix)
390
+ {
391
+ format ! ( "{:w$}" , s, w = width)
392
+ } else {
393
+ let mut s = s. to_string ( ) ;
394
+ s. truncate ( find_truncate_point ( & s, width_wo_postfix) ) ;
395
+ format ! ( "{}{}" , s, POSTFIX )
396
+ }
397
+ }
398
+
399
+ #[ inline]
400
+ fn find_truncate_point ( s : & str , chars : usize ) -> usize {
401
+ s. chars ( ) . take ( chars) . map ( char:: len_utf8) . sum ( )
402
+ }
403
+
404
+ #[ cfg( test) ]
405
+ mod tests {
406
+ use super :: * ;
407
+
408
+ #[ test]
409
+ fn test_string_width_align ( ) {
410
+ assert_eq ! ( string_width_align( "123" , 3 ) , "123" ) ;
411
+ assert_eq ! ( string_width_align( "123" , 2 ) , ".." ) ;
412
+ assert_eq ! ( string_width_align( "123" , 3 ) , "123" ) ;
413
+ assert_eq ! ( string_width_align( "12345" , 6 ) , "12345 " ) ;
414
+ assert_eq ! ( string_width_align( "1234556" , 4 ) , "12.." ) ;
415
+ }
416
+
417
+ #[ test]
418
+ fn test_string_width_align_unicode ( ) {
419
+ assert_eq ! ( string_width_align( "äste" , 3 ) , "ä.." ) ;
420
+ assert_eq ! (
421
+ string_width_align( "wüsten äste" , 10 ) ,
422
+ "wüsten ä.."
423
+ ) ;
424
+ assert_eq ! (
425
+ string_width_align( "Jon Grythe Stødle" , 19 ) ,
426
+ "Jon Grythe Stødle "
427
+ ) ;
428
+ }
429
+ }
0 commit comments