@@ -21,6 +21,7 @@ use super::{
2121 } ,
2222 view:: { DetailData , DialogView , Snapshot } ,
2323} ;
24+ use crate :: commands:: rm:: { LocalBranchStatus , RemoveOutcome } ;
2425
2526pub struct InteractiveCommand < B , E >
2627where
7778
7879 pub fn run < F , G > ( mut self , mut on_remove : F , mut on_create : G ) -> Result < Option < Selection > >
7980 where
80- F : FnMut ( & str , bool ) -> Result < ( ) > ,
81+ F : FnMut ( & str , bool ) -> Result < RemoveOutcome > ,
8182 G : FnMut ( & str , Option < & str > ) -> Result < ( ) > ,
8283 {
8384 self . terminal
8687
8788 let result = self . event_loop ( & mut on_remove, & mut on_create) ;
8889
90+ self . terminal
91+ . clear ( )
92+ . wrap_err ( "failed to clear terminal before exit" ) ?;
8993 self . terminal
9094 . show_cursor ( )
9195 . wrap_err ( "failed to show cursor" ) ?;
99103 on_create : & mut G ,
100104 ) -> Result < Option < Selection > >
101105 where
102- F : FnMut ( & str , bool ) -> Result < ( ) > ,
106+ F : FnMut ( & str , bool ) -> Result < RemoveOutcome > ,
103107 G : FnMut ( & str , Option < & str > ) -> Result < ( ) > ,
104108 {
105109 let mut state = ListState :: default ( ) ;
@@ -126,15 +130,15 @@ where
126130 on_create : & mut G ,
127131 ) -> Result < LoopControl >
128132 where
129- F : FnMut ( & str , bool ) -> Result < ( ) > ,
133+ F : FnMut ( & str , bool ) -> Result < RemoveOutcome > ,
130134 G : FnMut ( & str , Option < & str > ) -> Result < ( ) > ,
131135 {
132136 if let Some ( dialog) = self . dialog . clone ( ) {
133137 match dialog {
134138 Dialog :: Remove ( _) => {
135139 if let Event :: Key ( key) = event {
136140 if key. kind == KeyEventKind :: Press {
137- self . handle_remove_dialog_key ( key, state, on_remove) ? ;
141+ return self . handle_remove_dialog_key ( key, state, on_remove) ;
138142 }
139143 }
140144 return Ok ( LoopControl :: Continue ) ;
@@ -327,17 +331,18 @@ where
327331 key : KeyEvent ,
328332 state : & mut ListState ,
329333 on_remove : & mut F ,
330- ) -> Result < ( ) >
334+ ) -> Result < LoopControl >
331335 where
332- F : FnMut ( & str , bool ) -> Result < ( ) > ,
336+ F : FnMut ( & str , bool ) -> Result < RemoveOutcome > ,
333337 {
334338 let dialog_state = self . dialog . take ( ) ;
335339 let Some ( Dialog :: Remove ( mut dialog) ) = dialog_state else {
336340 self . dialog = dialog_state;
337- return Ok ( ( ) ) ;
341+ return Ok ( LoopControl :: Continue ) ;
338342 } ;
339343
340344 let mut reinstate = true ;
345+ let mut control = LoopControl :: Continue ;
341346
342347 match key. code {
343348 KeyCode :: Esc | KeyCode :: Char ( 'n' ) | KeyCode :: Char ( 'N' ) => {
@@ -346,7 +351,14 @@ where
346351 }
347352 KeyCode :: Char ( 'y' ) | KeyCode :: Char ( 'Y' ) => {
348353 reinstate = false ;
349- self . perform_remove ( dialog. index , dialog. remove_local_branch ( ) , state, on_remove) ?;
354+ if let Some ( selection) = self . perform_remove (
355+ dialog. index ,
356+ dialog. remove_local_branch ( ) ,
357+ state,
358+ on_remove,
359+ ) ? {
360+ control = LoopControl :: Exit ( Some ( selection) ) ;
361+ }
350362 }
351363 KeyCode :: Tab => dialog. focus_next ( ) ,
352364 KeyCode :: BackTab => dialog. focus_prev ( ) ,
@@ -381,12 +393,14 @@ where
381393 self . status = Some ( StatusMessage :: info ( "Removal cancelled." ) ) ;
382394 } else {
383395 reinstate = false ;
384- self . perform_remove (
396+ if let Some ( selection ) = self . perform_remove (
385397 dialog. index ,
386398 dialog. remove_local_branch ( ) ,
387399 state,
388400 on_remove,
389- ) ?;
401+ ) ? {
402+ control = LoopControl :: Exit ( Some ( selection) ) ;
403+ }
390404 }
391405 }
392406 } ,
@@ -397,7 +411,7 @@ where
397411 self . dialog = Some ( Dialog :: Remove ( dialog) ) ;
398412 }
399413
400- Ok ( ( ) )
414+ Ok ( control )
401415 }
402416
403417 fn perform_remove < F > (
@@ -406,26 +420,40 @@ where
406420 remove_local_branch : bool ,
407421 state : & mut ListState ,
408422 on_remove : & mut F ,
409- ) -> Result < ( ) >
423+ ) -> Result < Option < Selection > >
410424 where
411- F : FnMut ( & str , bool ) -> Result < ( ) > ,
425+ F : FnMut ( & str , bool ) -> Result < RemoveOutcome > ,
412426 {
413427 if let Some ( entry) = self . worktrees . get ( index) . cloned ( ) {
414428 match on_remove ( & entry. name , remove_local_branch) {
415- Ok ( ( ) ) => {
429+ Ok ( outcome ) => {
416430 self . worktrees . remove ( index) ;
417431 let removal_dir = entry
418432 . path
419433 . parent ( )
420434 . map ( |parent| parent. display ( ) . to_string ( ) )
421435 . unwrap_or_else ( || entry. path . display ( ) . to_string ( ) ) ;
422- let message =
436+ let mut message =
423437 format ! ( "Removed worktree `{}` from `{}`." , entry. name, removal_dir) ;
438+ match outcome. local_branch {
439+ Some ( LocalBranchStatus :: Deleted ) => {
440+ message. push_str ( & format ! ( " Deleted local branch `{}`." , entry. name) ) ;
441+ }
442+ Some ( LocalBranchStatus :: NotFound ) => {
443+ message. push_str ( & format ! ( " Local branch `{}` not found." , entry. name) ) ;
444+ }
445+ None => { }
446+ }
424447 self . selected = None ;
425448 self . focus = Focus :: Worktrees ;
426449 self . sync_selection ( state) ;
427450 self . status = None ;
428- self . dialog = Some ( Dialog :: Info { message } ) ;
451+ if outcome. repositioned {
452+ self . dialog = None ;
453+ return Ok ( Some ( Selection :: RepoRoot ) ) ;
454+ } else {
455+ self . dialog = Some ( Dialog :: Info { message } ) ;
456+ }
429457 }
430458 Err ( err) => {
431459 self . status = Some ( StatusMessage :: error ( format ! (
@@ -439,7 +467,7 @@ where
439467 self . dialog = None ;
440468 }
441469
442- Ok ( ( ) )
470+ Ok ( None )
443471 }
444472
445473 fn handle_create_key < G > (
0 commit comments