mirror of
https://github.com/simonmichael/hledger.git
synced 2024-11-09 00:15:48 +03:00
ui: Esc (outside minibuffer) resets, jumps to top
This commit is contained in:
parent
579ab45d0a
commit
bbcbaf6080
@ -49,8 +49,8 @@ screen = AccountsScreen{
|
||||
asSetSelectedAccount a scr@AccountsScreen{asState=(l,_)} = scr{asState=(l,a)}
|
||||
asSetSelectedAccount _ scr = scr
|
||||
|
||||
initAccountsScreen :: Day -> AppState -> AppState
|
||||
initAccountsScreen d st@AppState{
|
||||
initAccountsScreen :: Day -> Bool -> AppState -> AppState
|
||||
initAccountsScreen d reset st@AppState{
|
||||
aopts=uopts@UIOpts{cliopts_=copts@CliOpts{reportopts_=ropts}},
|
||||
ajournal=j,
|
||||
aScreen=s@AccountsScreen{asState=(oldl,selacct)}
|
||||
@ -63,9 +63,10 @@ initAccountsScreen d st@AppState{
|
||||
-- (may need to move to the next leaf account when entering flat mode)
|
||||
newl' = listMoveTo selidx newl
|
||||
where
|
||||
selidx = case listSelectedElement oldl of
|
||||
Nothing -> 0
|
||||
Just (_,(_,a,_,_)) -> fromMaybe (fromMaybe 0 mprefixmatch) mexactmatch
|
||||
selidx = case (reset, listSelectedElement oldl) of
|
||||
(True, _) -> 0
|
||||
(_, Nothing) -> 0
|
||||
(_, Just (_,(_,a,_,_))) -> fromMaybe (fromMaybe 0 mprefixmatch) mexactmatch
|
||||
where
|
||||
mexactmatch = findIndex ((a ==) . second4) displayitems
|
||||
mprefixmatch = findIndex ((a `isAccountNamePrefixOf`) . second4) displayitems
|
||||
@ -99,7 +100,7 @@ initAccountsScreen d st@AppState{
|
||||
displayitems = map displayitem items
|
||||
|
||||
|
||||
initAccountsScreen _ _ = error "init function called with wrong screen type, should not happen"
|
||||
initAccountsScreen _ _ _ = error "init function called with wrong screen type, should not happen"
|
||||
|
||||
drawAccountsScreen :: AppState -> [Widget]
|
||||
drawAccountsScreen AppState{aopts=UIOpts{cliopts_=CliOpts{reportopts_=ropts}}
|
||||
@ -153,6 +154,7 @@ drawAccountsScreen AppState{aopts=UIOpts{cliopts_=CliOpts{reportopts_=ropts}}
|
||||
,("/", "filter")
|
||||
,("DEL", "unfilter")
|
||||
,("right/enter", "register")
|
||||
,("ESC", "cancel/top")
|
||||
,("g", "reload")
|
||||
,("q", "quit")
|
||||
]
|
||||
@ -253,6 +255,7 @@ handleAccountsScreen st@AppState{
|
||||
case ev of
|
||||
Vty.EvKey (Vty.KChar 'q') [] -> halt st'
|
||||
-- Vty.EvKey (Vty.KChar 'l') [Vty.MCtrl] -> do
|
||||
Vty.EvKey Vty.KEsc [] -> continue $ resetScreens d st'
|
||||
|
||||
Vty.EvKey (Vty.KChar 'g') [] -> do
|
||||
(ej, _) <- liftIO $ journalReloadIfChanged copts d j
|
||||
|
@ -33,9 +33,9 @@ screen = ErrorScreen{
|
||||
,sHandleFn = handleErrorScreen
|
||||
}
|
||||
|
||||
initErrorScreen :: Day -> AppState -> AppState
|
||||
initErrorScreen _ st@AppState{aScreen=ErrorScreen{}} = st
|
||||
initErrorScreen _ _ = error "init function called with wrong screen type, should not happen"
|
||||
initErrorScreen :: Day -> Bool -> AppState -> AppState
|
||||
initErrorScreen _ _ st@AppState{aScreen=ErrorScreen{}} = st
|
||||
initErrorScreen _ _ _ = error "init function called with wrong screen type, should not happen"
|
||||
|
||||
drawErrorScreen :: AppState -> [Widget]
|
||||
drawErrorScreen AppState{ -- aopts=_uopts@UIOpts{cliopts_=_copts@CliOpts{reportopts_=_ropts@ReportOpts{query_=querystr}}},
|
||||
@ -103,12 +103,12 @@ handleErrorScreen st@AppState{
|
||||
,aopts=UIOpts{cliopts_=copts}
|
||||
,ajournal=j
|
||||
} e = do
|
||||
d <- liftIO getCurrentDay
|
||||
case e of
|
||||
Vty.EvKey Vty.KEsc [] -> halt st
|
||||
Vty.EvKey (Vty.KChar 'q') [] -> halt st
|
||||
Vty.EvKey Vty.KEsc [] -> continue $ resetScreens d st
|
||||
|
||||
Vty.EvKey (Vty.KChar 'g') [] -> do
|
||||
d <- liftIO getCurrentDay
|
||||
(ej, _) <- liftIO $ journalReloadIfChanged copts d j
|
||||
case ej of
|
||||
Left err -> continue st{aScreen=s{esState=err}} -- show latest parse error
|
||||
|
@ -109,7 +109,7 @@ runBrickUi uopts@UIOpts{cliopts_=copts@CliOpts{reportopts_=ropts}} j = do
|
||||
-- Initialising the accounts screen is awkward, requiring
|
||||
-- another temporary AppState value..
|
||||
ascr' = aScreen $
|
||||
AS.initAccountsScreen d $
|
||||
AS.initAccountsScreen d True $
|
||||
AppState{
|
||||
aopts=uopts'
|
||||
,ajournal=j
|
||||
@ -118,7 +118,7 @@ runBrickUi uopts@UIOpts{cliopts_=copts@CliOpts{reportopts_=ropts}} j = do
|
||||
,aMinibuffer=Nothing
|
||||
}
|
||||
|
||||
st = (sInitFn scr) d
|
||||
st = (sInitFn scr) d True
|
||||
AppState{
|
||||
aopts=uopts'
|
||||
,ajournal=j
|
||||
|
@ -45,8 +45,8 @@ screen = RegisterScreen{
|
||||
rsSetCurrentAccount a scr@RegisterScreen{rsState=(l,_)} = scr{rsState=(l,a)}
|
||||
rsSetCurrentAccount _ scr = scr
|
||||
|
||||
initRegisterScreen :: Day -> AppState -> AppState
|
||||
initRegisterScreen d st@AppState{aopts=opts, ajournal=j, aScreen=s@RegisterScreen{rsState=(oldl,acct)}} =
|
||||
initRegisterScreen :: Day -> Bool -> AppState -> AppState
|
||||
initRegisterScreen d reset st@AppState{aopts=opts, ajournal=j, aScreen=s@RegisterScreen{rsState=(oldl,acct)}} =
|
||||
st{aScreen=s{rsState=(newl',acct)}}
|
||||
where
|
||||
-- gather arguments and queries
|
||||
@ -86,12 +86,13 @@ initRegisterScreen d st@AppState{aopts=opts, ajournal=j, aScreen=s@RegisterScree
|
||||
-- (eg after toggling nonzero mode), otherwise select the last element.
|
||||
newl' = listMoveTo newselidx newl
|
||||
where
|
||||
newselidx = case listSelectedElement oldl of
|
||||
Nothing -> endidx
|
||||
Just (_,(_,_,_,_,_,Transaction{tindex=ti})) -> fromMaybe endidx $ findIndex ((==ti) . tindex . sixth6) displayitems
|
||||
newselidx = case (reset, listSelectedElement oldl) of
|
||||
(True, _) -> 0
|
||||
(_, Nothing) -> endidx
|
||||
(_, Just (_,(_,_,_,_,_,Transaction{tindex=ti}))) -> fromMaybe endidx $ findIndex ((==ti) . tindex . sixth6) displayitems
|
||||
endidx = length displayitems
|
||||
|
||||
initRegisterScreen _ _ = error "init function called with wrong screen type, should not happen"
|
||||
initRegisterScreen _ _ _ = error "init function called with wrong screen type, should not happen"
|
||||
|
||||
drawRegisterScreen :: AppState -> [Widget]
|
||||
drawRegisterScreen AppState{aopts=UIOpts{cliopts_=CliOpts{reportopts_=ropts}}
|
||||
@ -182,6 +183,7 @@ drawRegisterScreen AppState{aopts=UIOpts{cliopts_=CliOpts{reportopts_=ropts}}
|
||||
,("/", "filter")
|
||||
,("DEL", "unfilter")
|
||||
,("right/enter", "transaction")
|
||||
,("ESC", "cancel/top")
|
||||
,("g", "reload")
|
||||
,("q", "quit")
|
||||
]
|
||||
@ -228,6 +230,7 @@ handleRegisterScreen st@AppState{
|
||||
|
||||
case ev of
|
||||
Vty.EvKey (Vty.KChar 'q') [] -> halt st
|
||||
Vty.EvKey Vty.KEsc [] -> continue $ resetScreens d st
|
||||
|
||||
Vty.EvKey (Vty.KChar 'g') [] -> do
|
||||
(ej, _) <- liftIO $ journalReloadIfChanged copts d j
|
||||
|
@ -42,13 +42,13 @@ screen = TransactionScreen{
|
||||
,sHandleFn = handleTransactionScreen
|
||||
}
|
||||
|
||||
initTransactionScreen :: Day -> AppState -> AppState
|
||||
initTransactionScreen _d st@AppState{aopts=UIOpts{cliopts_=CliOpts{reportopts_=_ropts}}
|
||||
initTransactionScreen :: Day -> Bool -> AppState -> AppState
|
||||
initTransactionScreen _d _reset st@AppState{aopts=UIOpts{cliopts_=CliOpts{reportopts_=_ropts}}
|
||||
,ajournal=_j
|
||||
,aScreen=s@TransactionScreen{tsState=((n,t),nts,a)}} =
|
||||
st{aScreen=s{tsState=((n,t),nts,a)}}
|
||||
|
||||
initTransactionScreen _ _ = error "init function called with wrong screen type, should not happen"
|
||||
initTransactionScreen _ _ _ = error "init function called with wrong screen type, should not happen"
|
||||
|
||||
drawTransactionScreen :: AppState -> [Widget]
|
||||
drawTransactionScreen AppState{aopts=UIOpts{cliopts_=CliOpts{reportopts_=ropts}}
|
||||
@ -104,8 +104,8 @@ handleTransactionScreen st@AppState{
|
||||
(iprev,tprev) = maybe (i,t) ((i-1),) $ lookup (i-1) nts
|
||||
(inext,tnext) = maybe (i,t) ((i+1),) $ lookup (i+1) nts
|
||||
case e of
|
||||
Vty.EvKey Vty.KEsc [] -> halt st
|
||||
Vty.EvKey (Vty.KChar 'q') [] -> halt st
|
||||
Vty.EvKey Vty.KEsc [] -> continue $ resetScreens d st
|
||||
|
||||
Vty.EvKey (Vty.KChar 'g') [] -> do
|
||||
d <- liftIO getCurrentDay
|
||||
|
@ -70,7 +70,8 @@ data Screen =
|
||||
)
|
||||
,AccountName -- full name of the currently selected account (or "")
|
||||
)
|
||||
,sInitFn :: Day -> AppState -> AppState -- ^ function to generate the screen's state on entry or change
|
||||
,sInitFn :: Day -> Bool -> AppState -> AppState -- ^ function to generate/update the screen's state,
|
||||
-- takes the current date and whether to reset the selection.
|
||||
,sDrawFn :: AppState -> [Widget] -- ^ brick renderer to use for this screen
|
||||
,sHandleFn :: AppState -> V.Event -> EventM (Next AppState) -- ^ brick event handler to use for this screen
|
||||
}
|
||||
@ -85,22 +86,22 @@ data Screen =
|
||||
)
|
||||
,AccountName -- full name of the acct we are showing a register for
|
||||
)
|
||||
,sInitFn :: Day -> AppState -> AppState -- ^ function to generate the screen's state on entry or change
|
||||
,sDrawFn :: AppState -> [Widget] -- ^ brick renderer to use for this screen
|
||||
,sHandleFn :: AppState -> V.Event -> EventM (Next AppState) -- ^ brick event handler to use for this screen
|
||||
,sInitFn :: Day -> Bool -> AppState -> AppState
|
||||
,sDrawFn :: AppState -> [Widget]
|
||||
,sHandleFn :: AppState -> V.Event -> EventM (Next AppState)
|
||||
}
|
||||
| TransactionScreen {
|
||||
tsState :: ((Integer, Transaction) -- the (numbered) transaction we are currently viewing
|
||||
,[(Integer, Transaction)] -- the list of numbered transactions we can step through
|
||||
,AccountName -- the account whose register we entered this screen from
|
||||
)
|
||||
,sInitFn :: Day -> AppState -> AppState
|
||||
,sInitFn :: Day -> Bool -> AppState -> AppState
|
||||
,sDrawFn :: AppState -> [Widget]
|
||||
,sHandleFn :: AppState -> V.Event -> EventM (Next AppState)
|
||||
}
|
||||
| ErrorScreen {
|
||||
esState :: String -- error message to display
|
||||
,sInitFn :: Day -> AppState -> AppState
|
||||
,sInitFn :: Day -> Bool -> AppState -> AppState
|
||||
,sDrawFn :: AppState -> [Widget]
|
||||
,sHandleFn :: AppState -> V.Event -> EventM (Next AppState)
|
||||
}
|
||||
|
@ -3,6 +3,7 @@
|
||||
module Hledger.UI.UIUtils (
|
||||
pushScreen
|
||||
,popScreen
|
||||
,resetScreens
|
||||
,screenEnter
|
||||
,reload
|
||||
,getViewportSize
|
||||
@ -23,6 +24,7 @@ module Hledger.UI.UIUtils (
|
||||
,stToggleFlat
|
||||
,stToggleReal
|
||||
,stFilter
|
||||
,stResetFilter
|
||||
,stShowMinibuffer
|
||||
,stHideMinibuffer
|
||||
) where
|
||||
@ -98,6 +100,22 @@ stFilter :: String -> AppState -> AppState
|
||||
stFilter s st@AppState{aopts=uopts@UIOpts{cliopts_=copts@CliOpts{reportopts_=ropts}}} =
|
||||
st{aopts=uopts{cliopts_=copts{reportopts_=ropts{query_=s}}}}
|
||||
|
||||
-- | Clear all filter queries/flags.
|
||||
stResetFilter :: AppState -> AppState
|
||||
stResetFilter st@AppState{aopts=uopts@UIOpts{cliopts_=copts@CliOpts{reportopts_=ropts}}} =
|
||||
st{aopts=uopts{cliopts_=copts{reportopts_=ropts{
|
||||
empty_=True
|
||||
,cleared_=False
|
||||
,pending_=False
|
||||
,uncleared_=False
|
||||
,real_=False
|
||||
,query_=""
|
||||
}}}}
|
||||
|
||||
stResetDepth :: AppState -> AppState
|
||||
stResetDepth st@AppState{aopts=uopts@UIOpts{cliopts_=copts@CliOpts{reportopts_=ropts}}} =
|
||||
st{aopts=uopts{cliopts_=copts{reportopts_=ropts{depth_=Nothing}}}}
|
||||
|
||||
-- | Enable the minibuffer, setting its content to the current query with the cursor at the end.
|
||||
stShowMinibuffer st = st{aMinibuffer=Just e}
|
||||
where
|
||||
@ -117,8 +135,8 @@ reload j d st@AppState{aScreen=s,aPrevScreens=ss} =
|
||||
let
|
||||
first:rest = reverse $ s:ss
|
||||
st0 = st{ajournal=j, aScreen=first, aPrevScreens=[]}
|
||||
st1 = (sInitFn first) d st0
|
||||
st2 = foldl' (\st s -> (sInitFn s) d $ pushScreen s st) st1 rest
|
||||
st1 = (sInitFn first) d False st0
|
||||
st2 = foldl' (\st s -> (sInitFn s) d False $ pushScreen s st) st1 rest
|
||||
in
|
||||
st2
|
||||
|
||||
@ -131,13 +149,20 @@ popScreen :: AppState -> AppState
|
||||
popScreen st@AppState{aPrevScreens=s:ss} = st{aScreen=s, aPrevScreens=ss}
|
||||
popScreen st = st
|
||||
|
||||
resetScreens :: Day -> AppState -> AppState
|
||||
resetScreens d st@AppState{aScreen=s,aPrevScreens=ss} =
|
||||
(sInitFn topscreen) d True $ stResetDepth $ stResetFilter $ stHideMinibuffer st{aScreen=topscreen, aPrevScreens=[]}
|
||||
where
|
||||
topscreen = case ss of _:_ -> last ss
|
||||
[] -> s
|
||||
|
||||
-- clearScreens :: AppState -> AppState
|
||||
-- clearScreens st = st{aPrevScreens=[]}
|
||||
|
||||
-- | Enter a new screen, saving the old screen & state in the
|
||||
-- navigation history and initialising the new screen's state.
|
||||
screenEnter :: Day -> Screen -> AppState -> AppState
|
||||
screenEnter d scr st = (sInitFn scr) d $
|
||||
screenEnter d scr st = (sInitFn scr) d True $
|
||||
pushScreen scr
|
||||
st
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user