ui: allow the filter query to be changed
This commit is contained in:
		
							parent
							
								
									606036e1a2
								
							
						
					
					
						commit
						9131eb7c67
					
				| @ -25,6 +25,7 @@ import qualified Data.Vector as V | |||||||
| import Graphics.Vty as Vty | import Graphics.Vty as Vty | ||||||
| import Brick | import Brick | ||||||
| import Brick.Widgets.List | import Brick.Widgets.List | ||||||
|  | import Brick.Widgets.Edit | ||||||
| import Brick.Widgets.Border (borderAttr) | import Brick.Widgets.Border (borderAttr) | ||||||
| -- import Brick.Widgets.Center | -- import Brick.Widgets.Center | ||||||
| 
 | 
 | ||||||
| @ -103,7 +104,8 @@ initAccountsScreen _ _ = error "init function called with wrong screen type, sho | |||||||
| drawAccountsScreen :: AppState -> [Widget] | drawAccountsScreen :: AppState -> [Widget] | ||||||
| drawAccountsScreen AppState{aopts=UIOpts{cliopts_=CliOpts{reportopts_=ropts}} | drawAccountsScreen AppState{aopts=UIOpts{cliopts_=CliOpts{reportopts_=ropts}} | ||||||
|                            ,ajournal=j |                            ,ajournal=j | ||||||
|                            ,aScreen=AccountsScreen{asState=(l,_)}} = |                            ,aScreen=AccountsScreen{asState=(l,_)} | ||||||
|  |                            ,aMinibuffer=mbuf} = | ||||||
|   [ui] |   [ui] | ||||||
|     where |     where | ||||||
|       toplabel = files |       toplabel = files | ||||||
| @ -148,11 +150,16 @@ drawAccountsScreen AppState{aopts=UIOpts{cliopts_=CliOpts{reportopts_=ropts}} | |||||||
|         ,("C", "cleared?") |         ,("C", "cleared?") | ||||||
|         ,("U", "uncleared?") |         ,("U", "uncleared?") | ||||||
|         ,("R", "real?") |         ,("R", "real?") | ||||||
|  |         ,("f", "filter") | ||||||
|         ,("right/enter", "register") |         ,("right/enter", "register") | ||||||
|         ,("g", "reload") |         ,("g", "reload") | ||||||
|         ,("q", "quit") |         ,("q", "quit") | ||||||
|         ] |         ] | ||||||
| 
 | 
 | ||||||
|  |       bottomarea = case mbuf of | ||||||
|  |                     Nothing  -> bottomlabel | ||||||
|  |                     Just ed  -> minibuffer ed | ||||||
|  | 
 | ||||||
|       ui = Widget Greedy Greedy $ do |       ui = Widget Greedy Greedy $ do | ||||||
|         c <- getContext |         c <- getContext | ||||||
|         let |         let | ||||||
| @ -188,7 +195,7 @@ drawAccountsScreen AppState{aopts=UIOpts{cliopts_=CliOpts{reportopts_=ropts}} | |||||||
| 
 | 
 | ||||||
|           colwidths = (acctwidth, balwidth) |           colwidths = (acctwidth, balwidth) | ||||||
| 
 | 
 | ||||||
|         render $ defaultLayout toplabel bottomlabel $ renderList l (drawAccountsItem colwidths) |         render $ defaultLayout toplabel bottomarea $ renderList l (drawAccountsItem colwidths) | ||||||
| 
 | 
 | ||||||
| drawAccountsScreen _ = error "draw function called with wrong screen type, should not happen" | drawAccountsScreen _ = error "draw function called with wrong screen type, should not happen" | ||||||
| 
 | 
 | ||||||
| @ -224,7 +231,8 @@ handleAccountsScreen st@AppState{ | |||||||
|    aScreen=scr@AccountsScreen{asState=(l,selacct)} |    aScreen=scr@AccountsScreen{asState=(l,selacct)} | ||||||
|   ,aopts=UIOpts{cliopts_=copts} |   ,aopts=UIOpts{cliopts_=copts} | ||||||
|   ,ajournal=j |   ,ajournal=j | ||||||
|   } e = do |   ,aMinibuffer=mbuf | ||||||
|  |   } ev = do | ||||||
|     d <- liftIO getCurrentDay |     d <- liftIO getCurrentDay | ||||||
|     -- c <- getContext |     -- c <- getContext | ||||||
|     -- let h = c^.availHeightL |     -- let h = c^.availHeightL | ||||||
| @ -238,48 +246,60 @@ handleAccountsScreen st@AppState{ | |||||||
|                   Nothing -> selacct |                   Nothing -> selacct | ||||||
|       st' = st{aScreen=scr{asState=(l,selacct')}} |       st' = st{aScreen=scr{asState=(l,selacct')}} | ||||||
| 
 | 
 | ||||||
|     case e of |     case mbuf of | ||||||
|         Vty.EvKey Vty.KEsc []        -> halt st' |       Nothing -> | ||||||
|         Vty.EvKey (Vty.KChar 'q') [] -> halt st' |  | ||||||
|         -- Vty.EvKey (Vty.KChar 'l') [Vty.MCtrl] -> do |  | ||||||
| 
 | 
 | ||||||
|         Vty.EvKey (Vty.KChar 'g') [] -> do |         case ev of | ||||||
|           (ej, _) <- liftIO $ journalReloadIfChanged copts d j |             Vty.EvKey (Vty.KChar 'q') [] -> halt st' | ||||||
|           case ej of |             -- Vty.EvKey (Vty.KChar 'l') [Vty.MCtrl] -> do | ||||||
|             Right j' -> continue $ reload j' d st' |  | ||||||
|             Left err -> continue $ screenEnter d ES.screen{esState=err} st' |  | ||||||
| 
 | 
 | ||||||
|         Vty.EvKey (Vty.KChar '-') [] -> continue $ reload j d $ decDepth st' |             Vty.EvKey (Vty.KChar 'g') [] -> do | ||||||
|         Vty.EvKey (Vty.KChar '+') [] -> continue $ reload j d $ incDepth st' |               (ej, _) <- liftIO $ journalReloadIfChanged copts d j | ||||||
|         Vty.EvKey (Vty.KChar '=') [] -> continue $ reload j d $ incDepth st' |               case ej of | ||||||
|         Vty.EvKey (Vty.KChar '1') [] -> continue $ reload j d $ setDepth 1 st' |                 Right j' -> continue $ reload j' d st' | ||||||
|         Vty.EvKey (Vty.KChar '2') [] -> continue $ reload j d $ setDepth 2 st' |                 Left err -> continue $ screenEnter d ES.screen{esState=err} st' | ||||||
|         Vty.EvKey (Vty.KChar '3') [] -> continue $ reload j d $ setDepth 3 st' | 
 | ||||||
|         Vty.EvKey (Vty.KChar '4') [] -> continue $ reload j d $ setDepth 4 st' |             Vty.EvKey (Vty.KChar '-') [] -> continue $ reload j d $ decDepth st' | ||||||
|         Vty.EvKey (Vty.KChar '5') [] -> continue $ reload j d $ setDepth 5 st' |             Vty.EvKey (Vty.KChar '+') [] -> continue $ reload j d $ incDepth st' | ||||||
|         Vty.EvKey (Vty.KChar '6') [] -> continue $ reload j d $ setDepth 6 st' |             Vty.EvKey (Vty.KChar '=') [] -> continue $ reload j d $ incDepth st' | ||||||
|         Vty.EvKey (Vty.KChar '7') [] -> continue $ reload j d $ setDepth 7 st' |             Vty.EvKey (Vty.KChar '1') [] -> continue $ reload j d $ setDepth 1 st' | ||||||
|         Vty.EvKey (Vty.KChar '8') [] -> continue $ reload j d $ setDepth 8 st' |             Vty.EvKey (Vty.KChar '2') [] -> continue $ reload j d $ setDepth 2 st' | ||||||
|         Vty.EvKey (Vty.KChar '9') [] -> continue $ reload j d $ setDepth 9 st' |             Vty.EvKey (Vty.KChar '3') [] -> continue $ reload j d $ setDepth 3 st' | ||||||
|         Vty.EvKey (Vty.KChar '0') [] -> continue $ reload j d $ setDepth 0 st' |             Vty.EvKey (Vty.KChar '4') [] -> continue $ reload j d $ setDepth 4 st' | ||||||
|         Vty.EvKey (Vty.KChar 'F') [] -> continue $ reload j d $ stToggleFlat st' |             Vty.EvKey (Vty.KChar '5') [] -> continue $ reload j d $ setDepth 5 st' | ||||||
|         Vty.EvKey (Vty.KChar 'E') [] -> scrollTop >> (continue $ reload j d $ stToggleEmpty st') |             Vty.EvKey (Vty.KChar '6') [] -> continue $ reload j d $ setDepth 6 st' | ||||||
|         Vty.EvKey (Vty.KChar 'C') [] -> scrollTop >> (continue $ reload j d $ stToggleCleared st') |             Vty.EvKey (Vty.KChar '7') [] -> continue $ reload j d $ setDepth 7 st' | ||||||
|         Vty.EvKey (Vty.KChar 'U') [] -> scrollTop >> (continue $ reload j d $ stToggleUncleared st') |             Vty.EvKey (Vty.KChar '8') [] -> continue $ reload j d $ setDepth 8 st' | ||||||
|         Vty.EvKey (Vty.KChar 'R') [] -> scrollTop >> (continue $ reload j d $ stToggleReal st') |             Vty.EvKey (Vty.KChar '9') [] -> continue $ reload j d $ setDepth 9 st' | ||||||
|         Vty.EvKey (Vty.KLeft) []     -> continue $ popScreen st' |             Vty.EvKey (Vty.KChar '0') [] -> continue $ reload j d $ setDepth 0 st' | ||||||
|         Vty.EvKey (k) [] | k `elem` [Vty.KRight, Vty.KEnter] -> do |             Vty.EvKey (Vty.KChar 'F') [] -> continue $ reload j d $ stToggleFlat st' | ||||||
|           let |             Vty.EvKey (Vty.KChar 'E') [] -> scrollTop >> (continue $ reload j d $ stToggleEmpty st') | ||||||
|             scr = RS.rsSetCurrentAccount selacct' RS.screen |             Vty.EvKey (Vty.KChar 'C') [] -> scrollTop >> (continue $ reload j d $ stToggleCleared st') | ||||||
|             st'' = screenEnter d scr st' |             Vty.EvKey (Vty.KChar 'U') [] -> scrollTop >> (continue $ reload j d $ stToggleUncleared st') | ||||||
|           scrollTopRegister |             Vty.EvKey (Vty.KChar 'R') [] -> scrollTop >> (continue $ reload j d $ stToggleReal st') | ||||||
|           continue st'' |             Vty.EvKey (Vty.KChar 'f') [] -> continue $ reload j d $ stShowMinibuffer st' | ||||||
|  |             Vty.EvKey (Vty.KLeft) []     -> continue $ popScreen st' | ||||||
|  |             Vty.EvKey (k) [] | k `elem` [Vty.KRight, Vty.KEnter] -> do | ||||||
|  |               let | ||||||
|  |                 scr = RS.rsSetCurrentAccount selacct' RS.screen | ||||||
|  |                 st'' = screenEnter d scr st' | ||||||
|  |               scrollTopRegister | ||||||
|  |               continue st'' | ||||||
|  | 
 | ||||||
|  |             -- fall through to the list's event handler (handles up/down) | ||||||
|  |             ev                       -> do | ||||||
|  |                                          l' <- handleEvent ev l | ||||||
|  |                                          continue $ st'{aScreen=scr{asState=(l',selacct')}} | ||||||
|  |                                      -- continue =<< handleEventLensed st' someLens ev | ||||||
|  | 
 | ||||||
|  |       Just ed -> | ||||||
|  |         case ev of | ||||||
|  |             Vty.EvKey Vty.KEsc   [] -> continue $ stHideMinibuffer st' | ||||||
|  |             Vty.EvKey Vty.KEnter [] -> continue $ reload j d $ stFilter s $ stHideMinibuffer st' | ||||||
|  |                                         where s = chomp $ unlines $ getEditContents ed | ||||||
|  |             ev                      -> do ed' <- handleEvent ev ed | ||||||
|  |                                           continue $ st'{aMinibuffer=Just ed'} | ||||||
| 
 | 
 | ||||||
|         -- fall through to the list's event handler (handles up/down) |  | ||||||
|         ev                       -> do |  | ||||||
|                                      l' <- handleEvent ev l |  | ||||||
|                                      continue $ st'{aScreen=scr{asState=(l',selacct')}} |  | ||||||
|                                  -- continue =<< handleEventLensed st' someLens ev |  | ||||||
|   where |   where | ||||||
|     -- Encourage a more stable scroll position when toggling list items. |     -- Encourage a more stable scroll position when toggling list items. | ||||||
|     -- We scroll to the top, and the viewport will automatically |     -- We scroll to the top, and the viewport will automatically | ||||||
|  | |||||||
| @ -115,6 +115,7 @@ runBrickUi uopts@UIOpts{cliopts_=copts@CliOpts{reportopts_=ropts}} j = do | |||||||
|                    ,ajournal=j |                    ,ajournal=j | ||||||
|                    ,aScreen=asSetSelectedAccount acct AS.screen |                    ,aScreen=asSetSelectedAccount acct AS.screen | ||||||
|                    ,aPrevScreens=[] |                    ,aPrevScreens=[] | ||||||
|  |                    ,aMinibuffer=Nothing | ||||||
|                    } |                    } | ||||||
|    |    | ||||||
|     st = (sInitFn scr) d |     st = (sInitFn scr) d | ||||||
| @ -123,6 +124,7 @@ runBrickUi uopts@UIOpts{cliopts_=copts@CliOpts{reportopts_=ropts}} j = do | |||||||
|            ,ajournal=j |            ,ajournal=j | ||||||
|            ,aScreen=scr |            ,aScreen=scr | ||||||
|            ,aPrevScreens=prevscrs |            ,aPrevScreens=prevscrs | ||||||
|  |            ,aMinibuffer=Nothing | ||||||
|            } |            } | ||||||
|           |           | ||||||
|     app :: App (AppState) V.Event |     app :: App (AppState) V.Event | ||||||
|  | |||||||
| @ -21,6 +21,7 @@ import qualified Data.Vector as V | |||||||
| import Graphics.Vty as Vty | import Graphics.Vty as Vty | ||||||
| import Brick | import Brick | ||||||
| import Brick.Widgets.List | import Brick.Widgets.List | ||||||
|  | import Brick.Widgets.Edit | ||||||
| import Brick.Widgets.Border (borderAttr) | import Brick.Widgets.Border (borderAttr) | ||||||
| -- import Brick.Widgets.Center | -- import Brick.Widgets.Center | ||||||
| -- import Text.Printf | -- import Text.Printf | ||||||
| @ -94,12 +95,14 @@ initRegisterScreen _ _ = error "init function called with wrong screen type, sho | |||||||
| 
 | 
 | ||||||
| drawRegisterScreen :: AppState -> [Widget] | drawRegisterScreen :: AppState -> [Widget] | ||||||
| drawRegisterScreen AppState{aopts=UIOpts{cliopts_=CliOpts{reportopts_=ropts}} | drawRegisterScreen AppState{aopts=UIOpts{cliopts_=CliOpts{reportopts_=ropts}} | ||||||
|                            ,aScreen=RegisterScreen{rsState=(l,acct)}} = [ui] |                            ,aScreen=RegisterScreen{rsState=(l,acct)} | ||||||
|  |                            ,aMinibuffer=mbuf} | ||||||
|  |   = [ui] | ||||||
|   where |   where | ||||||
|     toplabel = withAttr ("border" <> "bold") (str $ T.unpack acct) |     toplabel = withAttr ("border" <> "bold") (str $ T.unpack acct) | ||||||
|             <+> togglefilters |             <+> togglefilters | ||||||
|             <+> str " transactions" |             <+> str " transactions" | ||||||
|             -- <+> borderQueryStr querystr -- no, account transactions report shows all transactions in the acct ? |             <+> borderQueryStr (query_ ropts) | ||||||
|             -- <+> str " and subs" |             -- <+> str " and subs" | ||||||
|             <+> str " (" |             <+> str " (" | ||||||
|             <+> cur |             <+> cur | ||||||
| @ -176,12 +179,17 @@ drawRegisterScreen AppState{aopts=UIOpts{cliopts_=CliOpts{reportopts_=ropts}} | |||||||
|           ,("C", "cleared?") |           ,("C", "cleared?") | ||||||
|           ,("U", "uncleared?") |           ,("U", "uncleared?") | ||||||
|           ,("R", "real?") |           ,("R", "real?") | ||||||
|  |           ,("f", "filter") | ||||||
|           ,("right/enter", "transaction") |           ,("right/enter", "transaction") | ||||||
|           ,("g", "reload") |           ,("g", "reload") | ||||||
|           ,("q", "quit") |           ,("q", "quit") | ||||||
|           ] |           ] | ||||||
| 
 | 
 | ||||||
|       render $ defaultLayout toplabel bottomlabel $ renderList l (drawRegisterItem colwidths) |         bottomarea = case mbuf of | ||||||
|  |                       Nothing  -> bottomlabel | ||||||
|  |                       Just ed  -> minibuffer ed | ||||||
|  | 
 | ||||||
|  |       render $ defaultLayout toplabel bottomarea $ renderList l (drawRegisterItem colwidths) | ||||||
| 
 | 
 | ||||||
| drawRegisterScreen _ = error "draw function called with wrong screen type, should not happen" | drawRegisterScreen _ = error "draw function called with wrong screen type, should not happen" | ||||||
| 
 | 
 | ||||||
| @ -211,40 +219,53 @@ handleRegisterScreen st@AppState{ | |||||||
|    aScreen=s@RegisterScreen{rsState=(l,acct)} |    aScreen=s@RegisterScreen{rsState=(l,acct)} | ||||||
|   ,aopts=UIOpts{cliopts_=copts} |   ,aopts=UIOpts{cliopts_=copts} | ||||||
|   ,ajournal=j |   ,ajournal=j | ||||||
|   } e = do |   ,aMinibuffer=mbuf | ||||||
|  |   } ev = do | ||||||
|   d <- liftIO getCurrentDay |   d <- liftIO getCurrentDay | ||||||
|   case e of |   case mbuf of | ||||||
|     Vty.EvKey Vty.KEsc []        -> halt st |     Nothing -> | ||||||
|     Vty.EvKey (Vty.KChar 'q') [] -> halt st |  | ||||||
| 
 | 
 | ||||||
|     Vty.EvKey (Vty.KChar 'g') [] -> do |       case ev of | ||||||
|       (ej, _) <- liftIO $ journalReloadIfChanged copts d j |         Vty.EvKey (Vty.KChar 'q') [] -> halt st | ||||||
|       case ej of |  | ||||||
|         Right j' -> continue $ reload j' d st |  | ||||||
|         Left err -> continue $ screenEnter d ES.screen{esState=err} st |  | ||||||
| 
 | 
 | ||||||
|     Vty.EvKey (Vty.KChar 'E') [] -> scrollTop >> (continue $ reload j d $ stToggleEmpty st) |         Vty.EvKey (Vty.KChar 'g') [] -> do | ||||||
|     Vty.EvKey (Vty.KChar 'C') [] -> scrollTop >> (continue $ reload j d $ stToggleCleared st) |           (ej, _) <- liftIO $ journalReloadIfChanged copts d j | ||||||
|     Vty.EvKey (Vty.KChar 'U') [] -> scrollTop >> (continue $ reload j d $ stToggleUncleared st) |           case ej of | ||||||
|     Vty.EvKey (Vty.KChar 'R') [] -> scrollTop >> (continue $ reload j d $ stToggleReal st) |             Right j' -> continue $ reload j' d st | ||||||
|     Vty.EvKey (Vty.KLeft)     [] -> continue $ popScreen st |             Left err -> continue $ screenEnter d ES.screen{esState=err} st | ||||||
| 
 | 
 | ||||||
|     Vty.EvKey (k) [] | k `elem` [Vty.KRight, Vty.KEnter] -> do |         Vty.EvKey (Vty.KChar 'E') [] -> scrollTop >> (continue $ reload j d $ stToggleEmpty st) | ||||||
|       case listSelectedElement l of |         Vty.EvKey (Vty.KChar 'C') [] -> scrollTop >> (continue $ reload j d $ stToggleCleared st) | ||||||
|         Just (_, (_, _, _, _, _, t)) -> |         Vty.EvKey (Vty.KChar 'U') [] -> scrollTop >> (continue $ reload j d $ stToggleUncleared st) | ||||||
|           let |         Vty.EvKey (Vty.KChar 'R') [] -> scrollTop >> (continue $ reload j d $ stToggleReal st) | ||||||
|             ts = map sixth6 $ V.toList $ listElements l |         Vty.EvKey (Vty.KChar 'f') [] -> (continue $ reload j d $ stShowMinibuffer st) | ||||||
|             numberedts = zip [1..] ts |         Vty.EvKey (Vty.KLeft)     [] -> continue $ popScreen st | ||||||
|             i = fromIntegral $ maybe 0 (+1) $ elemIndex t ts -- XXX | 
 | ||||||
|           in |         Vty.EvKey (k) [] | k `elem` [Vty.KRight, Vty.KEnter] -> do | ||||||
|             continue $ screenEnter d TS.screen{tsState=((i,t),numberedts,acct)} st |           case listSelectedElement l of | ||||||
|         Nothing -> continue st |             Just (_, (_, _, _, _, _, t)) -> | ||||||
|  |               let | ||||||
|  |                 ts = map sixth6 $ V.toList $ listElements l | ||||||
|  |                 numberedts = zip [1..] ts | ||||||
|  |                 i = fromIntegral $ maybe 0 (+1) $ elemIndex t ts -- XXX | ||||||
|  |               in | ||||||
|  |                 continue $ screenEnter d TS.screen{tsState=((i,t),numberedts,acct)} st | ||||||
|  |             Nothing -> continue st | ||||||
|  | 
 | ||||||
|  |         -- fall through to the list's event handler (handles [pg]up/down) | ||||||
|  |         ev                       -> do | ||||||
|  |                                      l' <- handleEvent ev l | ||||||
|  |                                      continue st{aScreen=s{rsState=(l',acct)}} | ||||||
|  |                                      -- continue =<< handleEventLensed st someLens ev | ||||||
|  | 
 | ||||||
|  |     Just ed -> | ||||||
|  |         case ev of | ||||||
|  |             Vty.EvKey Vty.KEsc   [] -> continue $ stHideMinibuffer st | ||||||
|  |             Vty.EvKey Vty.KEnter [] -> continue $ reload j d $ stFilter s $ stHideMinibuffer st | ||||||
|  |                                         where s = chomp $ unlines $ getEditContents ed | ||||||
|  |             ev                      -> do ed' <- handleEvent ev ed | ||||||
|  |                                           continue $ st{aMinibuffer=Just ed'} | ||||||
| 
 | 
 | ||||||
|     -- fall through to the list's event handler (handles [pg]up/down) |  | ||||||
|     ev                       -> do |  | ||||||
|                                  l' <- handleEvent ev l |  | ||||||
|                                  continue st{aScreen=s{rsState=(l',acct)}} |  | ||||||
|                                  -- continue =<< handleEventLensed st someLens ev |  | ||||||
|   where |   where | ||||||
|     -- Encourage a more stable scroll position when toggling list items (cf AccountsScreen.hs) |     -- Encourage a more stable scroll position when toggling list items (cf AccountsScreen.hs) | ||||||
|     scrollTop = vScrollToBeginning $ viewportScroll "register" |     scrollTop = vScrollToBeginning $ viewportScroll "register" | ||||||
|  | |||||||
| @ -72,6 +72,7 @@ themesList = [ | |||||||
|               (borderAttr <> "query", cyan `on` black & bold), |               (borderAttr <> "query", cyan `on` black & bold), | ||||||
|               (borderAttr <> "depth", yellow `on` black & bold), |               (borderAttr <> "depth", yellow `on` black & bold), | ||||||
|               (borderAttr <> "keys", white `on` black & bold), |               (borderAttr <> "keys", white `on` black & bold), | ||||||
|  |               (borderAttr <> "minibuffer", white `on` black & bold), | ||||||
|               -- ("normal"                , black `on` white), |               -- ("normal"                , black `on` white), | ||||||
|               ("list"                  , black `on` white),      -- regular list items |               ("list"                  , black `on` white),      -- regular list items | ||||||
|               ("list" <> "selected"    , white `on` blue & bold), -- selected list items |               ("list" <> "selected"    , white `on` blue & bold), -- selected list items | ||||||
|  | |||||||
| @ -1,9 +1,12 @@ | |||||||
|  | {-# LANGUAGE StandaloneDeriving #-} | ||||||
|  | 
 | ||||||
| module Hledger.UI.UITypes where | module Hledger.UI.UITypes where | ||||||
| 
 | 
 | ||||||
| import Data.Time.Calendar (Day) | import Data.Time.Calendar (Day) | ||||||
| import qualified Graphics.Vty as V | import qualified Graphics.Vty as V | ||||||
| import Brick | import Brick | ||||||
| import Brick.Widgets.List (List) | import Brick.Widgets.List (List) | ||||||
|  | import Brick.Widgets.Edit (Editor) | ||||||
| import Text.Show.Functions () | import Text.Show.Functions () | ||||||
|   -- import the Show instance for functions. Warning, this also re-exports it |   -- import the Show instance for functions. Warning, this also re-exports it | ||||||
| 
 | 
 | ||||||
| @ -12,6 +15,10 @@ import Hledger.UI.UIOptions | |||||||
| 
 | 
 | ||||||
| ---------------------------------------------------------------------- | ---------------------------------------------------------------------- | ||||||
| 
 | 
 | ||||||
|  | instance Show Editor | ||||||
|  |   where | ||||||
|  |     show = const "<Editor>" | ||||||
|  | 
 | ||||||
| -- | hledger-ui's application state. This is part of, but distinct | -- | hledger-ui's application state. This is part of, but distinct | ||||||
| -- from, brick's App. | -- from, brick's App. | ||||||
| data AppState = AppState { | data AppState = AppState { | ||||||
| @ -19,6 +26,7 @@ data AppState = AppState { | |||||||
|   ,ajournal :: Journal      -- ^ the journal being viewed |   ,ajournal :: Journal      -- ^ the journal being viewed | ||||||
|   ,aScreen :: Screen        -- ^ the currently active screen |   ,aScreen :: Screen        -- ^ the currently active screen | ||||||
|   ,aPrevScreens :: [Screen] -- ^ previously visited screens, most recent first |   ,aPrevScreens :: [Screen] -- ^ previously visited screens, most recent first | ||||||
|  |   ,aMinibuffer :: Maybe Editor  -- ^ a compact editor used for data entry, when active | ||||||
|   } deriving (Show) |   } deriving (Show) | ||||||
| 
 | 
 | ||||||
| -- | Types of screen available within the app, along with their state. | -- | Types of screen available within the app, along with their state. | ||||||
|  | |||||||
| @ -14,6 +14,7 @@ module Hledger.UI.UIUtils ( | |||||||
|  ,borderQueryStr |  ,borderQueryStr | ||||||
|  ,borderDepthStr |  ,borderDepthStr | ||||||
|  ,borderKeysStr |  ,borderKeysStr | ||||||
|  |  ,minibuffer | ||||||
|  -- |  -- | ||||||
|  ,stToggleCleared |  ,stToggleCleared | ||||||
|  ,stTogglePending |  ,stTogglePending | ||||||
| @ -21,6 +22,9 @@ module Hledger.UI.UIUtils ( | |||||||
|  ,stToggleEmpty |  ,stToggleEmpty | ||||||
|  ,stToggleFlat |  ,stToggleFlat | ||||||
|  ,stToggleReal |  ,stToggleReal | ||||||
|  |  ,stFilter | ||||||
|  |  ,stShowMinibuffer | ||||||
|  |  ,stHideMinibuffer | ||||||
|  ) where |  ) where | ||||||
| 
 | 
 | ||||||
| import Lens.Micro ((^.)) | import Lens.Micro ((^.)) | ||||||
| @ -29,9 +33,11 @@ import Lens.Micro ((^.)) | |||||||
| -- import Data.Default | -- import Data.Default | ||||||
| import Data.List | import Data.List | ||||||
| import Data.Monoid | import Data.Monoid | ||||||
|  | import Data.Text.Zipper (gotoEOL) | ||||||
| import Data.Time.Calendar (Day) | import Data.Time.Calendar (Day) | ||||||
| import Brick | import Brick | ||||||
| -- import Brick.Widgets.List | -- import Brick.Widgets.List | ||||||
|  | import Brick.Widgets.Edit | ||||||
| import Brick.Widgets.Border | import Brick.Widgets.Border | ||||||
| import Brick.Widgets.Border.Style | import Brick.Widgets.Border.Style | ||||||
| import Graphics.Vty as Vty | import Graphics.Vty as Vty | ||||||
| @ -87,6 +93,20 @@ stToggleReal st@AppState{aopts=uopts@UIOpts{cliopts_=copts@CliOpts{reportopts_=r | |||||||
|   where |   where | ||||||
|     toggleReal ropts = ropts{real_=not $ real_ ropts} |     toggleReal ropts = ropts{real_=not $ real_ ropts} | ||||||
| 
 | 
 | ||||||
|  | -- | Apply a new filter query. | ||||||
|  | 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}}}} | ||||||
|  | 
 | ||||||
|  | -- | Enable the minibuffer, setting its content to the current query with the cursor at the end. | ||||||
|  | stShowMinibuffer st = st{aMinibuffer=Just e} | ||||||
|  |   where | ||||||
|  |     e = applyEdit gotoEOL $ editor "minibuffer" (str . unlines) (Just 1) oldq | ||||||
|  |     oldq = query_ $ reportopts_ $ cliopts_ $ aopts st | ||||||
|  | 
 | ||||||
|  | -- | Disable the minibuffer, discarding any edit in progress. | ||||||
|  | stHideMinibuffer st = st{aMinibuffer=Nothing} | ||||||
|  | 
 | ||||||
| -- | Regenerate the content for the current and previous screens, from a new journal and current date. | -- | Regenerate the content for the current and previous screens, from a new journal and current date. | ||||||
| reload :: Journal -> Day -> AppState -> AppState | reload :: Journal -> Day -> AppState -> AppState | ||||||
| reload j d st@AppState{aScreen=s,aPrevScreens=ss} = | reload j d st@AppState{aScreen=s,aPrevScreens=ss} = | ||||||
| @ -229,3 +249,9 @@ borderKeysStr keydescs = | |||||||
|     -- sep = str " | " |     -- sep = str " | " | ||||||
|     sep = str " " |     sep = str " " | ||||||
| 
 | 
 | ||||||
|  | minibuffer :: Editor -> Widget | ||||||
|  | minibuffer ed = | ||||||
|  |   forceAttr (borderAttr <> "minibuffer") $ | ||||||
|  |   hBox $ | ||||||
|  |   [txt "filter: ", renderEditor ed] | ||||||
|  | 
 | ||||||
|  | |||||||
| @ -232,7 +232,14 @@ With large journal files, there can be a noticeable pause. | |||||||
| .PP | .PP | ||||||
| \f[C]q\f[] quits the application. | \f[C]q\f[] quits the application. | ||||||
| .PP | .PP | ||||||
| Some screens have additional key bindings, described below. | \f[C]f\f[] lets you add or change the current filter query which limits | ||||||
|  | the data shown on most screens. | ||||||
|  | While editing, you can use typical command\-line edit keys, and press | ||||||
|  | enter to set the new filter, or escape to cancel. | ||||||
|  | Note queries which filter by account name may not work well in the | ||||||
|  | register screen. | ||||||
|  | .PP | ||||||
|  | Additional screen\-specific keys are described below. | ||||||
| .SH SCREENS | .SH SCREENS | ||||||
| .SS Accounts screen | .SS Accounts screen | ||||||
| .PP | .PP | ||||||
|  | |||||||
| @ -162,7 +162,13 @@ screens). With large journal files, there can be a noticeable pause. | |||||||
| 
 | 
 | ||||||
|    `q' quits the application. |    `q' quits the application. | ||||||
| 
 | 
 | ||||||
|    Some screens have additional key bindings, described below. |    `f' lets you add or change the current filter query which limits the | ||||||
|  | data shown on most screens. While editing, you can use typical | ||||||
|  | command-line edit keys, and press enter to set the new filter, or escape | ||||||
|  | to cancel. Note queries which filter by account name may not work well | ||||||
|  | in the register screen. | ||||||
|  | 
 | ||||||
|  |    Additional screen-specific keys are described below. | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
| File: hledger-ui.1.info,  Node: SCREENS,  Prev: KEYS,  Up: Top | File: hledger-ui.1.info,  Node: SCREENS,  Prev: KEYS,  Up: Top | ||||||
| @ -303,15 +309,15 @@ Node: OPTIONS714 | |||||||
| Ref: #options813 | Ref: #options813 | ||||||
| Node: KEYS3689 | Node: KEYS3689 | ||||||
| Ref: #keys3786 | Ref: #keys3786 | ||||||
| Node: SCREENS4209 | Node: SCREENS4506 | ||||||
| Ref: #screens4296 | Ref: #screens4593 | ||||||
| Node: Accounts screen4386 | Node: Accounts screen4683 | ||||||
| Ref: #accounts-screen4516 | Ref: #accounts-screen4813 | ||||||
| Node: Register screen5620 | Node: Register screen5917 | ||||||
| Ref: #register-screen5777 | Ref: #register-screen6074 | ||||||
| Node: Transaction screen7434 | Node: Transaction screen7731 | ||||||
| Ref: #transaction-screen7594 | Ref: #transaction-screen7891 | ||||||
| Node: Error screen8461 | Node: Error screen8758 | ||||||
| Ref: #error-screen8585 | Ref: #error-screen8882 | ||||||
|  |  | ||||||
| End Tag Table | End Tag Table | ||||||
|  | |||||||
| @ -92,7 +92,13 @@ screens). With large journal files, there can be a noticeable pause. | |||||||
| 
 | 
 | ||||||
| `q` quits the application. | `q` quits the application. | ||||||
| 
 | 
 | ||||||
| Some screens have additional key bindings, described below. | `f` lets you add or change the current | ||||||
|  | [filter query](/journal.html#queries) which limits the data shown on | ||||||
|  | most screens. While editing, you can use typical command-line edit keys, | ||||||
|  | and press enter to set the new filter, or escape to cancel. Note queries | ||||||
|  | which filter by account name may not work well in the register screen. | ||||||
|  | 
 | ||||||
|  | Additional screen-specific keys are described below. | ||||||
| 
 | 
 | ||||||
| # SCREENS | # SCREENS | ||||||
| 
 | 
 | ||||||
|  | |||||||
| @ -154,7 +154,13 @@ KKEEYYSS | |||||||
| 
 | 
 | ||||||
|        q quits the application. |        q quits the application. | ||||||
| 
 | 
 | ||||||
|        Some screens have additional key bindings, described below. |        f lets you add or change the current filter query which limits the data | ||||||
|  |        shown on most screens.  While editing, you can use typical command-line | ||||||
|  |        edit keys, and press enter to set the new filter, or escape to  cancel. | ||||||
|  |        Note queries which filter by account name may not work well in the reg- | ||||||
|  |        ister screen. | ||||||
|  | 
 | ||||||
|  |        Additional screen-specific keys are described below. | ||||||
| 
 | 
 | ||||||
| SSCCRREEEENNSS | SSCCRREEEENNSS | ||||||
|    AAccccoouunnttss ssccrreeeenn |    AAccccoouunnttss ssccrreeeenn | ||||||
|  | |||||||
| @ -84,6 +84,7 @@ executables: | |||||||
|       - safe >= 0.2 |       - safe >= 0.2 | ||||||
|       - split >= 0.1 && < 0.3 |       - split >= 0.1 && < 0.3 | ||||||
|       - text >= 1.2 && < 1.3 |       - text >= 1.2 && < 1.3 | ||||||
|  |       - text-zipper >= 0.4 && < 0.5 | ||||||
|       - transformers |       - transformers | ||||||
|       - vector |       - vector | ||||||
|       - vty >= 5.2 && < 5.5 |       - vty >= 5.2 && < 5.5 | ||||||
|  | |||||||
| @ -75,6 +75,7 @@ executable hledger-ui | |||||||
|     , safe >= 0.2 |     , safe >= 0.2 | ||||||
|     , split >= 0.1 && < 0.3 |     , split >= 0.1 && < 0.3 | ||||||
|     , text >= 1.2 && < 1.3 |     , text >= 1.2 && < 1.3 | ||||||
|  |     , text-zipper >= 0.4 && < 0.5 | ||||||
|     , transformers |     , transformers | ||||||
|     , vector |     , vector | ||||||
|     , vty >= 5.2 && < 5.6 |     , vty >= 5.2 && < 5.6 | ||||||
|  | |||||||
		Loading…
	
		Reference in New Issue
	
	Block a user