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