@@ -119,8 +119,8 @@ impl App {
119119 Duration :: from_secs ( file_refresh_rate) ,
120120 ) ,
121121 // sender,
122- receiver : receiver ,
123- input_receiver : input_receiver ,
122+ receiver,
123+ input_receiver,
124124 output_file_view : OutputFileView :: default ( ) ,
125125 }
126126 }
@@ -155,13 +155,33 @@ impl App {
155155
156156 fn handle ( & mut self , msg : AppMessage ) {
157157 match msg {
158- AppMessage :: Jobs ( jobs) => self . jobs = jobs,
158+ AppMessage :: Jobs ( jobs) => {
159+ // On refresh: keep the same job selected if it still exists
160+ let old_index = self . job_list_state . selected ( ) ;
161+ let old_id = old_index. and_then ( |i| self . jobs . get ( i) ) . map ( |j| j. id ( ) ) ;
162+
163+ self . jobs = jobs;
164+
165+ if self . jobs . is_empty ( ) {
166+ self . job_list_state . select ( None ) ;
167+ } else if let Some ( id) = old_id {
168+ let new_index = self
169+ . jobs
170+ . iter ( )
171+ . position ( |j| j. id ( ) == id)
172+ . unwrap_or ( old_index. unwrap_or ( 0 ) . min ( self . jobs . len ( ) - 1 ) ) ;
173+ self . job_list_state . select ( Some ( new_index) ) ;
174+ } else {
175+ self . job_list_state . select_first ( ) ;
176+ }
177+ }
159178 AppMessage :: JobOutput ( content) => self . job_output = content,
160179 AppMessage :: Key ( key) => {
161180 if let Some ( dialog) = & self . dialog {
162181 match dialog {
163182 Dialog :: ConfirmCancelJob ( id) => match key. code {
164183 KeyCode :: Enter | KeyCode :: Char ( 'y' ) => {
184+ let id = id. clone ( ) ;
165185 Command :: new ( "scancel" )
166186 . arg ( id)
167187 . stdout ( Stdio :: null ( ) )
@@ -388,9 +408,6 @@ impl App {
388408 } ) ,
389409 )
390410 . highlight_style ( Style :: default ( ) . bg ( Color :: Green ) . fg ( Color :: Black ) ) ;
391- if self . job_list_state . selected ( ) . is_none ( ) {
392- self . job_list_state . select_first ( ) ;
393- }
394411 f. render_stateful_widget ( job_list, master_detail[ 0 ] , & mut self . job_list_state ) ;
395412
396413 // Job details
@@ -564,7 +581,7 @@ fn chunked_string(s: &str, first_chunk_size: usize, chunk_size: usize) -> Vec<&s
564581 . enumerate ( )
565582 . filter ( |& ( i, _) | {
566583 if i > ( first_chunk_size) {
567- chunk_size > 0 && ( i - first_chunk_size) % chunk_size == 0
584+ chunk_size > 0 && ( i - first_chunk_size) . is_multiple_of ( chunk_size)
568585 } else {
569586 i == 0 || i == first_chunk_size
570587 }
@@ -631,7 +648,7 @@ fn fit_text(
631648 offset : usize ,
632649 wrap : bool ,
633650) -> Text < ' _ > {
634- let s = s. rsplit_once ( & [ '\r' , '\n' ] ) . map_or ( s, |( p, _) | p) ; // skip everything after last line delimiter
651+ let s = s. rsplit_once ( [ '\r' , '\n' ] ) . map_or ( s, |( p, _) | p) ; // skip everything after last line delimiter
635652 let l = s. lines ( ) . flat_map ( |l| l. split ( '\r' ) ) ; // bandaid for term escape codes
636653 let iter = match anchor {
637654 ScrollAnchor :: Top => Either :: Left ( l) ,
0 commit comments