From 3c724efe4f39bb369faa38cf63aa13c8ea6b2f28 Mon Sep 17 00:00:00 2001 From: Simon Michael Date: Tue, 2 Aug 2016 08:22:21 -0700 Subject: [PATCH] ui: d cycles report duration, n/p steps to next/prev period (#381) --- hledger-ui/Hledger/UI/AccountsScreen.hs | 4 ++++ hledger-ui/Hledger/UI/RegisterScreen.hs | 6 ++++- hledger-ui/Hledger/UI/UIState.hs | 31 +++++++++++++++++++++++++ hledger-ui/Hledger/UI/UIUtils.hs | 4 ++++ hledger-ui/doc/hledger-ui.1.m4.md | 11 +++++++-- 5 files changed, 53 insertions(+), 3 deletions(-) diff --git a/hledger-ui/Hledger/UI/AccountsScreen.hs b/hledger-ui/Hledger/UI/AccountsScreen.hs index 6ec5cb91b..75ad3bf08 100644 --- a/hledger-ui/Hledger/UI/AccountsScreen.hs +++ b/hledger-ui/Hledger/UI/AccountsScreen.hs @@ -155,6 +155,7 @@ asDraw UIState{aopts=UIOpts{cliopts_=copts@CliOpts{reportopts_=ropts}} <+> withAttr (borderAttr <> "query") (str (if flat_ ropts then " (flat)" else "")) <+> borderQueryStr querystr <+> togglefilters + <+> borderPeriodStr (period_ ropts) <+> borderDepthStr mdepth <+> str " (" <+> cur @@ -288,6 +289,9 @@ asHandle ui0@UIState{ EvKey (KChar '-') [] -> continue $ regenerateScreens j d $ decDepth ui EvKey (KChar '_') [] -> continue $ regenerateScreens j d $ decDepth ui EvKey (KChar c) [] | c `elem` ['+','='] -> continue $ regenerateScreens j d $ incDepth ui + EvKey (KChar 'd') [] -> continue $ regenerateScreens j d $ cycleReportDuration d ui + EvKey (KChar 'n') [] -> continue $ regenerateScreens j d $ nextReportPeriod ui + EvKey (KChar 'p') [] -> continue $ regenerateScreens j d $ previousReportPeriod ui EvKey (KChar 'F') [] -> continue $ regenerateScreens j d $ toggleFlat ui EvKey (KChar 'Z') [] -> scrollTop >> (continue $ regenerateScreens j d $ toggleEmpty ui) EvKey (KChar 'C') [] -> scrollTop >> (continue $ regenerateScreens j d $ toggleCleared ui) diff --git a/hledger-ui/Hledger/UI/RegisterScreen.hs b/hledger-ui/Hledger/UI/RegisterScreen.hs index fa5acfcc7..ab246eb95 100644 --- a/hledger-ui/Hledger/UI/RegisterScreen.hs +++ b/hledger-ui/Hledger/UI/RegisterScreen.hs @@ -160,11 +160,12 @@ rsDraw UIState{aopts=UIOpts{cliopts_=copts@CliOpts{reportopts_=ropts}} where toplabel = withAttr ("border" <> "bold") (str $ T.unpack $ replaceHiddenAccountsNameWith "All" rsAccount) - <+> withAttr (borderAttr <> "query") (str $ if inclusive then "" else " (exclusive)") + <+> withAttr (borderAttr <> "query") (str $ if inclusive then "" else " exclusive") <+> togglefilters <+> str " transactions" <+> borderQueryStr (query_ ropts) -- <+> str " and subs" + <+> borderPeriodStr (period_ ropts) <+> str " (" <+> cur <+> str "/" @@ -258,6 +259,9 @@ rsHandle ui@UIState{ EvKey (KChar 'g') [] -> liftIO (uiReloadJournalIfChanged copts d j ui) >>= continue EvKey (KChar 'I') [] -> continue $ uiCheckBalanceAssertions d (toggleIgnoreBalanceAssertions ui) EvKey (KChar 'a') [] -> suspendAndResume $ clearScreen >> setCursorPosition 0 0 >> add copts j >> uiReloadJournalIfChanged copts d j ui + EvKey (KChar 'd') [] -> continue $ regenerateScreens j d $ cycleReportDuration d ui + EvKey (KChar 'n') [] -> continue $ regenerateScreens j d $ nextReportPeriod ui + EvKey (KChar 'p') [] -> continue $ regenerateScreens j d $ previousReportPeriod ui EvKey (KChar 'E') [] -> suspendAndResume $ void (runEditor pos f) >> uiReloadJournalIfChanged copts d j ui where (pos,f) = case listSelectedElement rsList of diff --git a/hledger-ui/Hledger/UI/UIState.hs b/hledger-ui/Hledger/UI/UIState.hs index f12bd3d0a..3fee58302 100644 --- a/hledger-ui/Hledger/UI/UIState.hs +++ b/hledger-ui/Hledger/UI/UIState.hs @@ -68,6 +68,36 @@ toggleIgnoreBalanceAssertions :: UIState -> UIState toggleIgnoreBalanceAssertions ui@UIState{aopts=uopts@UIOpts{cliopts_=copts@CliOpts{}}} = ui{aopts=uopts{cliopts_=copts{ignore_assertions_=not $ ignore_assertions_ copts}}} +-- | Cycle through increasingly larger report periods enclosing the current one. +cycleReportDuration :: Day -> UIState -> UIState +cycleReportDuration d ui@UIState{aopts=uopts@UIOpts{cliopts_=copts@CliOpts{reportopts_=ropts}}} = + ui{aopts=uopts{cliopts_=copts{reportopts_=reportOptsCycleDuration d ropts}}} + +-- | Cycle through increasingly larger report periods. +-- Simple periods (a specific day, monday-starting week, month, quarter, year) +-- become the next larger enclosing period. +-- Other periods (between two arbitrary dates, or unbounded on one or both ends) +-- become today. +reportOptsCycleDuration :: Day -> ReportOpts -> ReportOpts +reportOptsCycleDuration d ropts@ReportOpts{period_=p} = ropts{period_=p'} + where + p' = case p of + PeriodAll -> DayPeriod d + PeriodFrom _ -> DayPeriod d + PeriodTo _ -> DayPeriod d + PeriodBetween _ _ -> DayPeriod d + _ -> periodGrow p + +-- | Step the report start/end dates to the next period of same duration. +nextReportPeriod :: UIState -> UIState +nextReportPeriod ui@UIState{aopts=uopts@UIOpts{cliopts_=copts@CliOpts{reportopts_=ropts@ReportOpts{period_=p}}}} = + ui{aopts=uopts{cliopts_=copts{reportopts_=ropts{period_=periodNext p}}}} + +-- | Step the report start/end dates to the next period of same duration. +previousReportPeriod :: UIState -> UIState +previousReportPeriod ui@UIState{aopts=uopts@UIOpts{cliopts_=copts@CliOpts{reportopts_=ropts@ReportOpts{period_=p}}}} = + ui{aopts=uopts{cliopts_=copts{reportopts_=ropts{period_=periodPrevious p}}}} + -- | Apply a new filter query. setFilter :: String -> UIState -> UIState setFilter s ui@UIState{aopts=uopts@UIOpts{cliopts_=copts@CliOpts{reportopts_=ropts}}} = @@ -82,6 +112,7 @@ resetFilter ui@UIState{aopts=uopts@UIOpts{cliopts_=copts@CliOpts{reportopts_=rop ,clearedstatus_=Nothing ,real_=False ,query_="" + ,period_=PeriodAll }}}} resetDepth :: UIState -> UIState diff --git a/hledger-ui/Hledger/UI/UIUtils.hs b/hledger-ui/Hledger/UI/UIUtils.hs index 49c7c3ad1..74ffe9e85 100644 --- a/hledger-ui/Hledger/UI/UIUtils.hs +++ b/hledger-ui/Hledger/UI/UIUtils.hs @@ -127,6 +127,10 @@ borderDepthStr :: Maybe Int -> Widget Name borderDepthStr Nothing = str "" borderDepthStr (Just d) = str " to " <+> withAttr (borderAttr <> "query") (str $ "depth "++show d) +borderPeriodStr :: Period -> Widget Name +borderPeriodStr PeriodAll = str "" +borderPeriodStr p = str " in " <+> withAttr (borderAttr <> "query") (str $ showPeriod p) + borderKeysStr :: [(String,String)] -> Widget Name borderKeysStr keydescs = hBox $ diff --git a/hledger-ui/doc/hledger-ui.1.m4.md b/hledger-ui/doc/hledger-ui.1.m4.md index dfbb713fc..235c89590 100644 --- a/hledger-ui/doc/hledger-ui.1.m4.md +++ b/hledger-ui/doc/hledger-ui.1.m4.md @@ -84,10 +84,11 @@ The cursor keys navigate: `left` returns to the previous screen, `up`/`down`/`page up`/`page down`/`home`/`end` move up and down through lists. Vi-style `h`/`j`/`k`/`l` movement keys are also supported. -A tip: movement speed is limited by your keyboard repeat rate, +(A tip: movement speed is limited by your keyboard repeat rate, to move faster you may want to adjust that. -(On a mac, the Karabiner app is one way to do that). +On a mac, the Karabiner app is one way to do that.) +On most screens, `/` lets you set or change the [filter query](/hledger.html#queries), which limits the data shown on most screens (in addition to the quick filters described below). While editing the query you can use typical @@ -95,6 +96,12 @@ command-line edit keys ([CTRL-a/e/d/k, cursor keys etc.](http://hackage.haskell.org/package/brick-0.7/docs/Brick-Widgets-Edit.html#t:Editor)), and `ENTER`to set the new filter or `ESCAPE`to cancel. +`d` cycles through the common report period durations: +day, week, month, quarter, year, and unlimited (the default). +When the report duration is limited in this way, `n` and `p` +step to the next or previous day/week/month/etc. +(To set arbitrary start/end dates, you can use `/` and a `date:` query.) + `BACKSPACE` or `DELETE` clears any filters in effect. `ESCAPE` removes any filters currently in effect, and jumps to the top screen.