ui: C-z suspend now restores the terminal cleanly

This commit is contained in:
Simon Michael 2019-01-23 17:25:20 -08:00
parent f7c22f97dc
commit ad424e0381
5 changed files with 23 additions and 36 deletions

View File

@ -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

View File

@ -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"

View File

@ -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

View File

@ -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"

View File

@ -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