ui: C-z suspend now restores the terminal cleanly
This commit is contained in:
		
							parent
							
								
									f7c22f97dc
								
							
						
					
					
						commit
						ad424e0381
					
				| @ -278,7 +278,7 @@ asHandle ui0@UIState{ | ||||
|         VtyEvent (EvKey KEnter []) -> continue $ regenerateScreens j d $ setFilter s $ closeMinibuffer ui | ||||
|                             where s = chomp $ unlines $ map strip $ getEditContents ed | ||||
|         VtyEvent (EvKey (KChar 'l') [MCtrl]) -> redraw ui | ||||
|         VtyEvent (EvKey (KChar 'z') [MCtrl]) -> suspendAndRedraw ui | ||||
|         VtyEvent (EvKey (KChar 'z') [MCtrl]) -> suspend ui | ||||
|         VtyEvent ev        -> do ed' <- handleEditorEvent ev ed | ||||
|                                  continue $ ui{aMode=Minibuffer ed'} | ||||
|         AppEvent _        -> continue ui | ||||
| @ -289,7 +289,7 @@ asHandle ui0@UIState{ | ||||
|       case ev of | ||||
|         VtyEvent (EvKey (KChar 'q') []) -> halt ui | ||||
|         VtyEvent (EvKey (KChar 'l') [MCtrl]) -> redraw ui | ||||
|         VtyEvent (EvKey (KChar 'z') [MCtrl]) -> suspendAndRedraw ui | ||||
|         VtyEvent (EvKey (KChar 'z') [MCtrl]) -> suspend ui | ||||
|         _                    -> helpHandle ui ev | ||||
| 
 | ||||
|     Normal -> | ||||
| @ -343,7 +343,7 @@ asHandle ui0@UIState{ | ||||
|         VtyEvent (EvKey k           []) | k `elem` [KBS, KDel] -> (continue $ regenerateScreens j d $ resetFilter ui) | ||||
|         VtyEvent e | e `elem` moveLeftEvents -> continue $ popScreen ui | ||||
|         VtyEvent (EvKey (KChar 'l') [MCtrl]) -> scrollSelectionToMiddle _asList >> redraw ui | ||||
|         VtyEvent (EvKey (KChar 'z') [MCtrl]) -> suspendAndRedraw ui | ||||
|         VtyEvent (EvKey (KChar 'z') [MCtrl]) -> suspend ui | ||||
| 
 | ||||
|         -- enter register screen for selected account (if there is one),  | ||||
|         -- centering its selected transaction if possible | ||||
|  | ||||
| @ -86,7 +86,7 @@ esHandle ui@UIState{aScreen=ErrorScreen{..} | ||||
|       case ev of | ||||
|         VtyEvent (EvKey (KChar 'q') []) -> halt ui | ||||
|         VtyEvent (EvKey (KChar 'l') [MCtrl]) -> redraw ui | ||||
|         VtyEvent (EvKey (KChar 'z') [MCtrl]) -> suspendAndRedraw ui | ||||
|         VtyEvent (EvKey (KChar 'z') [MCtrl]) -> suspend ui | ||||
|         _                    -> helpHandle ui ev | ||||
| 
 | ||||
|     _ -> do | ||||
| @ -108,7 +108,7 @@ esHandle ui@UIState{aScreen=ErrorScreen{..} | ||||
| --             Right j' -> continue $ regenerateScreens j' d $ popScreen ui  -- return to previous screen, and reload it | ||||
|         VtyEvent (EvKey (KChar 'I') []) -> continue $ uiCheckBalanceAssertions d (popScreen $ toggleIgnoreBalanceAssertions ui) | ||||
|         VtyEvent (EvKey (KChar 'l') [MCtrl]) -> redraw ui | ||||
|         VtyEvent (EvKey (KChar 'z') [MCtrl]) -> suspendAndRedraw ui | ||||
|         VtyEvent (EvKey (KChar 'z') [MCtrl]) -> suspend ui | ||||
|         _ -> continue ui | ||||
| 
 | ||||
| esHandle _ _ = error "event handler called with wrong screen type, should not happen" | ||||
|  | ||||
| @ -282,7 +282,7 @@ rsHandle ui@UIState{ | ||||
|         VtyEvent (EvKey KEnter []) -> continue $ regenerateScreens j d $ setFilter s $ closeMinibuffer ui | ||||
|                             where s = chomp $ unlines $ map strip $ getEditContents ed | ||||
|         VtyEvent (EvKey (KChar 'l') [MCtrl]) -> redraw ui | ||||
|         VtyEvent (EvKey (KChar 'z') [MCtrl]) -> suspendAndRedraw ui | ||||
|         VtyEvent (EvKey (KChar 'z') [MCtrl]) -> suspend ui | ||||
|         VtyEvent ev              -> do ed' <- handleEditorEvent ev ed | ||||
|                                        continue $ ui{aMode=Minibuffer ed'} | ||||
|         AppEvent _        -> continue ui | ||||
| @ -293,7 +293,7 @@ rsHandle ui@UIState{ | ||||
|       case ev of | ||||
|         VtyEvent (EvKey (KChar 'q') []) -> halt ui | ||||
|         VtyEvent (EvKey (KChar 'l') [MCtrl]) -> redraw ui | ||||
|         VtyEvent (EvKey (KChar 'z') [MCtrl]) -> suspendAndRedraw ui | ||||
|         VtyEvent (EvKey (KChar 'z') [MCtrl]) -> suspend ui | ||||
|         _                    -> helpHandle ui ev | ||||
| 
 | ||||
|     Normal -> | ||||
| @ -338,7 +338,7 @@ rsHandle ui@UIState{ | ||||
|         VtyEvent (EvKey k           []) | k `elem` [KBS, KDel] -> (continue $ regenerateScreens j d $ resetFilter ui) | ||||
|         VtyEvent e | e `elem` moveLeftEvents  -> continue $ popScreen ui | ||||
|         VtyEvent (EvKey (KChar 'l') [MCtrl]) -> scrollSelectionToMiddle rsList >> redraw ui | ||||
|         VtyEvent (EvKey (KChar 'z') [MCtrl]) -> suspendAndRedraw ui | ||||
|         VtyEvent (EvKey (KChar 'z') [MCtrl]) -> suspend ui | ||||
| 
 | ||||
|         -- enter transaction screen for selected transaction | ||||
|         VtyEvent e | e `elem` moveRightEvents -> do | ||||
|  | ||||
| @ -120,7 +120,7 @@ tsHandle ui@UIState{aScreen=s@TransactionScreen{tsTransaction=(i,t) | ||||
|       case ev of | ||||
|         VtyEvent (EvKey (KChar 'q') []) -> halt ui | ||||
|         VtyEvent (EvKey (KChar 'l') [MCtrl]) -> redraw ui | ||||
|         VtyEvent (EvKey (KChar 'z') [MCtrl]) -> suspendAndRedraw ui | ||||
|         VtyEvent (EvKey (KChar 'z') [MCtrl]) -> suspend ui | ||||
|         _                    -> helpHandle ui ev | ||||
| 
 | ||||
|     _ -> do | ||||
| @ -181,7 +181,7 @@ tsHandle ui@UIState{aScreen=s@TransactionScreen{tsTransaction=(i,t) | ||||
|             ui'@UIState{aScreen=scr} = popScreen ui | ||||
|             ui'' = ui'{aScreen=rsSelect (fromIntegral i) scr} | ||||
|         VtyEvent (EvKey (KChar 'l') [MCtrl]) -> redraw ui | ||||
|         VtyEvent (EvKey (KChar 'z') [MCtrl]) -> suspendAndRedraw ui | ||||
|         VtyEvent (EvKey (KChar 'z') [MCtrl]) -> suspend ui | ||||
|         _ -> continue ui | ||||
| 
 | ||||
| tsHandle _ _ = error "event handler called with wrong screen type, should not happen" | ||||
|  | ||||
| @ -22,7 +22,6 @@ module Hledger.UI.UIUtils ( | ||||
|   ,replaceHiddenAccountsNameWith | ||||
|   ,scrollSelectionToMiddle | ||||
|   ,suspend | ||||
|   ,suspendAndRedraw | ||||
|   ,redraw | ||||
| ) | ||||
| where | ||||
| @ -52,39 +51,27 @@ import Hledger.Cli.DocFiles | ||||
| import Hledger.UI.UITypes | ||||
| import Hledger.UI.UIState | ||||
| 
 | ||||
| -- | On posix platforms, suspend the program using the system STOP signal | ||||
| -- (as control-z usually does in bash). On windows, does nothing. | ||||
| -- | On posix platforms, send the system STOP signal to suspend the | ||||
| -- current program. On windows, does nothing. | ||||
| #ifdef mingw32_HOST_OS | ||||
| suspend :: IO () | ||||
| suspend = return () | ||||
| suspendSignal :: IO () | ||||
| suspendSignal = return () | ||||
| #else | ||||
| import System.Posix.Signals | ||||
| suspend :: IO () | ||||
| suspend = raiseSignal sigSTOP  | ||||
| suspendSignal :: IO () | ||||
| suspendSignal = raiseSignal sigSTOP  | ||||
| #endif | ||||
| 
 | ||||
| -- | On posix platforms, suspend the program using the system STOP | ||||
| -- signal, returning to the original shell prompt | ||||
| -- (TODO: and restore the original terminal attributes). | ||||
| -- When the program is resumed, redraw the screen and continue. | ||||
| -- On windows, just redraws the screen. | ||||
| suspendAndRedraw :: s -> EventM a (Next s) | ||||
| suspendAndRedraw ui = do | ||||
|   -- reset terminal attributes using vty ? | ||||
|   -- Vty{outputIface=output} <- getVtyHandle | ||||
|   -- r <- displayBounds output | ||||
|   -- DisplayContext{writeDefaultAttr=_reset} <- liftIO $ (mkDisplayContext output) output r | ||||
|   -- runWrite (reset True) _someptr | ||||
| 
 | ||||
|   -- suspend.. | ||||
|   liftIO suspend | ||||
| 
 | ||||
|   -- ..and resume | ||||
|   redraw ui | ||||
| -- | On posix platforms, suspend the program using the STOP signal, | ||||
| -- like control-z in bash, returning to the original shell prompt, | ||||
| -- and when resumed, continue where we left off. | ||||
| -- On windows, does nothing. | ||||
| suspend :: s -> EventM a (Next s) | ||||
| suspend st = suspendAndResume $ suspendSignal >> return st | ||||
| 
 | ||||
| -- | Tell vty to redraw the whole screen, and continue. | ||||
| redraw :: s -> EventM a (Next s) | ||||
| redraw ui = getVtyHandle >>= liftIO . refresh >> continue ui | ||||
| redraw st = getVtyHandle >>= liftIO . refresh >> continue st | ||||
| 
 | ||||
| -- ui | ||||
| 
 | ||||
|  | ||||
		Loading…
	
		Reference in New Issue
	
	Block a user