@@ -39,6 +39,7 @@ pub struct DetailsComponent {
3939 current_size : Cell < ( u16 , u16 ) > ,
4040 scroll_top : Cell < usize > ,
4141 key_config : SharedKeyConfig ,
42+ scroll_to_bottom_on_redraw : Cell < bool > ,
4243}
4344
4445type WrappedCommitMessage < ' a > =
@@ -58,6 +59,7 @@ impl DetailsComponent {
5859 focused,
5960 current_size : Cell :: new ( ( 0 , 0 ) ) ,
6061 scroll_top : Cell :: new ( 0 ) ,
62+ scroll_to_bottom_on_redraw : Cell :: new ( false ) ,
6163 key_config,
6264 }
6365 }
@@ -89,10 +91,7 @@ impl DetailsComponent {
8991
9092 if let Some ( ref body) = message. body {
9193 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 ( ) ;
9695
9796 ( wrapped_title, wrapped_message)
9897 } else {
@@ -101,10 +100,10 @@ impl DetailsComponent {
101100 }
102101
103102 fn get_wrapped_lines (
104- & self ,
103+ data : & Option < CommitDetails > ,
105104 width : usize ,
106105 ) -> WrappedCommitMessage < ' _ > {
107- if let Some ( ref data) = self . data {
106+ if let Some ( ref data) = data {
108107 if let Some ( ref message) = data. message {
109108 return Self :: wrap_commit_details ( message, width) ;
110109 }
@@ -113,9 +112,12 @@ impl DetailsComponent {
113112 ( vec ! [ ] , vec ! [ ] )
114113 }
115114
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 {
117119 let ( wrapped_title, wrapped_message) =
118- self . get_wrapped_lines ( width) ;
120+ Self :: get_wrapped_lines ( details , width) ;
119121
120122 wrapped_title. len ( ) + wrapped_message. len ( )
121123 }
@@ -134,7 +136,7 @@ impl DetailsComponent {
134136 height : usize ,
135137 ) -> Vec < Spans > {
136138 let ( wrapped_title, wrapped_message) =
137- self . get_wrapped_lines ( width) ;
139+ Self :: get_wrapped_lines ( & self . data , width) ;
138140
139141 [ & wrapped_title[ ..] , & wrapped_message[ ..] ]
140142 . concat ( )
@@ -278,7 +280,8 @@ impl DetailsComponent {
278280 let width = self . current_size . get ( ) . 0 as usize ;
279281 let height = self . current_size . get ( ) . 1 as usize ;
280282
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) ;
282285
283286 let max = number_of_lines. saturating_sub ( height) as usize ;
284287
@@ -290,7 +293,9 @@ impl DetailsComponent {
290293 _ => old,
291294 } ;
292295
293- if new_scroll_top > max {
296+ let new_scroll_top = new_scroll_top. clamp ( 0 , max) ;
297+
298+ if new_scroll_top == old {
294299 return false ;
295300 }
296301
@@ -336,6 +341,17 @@ impl DrawableComponent for DetailsComponent {
336341
337342 self . current_size . set ( ( width, height) ) ;
338343
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+
339355 let wrapped_lines = self . get_wrapped_text_message (
340356 width as usize ,
341357 height as usize ,
@@ -358,7 +374,7 @@ impl DrawableComponent for DetailsComponent {
358374 f,
359375 chunks[ 1 ] ,
360376 & self . theme ,
361- self . get_number_of_lines ( width as usize ) ,
377+ Self :: get_number_of_lines ( & self . data , width as usize ) ,
362378 self . scroll_top . get ( ) ,
363379 )
364380 }
@@ -376,7 +392,8 @@ impl Component for DetailsComponent {
376392 // visibility_blocking(self)
377393
378394 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) ;
380397
381398 out. push (
382399 CommandInfo :: new (
@@ -422,13 +439,7 @@ impl Component for DetailsComponent {
422439
423440 fn focus ( & mut self , focus : bool ) {
424441 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 ) ;
432443 }
433444
434445 self . focused = focus;
@@ -475,7 +486,7 @@ mod tests {
475486 ) ;
476487
477488 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" ,
479490 ) ;
480491
481492 assert_eq ! (
@@ -491,3 +502,28 @@ mod tests {
491502 ) ;
492503 }
493504}
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