ui: on posix, support ctrl-z to suspend the program
This commit is contained in:
		
							parent
							
								
									c02647d05e
								
							
						
					
					
						commit
						cc0764eac2
					
				| @ -40,6 +40,7 @@ import Hledger.UI.Editor | ||||
| import Hledger.UI.RegisterScreen | ||||
| import Hledger.UI.ErrorScreen | ||||
| 
 | ||||
| 
 | ||||
| accountsScreen :: Screen | ||||
| accountsScreen = AccountsScreen{ | ||||
|    sInit   = asInit | ||||
| @ -277,6 +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 ev        -> do ed' <- handleEditorEvent ev ed | ||||
|                                  continue $ ui{aMode=Minibuffer ed'} | ||||
|         AppEvent _        -> continue ui | ||||
| @ -287,6 +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 | ||||
|         _                    -> helpHandle ui ev | ||||
| 
 | ||||
|     Normal -> | ||||
| @ -340,6 +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 | ||||
| 
 | ||||
|         -- enter register screen for selected account (if there is one),  | ||||
|         -- centering its selected transaction if possible | ||||
|  | ||||
| @ -86,6 +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 | ||||
|         _                    -> helpHandle ui ev | ||||
| 
 | ||||
|     _ -> do | ||||
| @ -107,6 +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 | ||||
|         _ -> continue ui | ||||
| 
 | ||||
| esHandle _ _ = error "event handler called with wrong screen type, should not happen" | ||||
|  | ||||
| @ -282,6 +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 ev              -> do ed' <- handleEditorEvent ev ed | ||||
|                                        continue $ ui{aMode=Minibuffer ed'} | ||||
|         AppEvent _        -> continue ui | ||||
| @ -292,6 +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 | ||||
|         _                    -> helpHandle ui ev | ||||
| 
 | ||||
|     Normal -> | ||||
| @ -336,6 +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 | ||||
| 
 | ||||
|         -- enter transaction screen for selected transaction | ||||
|         VtyEvent e | e `elem` moveRightEvents -> do | ||||
|  | ||||
| @ -120,6 +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 | ||||
|         _                    -> helpHandle ui ev | ||||
| 
 | ||||
|     _ -> do | ||||
| @ -180,6 +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 | ||||
|         _ -> continue ui | ||||
| 
 | ||||
| tsHandle _ _ = error "event handler called with wrong screen type, should not happen" | ||||
|  | ||||
| @ -21,6 +21,8 @@ module Hledger.UI.UIUtils ( | ||||
|   ,renderToggle | ||||
|   ,replaceHiddenAccountsNameWith | ||||
|   ,scrollSelectionToMiddle | ||||
|   ,suspend | ||||
|   ,suspendAndRedraw | ||||
|   ,redraw | ||||
| ) | ||||
| where | ||||
| @ -50,6 +52,35 @@ 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. | ||||
| #ifdef mingw32_HOST_OS | ||||
| suspend :: IO () | ||||
| suspend = return () | ||||
| #else | ||||
| import System.Posix.Signals | ||||
| suspend :: IO () | ||||
| suspend = 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 | ||||
| 
 | ||||
| -- | Tell vty to redraw the whole screen, and continue. | ||||
| redraw :: s -> EventM a (Next s) | ||||
| @ -74,7 +105,7 @@ helpDialog _copts = | ||||
|     render $ | ||||
|       withDefAttr "help" $ | ||||
|       renderDialog (dialog (Just "Help (?/LEFT/ESC to close)") Nothing (c^.availWidthL)) $ -- (Just (0,[("ok",())])) | ||||
|       padAll 1 $ | ||||
|       padTop (Pad 1) $ padLeft (Pad 1) $ padRight (Pad 1) $ | ||||
|         vBox [ | ||||
|            hBox [ | ||||
|               padRight (Pad 1) $ | ||||
| @ -120,8 +151,9 @@ helpDialog _copts = | ||||
|                   ,renderKey ("A   ", "add transaction (hledger-iadd)") | ||||
|                   ,renderKey ("E   ", "open editor") | ||||
|                   ,renderKey ("I   ", "toggle balance assertions") | ||||
|                   ,renderKey ("C-l ", "redraw & recenter") | ||||
|                   ,renderKey ("g   ", "reload data") | ||||
|                   ,renderKey ("C-l ", "redraw & recenter") | ||||
|                   ,renderKey ("C-z ", "suspend") | ||||
|                   ,renderKey ("q   ", "quit") | ||||
|                 ] | ||||
|              ] | ||||
|  | ||||
| @ -4,7 +4,7 @@ cabal-version: 1.12 | ||||
| -- | ||||
| -- see: https://github.com/sol/hpack | ||||
| -- | ||||
| -- hash: 9e7f4d999a8b69e7adb4b03f99c96b7ae47113f1b11fe7ddb289e352b2632e7c | ||||
| -- hash: cb5960060c369ce0540af1659e44ad678d26cbc9dca2e8481fe8657bc8fc13ab | ||||
| 
 | ||||
| name:           hledger-ui | ||||
| version:        1.12.99 | ||||
| @ -95,6 +95,7 @@ executable hledger-ui | ||||
|   else | ||||
|     build-depends: | ||||
|         brick >=0.12 | ||||
|       , unix | ||||
|       , vty >=5.5 | ||||
|   if flag(threaded) | ||||
|     ghc-options: -threaded | ||||
|  | ||||
| @ -82,6 +82,7 @@ when: | ||||
|    else: | ||||
|      dependencies: | ||||
|        - brick >=0.12 | ||||
|        - unix | ||||
|        - vty >=5.5 | ||||
| 
 | ||||
| executables: | ||||
|  | ||||
		Loading…
	
		Reference in New Issue
	
	Block a user