ui: ESC now restores exactly to initial app state (#1286)

Also resetFilter (DEL/BS key) no longer changes tree/list mode.
This commit is contained in:
Simon Michael 2020-07-18 12:24:37 -07:00
parent bac3028704
commit 7868da2a48
5 changed files with 24 additions and 16 deletions

View File

@ -136,7 +136,8 @@ runBrickUi uopts@UIOpts{cliopts_=copts@CliOpts{inputopts_=_iopts,reportopts_=rop
ascr' = aScreen $ ascr' = aScreen $
asInit d True asInit d True
UIState{ UIState{
aopts=uopts' astartupopts=uopts'
,aopts=uopts'
,ajournal=j ,ajournal=j
,aScreen=asSetSelectedAccount acct accountsScreen ,aScreen=asSetSelectedAccount acct accountsScreen
,aPrevScreens=[] ,aPrevScreens=[]
@ -147,7 +148,8 @@ runBrickUi uopts@UIOpts{cliopts_=copts@CliOpts{inputopts_=_iopts,reportopts_=rop
(sInit scr) d True $ (sInit scr) d True $
(if change_ uopts' then toggleHistorical else id) -- XXX (if change_ uopts' then toggleHistorical else id) -- XXX
UIState{ UIState{
aopts=uopts' astartupopts=uopts'
,aopts=uopts'
,ajournal=j ,ajournal=j
,aScreen=scr ,aScreen=scr
,aPrevScreens=prevscrs ,aPrevScreens=prevscrs

View File

@ -245,18 +245,22 @@ setFilter :: String -> UIState -> UIState
setFilter s ui@UIState{aopts=uopts@UIOpts{cliopts_=copts@CliOpts{reportopts_=ropts}}} = setFilter s ui@UIState{aopts=uopts@UIOpts{cliopts_=copts@CliOpts{reportopts_=ropts}}} =
ui{aopts=uopts{cliopts_=copts{reportopts_=ropts{query_=s}}}} ui{aopts=uopts{cliopts_=copts{reportopts_=ropts{query_=s}}}}
-- | Clear all filters/flags. -- | Reset some filters & toggles.
resetFilter :: UIState -> UIState resetFilter :: UIState -> UIState
resetFilter ui@UIState{aopts=uopts@UIOpts{cliopts_=copts@CliOpts{reportopts_=ropts}}} = resetFilter ui@UIState{aopts=uopts@UIOpts{cliopts_=copts@CliOpts{reportopts_=ropts}}} =
ui{aopts=uopts{cliopts_=copts{reportopts_=ropts{ ui{aopts=uopts{cliopts_=copts{reportopts_=ropts{
accountlistmode_=ALFlat empty_=True
,empty_=True
,statuses_=[] ,statuses_=[]
,real_=False ,real_=False
,query_="" ,query_=""
--,period_=PeriodAll --,period_=PeriodAll
}}}} }}}}
-- | Reset all options state to exactly what it was at startup
-- (preserving any command-line options/arguments).
resetOpts :: UIState -> UIState
resetOpts ui@UIState{astartupopts} = ui{aopts=astartupopts}
resetDepth :: UIState -> UIState resetDepth :: UIState -> UIState
resetDepth ui@UIState{aopts=uopts@UIOpts{cliopts_=copts@CliOpts{reportopts_=ropts}}} = resetDepth ui@UIState{aopts=uopts@UIOpts{cliopts_=copts@CliOpts{reportopts_=ropts}}} =
ui{aopts=uopts{cliopts_=copts{reportopts_=ropts{depth_=Nothing}}}} ui{aopts=uopts{cliopts_=copts{reportopts_=ropts{depth_=Nothing}}}}
@ -345,7 +349,9 @@ popScreen ui = ui
resetScreens :: Day -> UIState -> UIState resetScreens :: Day -> UIState -> UIState
resetScreens d ui@UIState{aScreen=s,aPrevScreens=ss} = resetScreens d ui@UIState{aScreen=s,aPrevScreens=ss} =
(sInit topscreen) d True $ resetDepth $ resetReportPeriod $ resetFilter $ closeMinibuffer ui{aScreen=topscreen, aPrevScreens=[]} (sInit topscreen) d True $
resetOpts $
closeMinibuffer ui{aScreen=topscreen, aPrevScreens=[]}
where where
topscreen = case ss of _:_ -> last ss topscreen = case ss of _:_ -> last ss
[] -> s [] -> s

View File

@ -54,7 +54,8 @@ import Hledger.UI.UIOptions
-- The app can be in one of several modes: normal screen operation, -- The app can be in one of several modes: normal screen operation,
-- showing a help dialog, entering data in the minibuffer etc. -- showing a help dialog, entering data in the minibuffer etc.
data UIState = UIState { data UIState = UIState {
aopts :: UIOpts -- ^ the command-line options and query arguments currently in effect astartupopts :: UIOpts -- ^ the command-line options and query arguments specified at startup
,aopts :: UIOpts -- ^ the command-line options and query arguments currently in effect
,ajournal :: Journal -- ^ the journal being viewed ,ajournal :: Journal -- ^ the journal being viewed
,aPrevScreens :: [Screen] -- ^ previously visited screens, most recent first ,aPrevScreens :: [Screen] -- ^ previously visited screens, most recent first
,aScreen :: Screen -- ^ the currently active screen ,aScreen :: Screen -- ^ the currently active screen

View File

@ -98,11 +98,10 @@ helpDialog _copts =
vBox [ vBox [
withAttr ("help" <> "heading") $ str "Navigation" withAttr ("help" <> "heading") $ str "Navigation"
,renderKey ("UP/DOWN/PUP/PDN/HOME/END/k/j/C-p/C-n", "") ,renderKey ("UP/DOWN/PUP/PDN/HOME/END/k/j/C-p/C-n", "")
,str " move selection up/down" ,str " move selection up/down"
,renderKey ("RIGHT/l/C-f", "") ,renderKey ("RIGHT/l/C-f", "show txns, or txn detail")
,str " show account txns, or txn detail"
,renderKey ("LEFT/h/C-b ", "go back") ,renderKey ("LEFT/h/C-b ", "go back")
,renderKey ("ESC ", "cancel or reset") ,renderKey ("ESC ", "cancel or reset to initial state")
,str " " ,str " "
,withAttr ("help" <> "heading") $ str "Accounts screen" ,withAttr ("help" <> "heading") $ str "Accounts screen"
@ -168,15 +167,14 @@ helpHandle :: UIState -> BrickEvent Name AppEvent -> EventM Name (Next UIState)
helpHandle ui ev = do helpHandle ui ev = do
pagerprog <- liftIO $ fromMaybe "less" <$> lookupEnv "PAGER" pagerprog <- liftIO $ fromMaybe "less" <$> lookupEnv "PAGER"
case ev of case ev of
VtyEvent e VtyEvent e | e `elem` closeHelpEvents -> continue $ setMode Normal ui
| e `elem` (moveLeftEvents ++ [EvKey KEsc [], EvKey (KChar '?') [], EvKey (KChar 'q') []])
-> continue $ setMode Normal ui
VtyEvent (EvKey (KChar 'p') []) -> suspendAndResume $ runPagerForTopic pagerprog "hledger-ui" >> return ui' VtyEvent (EvKey (KChar 'p') []) -> suspendAndResume $ runPagerForTopic pagerprog "hledger-ui" >> return ui'
VtyEvent (EvKey (KChar 'm') []) -> suspendAndResume $ runManForTopic "hledger-ui" >> return ui' VtyEvent (EvKey (KChar 'm') []) -> suspendAndResume $ runManForTopic "hledger-ui" >> return ui'
VtyEvent (EvKey (KChar 'i') []) -> suspendAndResume $ runInfoForTopic "hledger-ui" >> return ui' VtyEvent (EvKey (KChar 'i') []) -> suspendAndResume $ runInfoForTopic "hledger-ui" >> return ui'
_ -> continue ui _ -> continue ui
where where
ui' = setMode Normal ui ui' = setMode Normal ui
closeHelpEvents = moveLeftEvents ++ [EvKey KEsc [], EvKey (KChar '?') [], EvKey (KChar 'q') []]
-- | Draw the minibuffer. -- | Draw the minibuffer.
minibuffer :: Editor String Name -> Widget Name minibuffer :: Editor String Name -> Widget Name

View File

@ -131,8 +131,9 @@ both ordinary transactions recorded in the journal, and periodic
transactions generated by rule. `f` toggles forecast mode, in which transactions generated by rule. `f` toggles forecast mode, in which
future/forecasted transactions are shown. *(experimental)* future/forecasted transactions are shown. *(experimental)*
`escape` removes all filters and report period limits and jumps back to the top screen. `escape` resets the UI state and jumps back to the top screen,
Or, it cancels minibuffer data entry or a help popup. restoring the app's initial state at startup.
Or, it cancels minibuffer data entry or the help dialog.
`ctrl-l` redraws the screen and centers the selection if possible `ctrl-l` redraws the screen and centers the selection if possible
(selections near the top won't be centered, since we don't scroll above the top). (selections near the top won't be centered, since we don't scroll above the top).