@@ -39,6 +39,7 @@ pub struct DetailsComponent {
39
39
current_size : Cell < ( u16 , u16 ) > ,
40
40
scroll_top : Cell < usize > ,
41
41
key_config : SharedKeyConfig ,
42
+ scroll_to_bottom_on_redraw : Cell < bool > ,
42
43
}
43
44
44
45
type WrappedCommitMessage < ' a > =
@@ -58,6 +59,7 @@ impl DetailsComponent {
58
59
focused,
59
60
current_size : Cell :: new ( ( 0 , 0 ) ) ,
60
61
scroll_top : Cell :: new ( 0 ) ,
62
+ scroll_to_bottom_on_redraw : Cell :: new ( false ) ,
61
63
key_config,
62
64
}
63
65
}
@@ -89,10 +91,7 @@ impl DetailsComponent {
89
91
90
92
if let Some ( ref body) = message. body {
91
93
let wrapped_message: Vec < Cow < ' _ , str > > =
92
- textwrap:: wrap ( body, width)
93
- . into_iter ( )
94
- . skip ( 1 )
95
- . collect ( ) ;
94
+ textwrap:: wrap ( body, width) . into_iter ( ) . collect ( ) ;
96
95
97
96
( wrapped_title, wrapped_message)
98
97
} else {
@@ -101,10 +100,10 @@ impl DetailsComponent {
101
100
}
102
101
103
102
fn get_wrapped_lines (
104
- & self ,
103
+ data : & Option < CommitDetails > ,
105
104
width : usize ,
106
105
) -> WrappedCommitMessage < ' _ > {
107
- if let Some ( ref data) = self . data {
106
+ if let Some ( ref data) = data {
108
107
if let Some ( ref message) = data. message {
109
108
return Self :: wrap_commit_details ( message, width) ;
110
109
}
@@ -113,9 +112,12 @@ impl DetailsComponent {
113
112
( vec ! [ ] , vec ! [ ] )
114
113
}
115
114
116
- fn get_number_of_lines ( & self , width : usize ) -> usize {
115
+ fn get_number_of_lines (
116
+ details : & Option < CommitDetails > ,
117
+ width : usize ,
118
+ ) -> usize {
117
119
let ( wrapped_title, wrapped_message) =
118
- self . get_wrapped_lines ( width) ;
120
+ Self :: get_wrapped_lines ( details , width) ;
119
121
120
122
wrapped_title. len ( ) + wrapped_message. len ( )
121
123
}
@@ -134,7 +136,7 @@ impl DetailsComponent {
134
136
height : usize ,
135
137
) -> Vec < Spans > {
136
138
let ( wrapped_title, wrapped_message) =
137
- self . get_wrapped_lines ( width) ;
139
+ Self :: get_wrapped_lines ( & self . data , width) ;
138
140
139
141
[ & wrapped_title[ ..] , & wrapped_message[ ..] ]
140
142
. concat ( )
@@ -278,7 +280,8 @@ impl DetailsComponent {
278
280
let width = self . current_size . get ( ) . 0 as usize ;
279
281
let height = self . current_size . get ( ) . 1 as usize ;
280
282
281
- let number_of_lines = self . get_number_of_lines ( width) ;
283
+ let number_of_lines =
284
+ Self :: get_number_of_lines ( & self . data , width) ;
282
285
283
286
let max = number_of_lines. saturating_sub ( height) as usize ;
284
287
@@ -290,7 +293,9 @@ impl DetailsComponent {
290
293
_ => old,
291
294
} ;
292
295
293
- if new_scroll_top > max {
296
+ let new_scroll_top = new_scroll_top. clamp ( 0 , max) ;
297
+
298
+ if new_scroll_top == old {
294
299
return false ;
295
300
}
296
301
@@ -336,6 +341,17 @@ impl DrawableComponent for DetailsComponent {
336
341
337
342
self . current_size . set ( ( width, height) ) ;
338
343
344
+ if self . scroll_to_bottom_on_redraw . get ( ) {
345
+ self . scroll_top . set (
346
+ Self :: get_number_of_lines (
347
+ & self . data ,
348
+ usize:: from ( width) ,
349
+ )
350
+ . saturating_sub ( usize:: from ( height) ) ,
351
+ ) ;
352
+ self . scroll_to_bottom_on_redraw . set ( false ) ;
353
+ }
354
+
339
355
let wrapped_lines = self . get_wrapped_text_message (
340
356
width as usize ,
341
357
height as usize ,
@@ -358,7 +374,7 @@ impl DrawableComponent for DetailsComponent {
358
374
f,
359
375
chunks[ 1 ] ,
360
376
& self . theme ,
361
- self . get_number_of_lines ( width as usize ) ,
377
+ Self :: get_number_of_lines ( & self . data , width as usize ) ,
362
378
self . scroll_top . get ( ) ,
363
379
)
364
380
}
@@ -376,7 +392,8 @@ impl Component for DetailsComponent {
376
392
// visibility_blocking(self)
377
393
378
394
let width = self . current_size . get ( ) . 0 as usize ;
379
- let number_of_lines = self . get_number_of_lines ( width) ;
395
+ let number_of_lines =
396
+ Self :: get_number_of_lines ( & self . data , width) ;
380
397
381
398
out. push (
382
399
CommandInfo :: new (
@@ -422,13 +439,7 @@ impl Component for DetailsComponent {
422
439
423
440
fn focus ( & mut self , focus : bool ) {
424
441
if focus {
425
- let width = self . current_size . get ( ) . 0 as usize ;
426
- let height = self . current_size . get ( ) . 1 as usize ;
427
-
428
- self . scroll_top . set (
429
- self . get_number_of_lines ( width)
430
- . saturating_sub ( height) ,
431
- ) ;
442
+ self . scroll_to_bottom_on_redraw . set ( true ) ;
432
443
}
433
444
434
445
self . focused = focus;
@@ -475,7 +486,7 @@ mod tests {
475
486
) ;
476
487
477
488
let message_with_body = CommitMessage :: from (
478
- "Commit message\n \ n First line\n Second line" ,
489
+ "Commit message\n First line\n Second line" ,
479
490
) ;
480
491
481
492
assert_eq ! (
@@ -491,3 +502,28 @@ mod tests {
491
502
) ;
492
503
}
493
504
}
505
+
506
+ #[ cfg( test) ]
507
+ mod test_line_count {
508
+ use super :: * ;
509
+
510
+ #[ test]
511
+ fn test_smoke ( ) {
512
+ let commit = CommitDetails {
513
+ message : Some ( CommitMessage {
514
+ subject : String :: from ( "subject line" ) ,
515
+ body : Some ( String :: from ( "body lone" ) ) ,
516
+ } ) ,
517
+ ..CommitDetails :: default ( )
518
+ } ;
519
+ let lines = DetailsComponent :: get_number_of_lines (
520
+ & Some ( commit. clone ( ) ) ,
521
+ 50 ,
522
+ ) ;
523
+ assert_eq ! ( lines, 2 ) ;
524
+
525
+ let lines =
526
+ DetailsComponent :: get_number_of_lines ( & Some ( commit) , 8 ) ;
527
+ assert_eq ! ( lines, 4 ) ;
528
+ }
529
+ }
0 commit comments