packages feed

hledger-ui 1.20 → 1.20.1

raw patch · 10 files changed

+152/−132 lines, 10 filesdep ~hledgerdep ~hledger-lib

Dependency ranges changed: hledger, hledger-lib

Files

CHANGES.md view
@@ -1,6 +1,14 @@ User-visible changes in hledger-ui. See also the hledger changelog. +# 1.20.1 2020-12-15++- Fix the F key (toggle future/forecast transactions), which in 1.20 +  would only work twice. (#1411)++- Fix loss of forecasted transactions when the journal was reloaded+  while they were hidden. (#1204)+ # 1.20 2020-12-05  - When entering a query with `/`, malformed queries/regular expressions
Hledger/UI/AccountsScreen.hs view
@@ -53,11 +53,11 @@  asInit :: Day -> Bool -> UIState -> UIState asInit d reset ui@UIState{-  aopts=uopts@UIOpts{cliopts_=copts@CliOpts{reportspec_=rspec@ReportSpec{rsOpts=ropts}}},+  aopts=UIOpts{cliopts_=CliOpts{reportspec_=rspec@ReportSpec{rsOpts=ropts}}},   ajournal=j,   aScreen=s@AccountsScreen{}   } =-  ui{aopts=uopts', aScreen=s & asList .~ newitems'}+  ui{aScreen=s & asList .~ newitems'}    where     newitems = list AccountsList (V.fromList $ displayitems ++ blankitems) 1 @@ -80,7 +80,7 @@                       where                         as = map asItemAccountName displayitems -    uopts' = uopts{cliopts_=copts{reportspec_=rspec'}}+    -- Further restrict the query based on the current period and future/forecast mode.     rspec' = rspec{rsQuery=simplifyQuery $ And [rsQuery rspec, periodq, excludeforecastq (forecast_ ropts)]}       where         periodq = Date $ periodAsDateSpan $ period_ ropts@@ -106,7 +106,8 @@         Mixed amts = normaliseMixedAmountSquashPricesForDisplay $ stripPrices bal         stripPrices (Mixed as) = Mixed $ map stripprice as where stripprice a = a{aprice=Nothing}     displayitems = map displayitem items-    -- blanks added for scrolling control, cf RegisterScreen+    -- blanks added for scrolling control, cf RegisterScreen.+    -- XXX Ugly. Changing to 0 helps when debugging.     blankitems = replicate 100       AccountsScreenItem{asItemIndentLevel        = 0                         ,asItemAccountName        = ""
Hledger/UI/ErrorScreen.hs view
@@ -30,6 +30,7 @@ import Hledger.UI.UIState import Hledger.UI.UIUtils import Hledger.UI.Editor+import Data.Foldable (asum)  errorScreen :: Screen errorScreen = ErrorScreen{@@ -137,36 +138,60 @@       ]  --- Unconditionally reload the journal, regenerating the current screen--- and all previous screens in the history.+-- | Unconditionally reload the journal, regenerating the current screen+-- and all previous screens in the history as of the provided today-date. -- If reloading fails, enter the error screen, or if we're already -- on the error screen, update the error displayed.--- The provided CliOpts are used for reloading, and then saved--- in the UIState if reloading is successful (otherwise the--- ui state keeps its old cli opts.) -- Defined here so it can reference the error screen.+--+-- The provided CliOpts are used for reloading, and then saved in the+-- UIState if reloading is successful (otherwise the UIState keeps its old+-- CliOpts.) (XXX needed for.. ?)+--+-- Forecasted transactions are always generated, as at hledger-ui startup.+-- If a forecast period is specified in the provided opts, or was specified+-- at startup, it is preserved.+-- uiReloadJournal :: CliOpts -> Day -> UIState -> IO UIState uiReloadJournal copts d ui = do-  ej <- journalReload copts+  ej <-+    let copts' = enableForecastPreservingPeriod ui copts+    in journalReload copts'   return $ case ej of-    Right j  -> regenerateScreens j d ui{aopts=(aopts ui){cliopts_=copts}}+    Right j  -> regenerateScreens j d ui     Left err ->       case ui of         UIState{aScreen=s@ErrorScreen{}} -> ui{aScreen=s{esError=err}}         _                                -> screenEnter d errorScreen{esError=err} ui --- Like uiReloadJournal, but does not bother re-parsing the journal if--- the file(s) have not changed since last loaded. Always regenerates--- the current and previous screens though, since opts or date may have changed.+-- | Like uiReloadJournal, but does not re-parse the journal if the file(s)+-- have not changed since last loaded. Always regenerates the screens though,+-- since the provided options or today-date may have changed. uiReloadJournalIfChanged :: CliOpts -> Day -> Journal -> UIState -> IO UIState uiReloadJournalIfChanged copts d j ui = do-  (ej, _changed) <- journalReloadIfChanged copts d j+  (ej, _changed) <-+    let copts' = enableForecastPreservingPeriod ui copts+    in journalReloadIfChanged copts' d j   return $ case ej of-    Right j' -> regenerateScreens j' d ui{aopts=(aopts ui){cliopts_=copts}}+    Right j' -> regenerateScreens j' d ui     Left err ->       case ui of         UIState{aScreen=s@ErrorScreen{}} -> ui{aScreen=s{esError=err}}         _                                -> screenEnter d errorScreen{esError=err} ui++-- | Ensure this CliOpts enables forecasted transactions.+-- If a forecast period was specified in the old CliOpts,+-- or in the provided UIState's startup options,+-- it is preserved.+enableForecastPreservingPeriod :: UIState -> CliOpts -> CliOpts+enableForecastPreservingPeriod ui copts@CliOpts{reportspec_=rspec@ReportSpec{rsOpts=ropts}} =+  copts{reportspec_=rspec{rsOpts=ropts{forecast_=mforecast}}}+  where+    mforecast = asum [mprovidedforecastperiod, mstartupforecastperiod, mdefaultforecastperiod]+      where+        mprovidedforecastperiod = forecast_ ropts+        mstartupforecastperiod  = forecast_ $ rsOpts $ reportspec_ $ cliopts_ $ astartupopts ui+        mdefaultforecastperiod  = Just nulldatespan  -- Re-check any balance assertions in the current journal, and if any -- fail, enter (or update) the error screen. Or if balance assertions
Hledger/UI/Main.hs view
@@ -54,8 +54,7 @@   opts@UIOpts{cliopts_=copts@CliOpts{inputopts_=_iopts,reportspec_=rspec@ReportSpec{rsOpts=ropts},rawopts_=rawopts}} <- getHledgerUIOpts   -- when (debug_ $ cliopts_ opts) $ printf "%s\n" prognameandversion >> printf "opts: %s\n" (show opts) -  -- always include forecasted periodic transactions when loading data;-  -- they will be toggled on and off in the UI.+  -- always generate forecasted periodic transactions; their visibility will be toggled by the UI.   let copts' = copts{reportspec_=rspec{rsOpts=ropts{forecast_=Just $ fromMaybe nulldatespan (forecast_ ropts)}}}    case True of
Hledger/UI/RegisterScreen.hs view
@@ -66,8 +66,10 @@     -- XXX temp     inclusive = tree_ ropts || rsForceInclusive     thisacctq = Acct $ (if inclusive then accountNameToAccountRegex else accountNameToAccountOnlyRegex) rsAccount+     rspec' = rspec{rsOpts=ropts{depth_=Nothing}}-    q = And [rsQuery rspec, periodq, excludeforecastq (forecast_ ropts)]+    -- Further restrict the query based on the current period and future/forecast mode.+    q = simplifyQuery $ And [rsQuery rspec, periodq, excludeforecastq (forecast_ ropts)]       where         periodq = Date $ periodAsDateSpan $ period_ ropts         -- Except in forecast mode, exclude future/forecast transactions.@@ -98,8 +100,9 @@                             ,rsItemBalanceAmount = showMixedOneLine showAmountWithoutPrice Nothing (Just 32) False bal                             ,rsItemTransaction   = t                             }-    -- blank items are added to allow more control of scroll position; we won't allow movement over these-    blankitems = replicate 100  -- 100 ought to be enough for anyone+    -- blank items are added to allow more control of scroll position; we won't allow movement over these.+    -- XXX Ugly. Changing to 0 helps when debugging.+    blankitems = replicate 100  -- "100 ought to be enough for anyone"           RegisterScreenItem{rsItemDate          = ""                             ,rsItemStatus        = Unmarked                             ,rsItemDescription   = ""
Hledger/UI/UIState.hs view
@@ -22,17 +22,17 @@ -- | Toggle between showing only unmarked items or all items. toggleUnmarked :: UIState -> UIState toggleUnmarked ui@UIState{aopts=uopts@UIOpts{cliopts_=copts@CliOpts{reportspec_=rspec}}} =-  ui{aopts=uopts{cliopts_=copts{reportspec_=reportSpecToggleStatusSomehow Unmarked copts rspec}}}+  ui{aopts=uopts{cliopts_=copts{reportspec_=reportSpecToggleStatus Unmarked copts rspec}}}  -- | Toggle between showing only pending items or all items. togglePending :: UIState -> UIState togglePending ui@UIState{aopts=uopts@UIOpts{cliopts_=copts@CliOpts{reportspec_=rspec}}} =-  ui{aopts=uopts{cliopts_=copts{reportspec_=reportSpecToggleStatusSomehow Pending copts rspec}}}+  ui{aopts=uopts{cliopts_=copts{reportspec_=reportSpecToggleStatus Pending copts rspec}}}  -- | Toggle between showing only cleared items or all items. toggleCleared :: UIState -> UIState toggleCleared ui@UIState{aopts=uopts@UIOpts{cliopts_=copts@CliOpts{reportspec_=rspec}}} =-  ui{aopts=uopts{cliopts_=copts{reportspec_=reportSpecToggleStatusSomehow Cleared copts rspec}}}+  ui{aopts=uopts{cliopts_=copts{reportspec_=reportSpecToggleStatus Cleared copts rspec}}}  -- TODO testing different status toggle styles @@ -52,18 +52,13 @@     showstatus Pending  = "pending"     showstatus Unmarked = "unmarked" -reportSpecToggleStatusSomehow :: Status -> CliOpts -> ReportSpec -> ReportSpec-reportSpecToggleStatusSomehow s copts =-    either (error "reportSpecToggleStatusSomehow: updating Status should not result in an error") id  -- PARTIAL:-    . updateReportSpecFromOpts update-  where-    update = case maybeposintopt "status-toggles" $ rawopts_ copts of-      Just 2 -> reportOptsToggleStatus2 s-      Just 3 -> reportOptsToggleStatus3 s---      Just 4 -> reportOptsToggleStatus4 s---      Just 5 -> reportOptsToggleStatus5 s-      _      -> reportOptsToggleStatus1 s+reportSpecToggleStatus :: Status -> CliOpts -> ReportSpec -> ReportSpec+reportSpecToggleStatus s _copts =+    either (error "reportSpecToggleStatus: changing status should not have caused this error") id  -- PARTIAL:+    . updateReportSpecWith (reportOptsToggleStatus1 s) +-- various toggle behaviours:+ -- 1 UPC toggles only X/all reportOptsToggleStatus1 s ropts@ReportOpts{statuses_=ss}   | ss == [s]  = ropts{statuses_=[]}@@ -77,21 +72,21 @@ -- pressing Y after first or second step starts new cycle: -- [u] P [p] -- [pc] P [p]-reportOptsToggleStatus2 s ropts@ReportOpts{statuses_=ss}-  | ss == [s]            = ropts{statuses_=complement [s]}-  | ss == complement [s] = ropts{statuses_=[]}-  | otherwise            = ropts{statuses_=[s]}  -- XXX assume only three values+-- reportOptsToggleStatus2 s ropts@ReportOpts{statuses_=ss}+--   | ss == [s]            = ropts{statuses_=complement [s]}+--   | ss == complement [s] = ropts{statuses_=[]}+--   | otherwise            = ropts{statuses_=[s]}  -- XXX assume only three values  -- 3 UPC toggles each X-reportOptsToggleStatus3 s ropts@ReportOpts{statuses_=ss}-  | s `elem` ss = ropts{statuses_=filter (/= s) ss}-  | otherwise   = ropts{statuses_=simplifyStatuses (s:ss)}+-- reportOptsToggleStatus3 s ropts@ReportOpts{statuses_=ss}+--   | s `elem` ss = ropts{statuses_=filter (/= s) ss}+--   | otherwise   = ropts{statuses_=simplifyStatuses (s:ss)}  -- 4 upc sets X, UPC sets not-X --reportOptsToggleStatus4 s ropts@ReportOpts{statuses_=ss} --  | s `elem` ss = ropts{statuses_=filter (/= s) ss} --  | otherwise   = ropts{statuses_=simplifyStatuses (s:ss)}---+ -- 5 upc toggles X, UPC toggles not-X --reportOptsToggleStatus5 s ropts@ReportOpts{statuses_=ss} --  | s `elem` ss = ropts{statuses_=filter (/= s) ss}@@ -163,36 +158,33 @@     b | balancetype_ ropts == HistoricalBalance = PeriodChange       | otherwise                               = HistoricalBalance --- | Toggle hledger-ui's "forecast mode". In forecast mode, periodic--- transactions (generated by periodic rules) are enabled (as with--- hledger --forecast), and also future transactions in general--- (including non-periodic ones) are displayed. In normal mode, all--- future transactions (periodic or not) are suppressed (unlike--- command-line hledger).------ After toggling this, we do a full reload of the journal from disk--- to make it take effect; currently that's done in the callers (cf--- AccountsScreen, RegisterScreen) where it's easier. This is--- overkill, probably we should just hide/show the periodic--- transactions with a query for their special tag.---+-- | Toggle hledger-ui's "forecast/future mode". When this mode is enabled,+-- hledger-shows regular transactions which have future dates, and+-- "forecast" transactions generated by periodic transaction rules+-- (which are usually but not necessarily future-dated).+-- In normal mode, both of these are hidden. toggleForecast :: Day -> UIState -> UIState-toggleForecast d ui@UIState{aopts=uopts@UIOpts{cliopts_=copts@CliOpts{reportspec_=rspec@ReportSpec{rsOpts=ropts}}}} =-  ui{aopts=uopts{cliopts_=copts'}}-  where-    copts' = copts{reportspec_=rspec{rsOpts=ropts{forecast_=forecast'}}}-    forecast' =-      case forecast_ ropts of-        Just _  -> Nothing-        Nothing -> Just $ fromMaybe nulldatespan $ forecastPeriodFromRawOpts d $ rawopts_ copts+toggleForecast d ui@UIState{aopts=UIOpts{cliopts_=copts@CliOpts{reportspec_=ReportSpec{rsOpts=ropts}}}} =+  uiSetForecast ui $+    case forecast_ ropts of+      Just _  -> Nothing+      Nothing -> Just $ fromMaybe nulldatespan $ forecastPeriodFromRawOpts d $ rawopts_ copts +-- | Helper: set forecast mode (with the given forecast period) on or off in the UI state.+uiSetForecast :: UIState -> Maybe DateSpan -> UIState+uiSetForecast+  ui@UIState{aopts=uopts@UIOpts{cliopts_=copts@CliOpts{reportspec_=rspec@ReportSpec{rsOpts=ropts}}}}+  mforecast =+  -- we assume forecast mode has no effect on ReportSpec's derived fields+  ui{aopts=uopts{cliopts_=copts{reportspec_=rspec{rsOpts=ropts{forecast_=mforecast}}}}}+ -- | Toggle between showing all and showing only real (non-virtual) items. toggleReal :: UIState -> UIState toggleReal ui@UIState{aopts=uopts@UIOpts{cliopts_=copts@CliOpts{reportspec_=rspec}}} =     ui{aopts=uopts{cliopts_=copts{reportspec_=update rspec}}}   where     update = either (error "toggleReal: updating Real should not result in an error") id  -- PARTIAL:-           . updateReportSpecFromOpts (\ropts -> ropts{real_=not $ real_ ropts})+           . updateReportSpecWith (\ropts -> ropts{real_=not $ real_ ropts})  -- | Toggle the ignoring of balance assertions. toggleIgnoreBalanceAssertions :: UIState -> UIState@@ -240,14 +232,14 @@     ui{aopts=uopts{cliopts_=copts{reportspec_=update rspec}}}   where     update = either (error "updateReportPeriod: updating period should not result in an error") id  -- PARTIAL:-           . updateReportSpecFromOpts (\ropts -> ropts{period_=updatePeriod $ period_ ropts})+           . updateReportSpecWith (\ropts -> ropts{period_=updatePeriod $ period_ ropts})  -- | Apply a new filter query. setFilter :: String -> UIState -> UIState setFilter s ui@UIState{aopts=uopts@UIOpts{cliopts_=copts@CliOpts{reportspec_=rspec}}} =     ui{aopts=uopts{cliopts_=copts{reportspec_=update rspec}}}   where-    update = either (const rspec) id . updateReportSpecFromOpts (\ropts -> ropts{querystring_=querystring})+    update = either (const rspec) id . updateReportSpecWith (\ropts -> ropts{querystring_=querystring})     querystring = words'' prefixes $ T.pack s  -- | Reset some filters & toggles.@@ -306,7 +298,7 @@     ui{aopts=uopts{cliopts_=copts{reportspec_=update rspec}}}   where     update = either (error "updateReportDepth: updating depth should not result in an error") id  -- PARTIAL:-           . updateReportSpecFromOpts (\ropts -> ropts{depth_=updateDepth (depth_ ropts) >>= clipDepth ropts})+           . updateReportSpecWith (\ropts -> ropts{depth_=updateDepth (depth_ ropts) >>= clipDepth ropts})     clipDepth ropts d | d < 0            = depth_ ropts                       | d >= maxDepth ui = Nothing                       | otherwise        = Just d
hledger-ui.1 view
@@ -1,5 +1,5 @@ -.TH "hledger-ui" "1" "November 2020" "hledger-ui 1.20" "hledger User Manuals"+.TH "hledger-ui" "1" "December 2020" "hledger-ui 1.20.1" "hledger User Manuals"   @@ -500,13 +500,11 @@  .SH COPYRIGHT -Copyright (C) 2007-2019 Simon Michael.+Copyright (C) 2007-2020 Simon Michael. .br Released under GNU GPL v3 or later.  .SH SEE ALSO-hledger(1), hledger\-ui(1), hledger\-web(1), hledger\-api(1),+hledger(1), hledger\-ui(1), hledger\-web(1), hledger_csv(5), hledger_journal(5), hledger_timeclock(5), hledger_timedot(5), ledger(1)--http://hledger.org
hledger-ui.cabal view
@@ -4,10 +4,10 @@ -- -- see: https://github.com/sol/hpack ----- hash: 4007bd6deffcff3c3d5a40863cfa11bddaed31c367fdf5033728ec847c292a91+-- hash: aa2ee3de3cbd0649f1506526856f8646a597192d6dcd5e80e30204b3b6764578  name:           hledger-ui-version:        1.20+version:        1.20.1 synopsis:       Curses-style terminal interface for the hledger accounting system description:    A simple curses-style terminal user interface for the hledger accounting system.                 It can be a more convenient way to browse your accounts than the CLI.@@ -64,7 +64,7 @@   hs-source-dirs:       ./.   ghc-options: -Wall -fno-warn-unused-do-bind -fno-warn-name-shadowing -fno-warn-missing-signatures -fno-warn-type-defaults -fno-warn-orphans-  cpp-options: -DVERSION="1.20"+  cpp-options: -DVERSION="1.20.1"   build-depends:       ansi-terminal >=0.9     , async@@ -78,8 +78,8 @@     , extra >=1.6.3     , filepath     , fsnotify >=0.2.1.2 && <0.4-    , hledger >=1.20 && <1.21-    , hledger-lib >=1.20 && <1.21+    , hledger >=1.20.1 && <1.21+    , hledger-lib >=1.20.1 && <1.21     , megaparsec >=7.0.0 && <9.1     , microlens >=0.4     , microlens-platform >=0.2.3.1
hledger-ui.info view
@@ -3,8 +3,8 @@  File: hledger-ui.info,  Node: Top,  Next: OPTIONS,  Up: (dir) -hledger-ui(1) hledger-ui 1.20-*****************************+hledger-ui(1) hledger-ui 1.20.1+*******************************  hledger-ui - terminal interface for the hledger accounting tool @@ -38,6 +38,10 @@ * OPTIONS:: * keys:: * screens::+* accounts screen::+* Register screen::+* Transaction screen::+* Error screen:: * ENVIRONMENT:: * FILES:: * BUGS::@@ -306,23 +310,16 @@    additional screen-specific keys are described below.  -File: hledger-ui.info,  Node: screens,  Next: ENVIRONMENT,  Prev: keys,  Up: Top+File: hledger-ui.info,  Node: screens,  Next: accounts screen,  Prev: keys,  Up: Top  3 screens ********* -* Menu:--* accounts screen::-* Register screen::-* Transaction screen::-* Error screen::- -File: hledger-ui.info,  Node: accounts screen,  Next: Register screen,  Up: screens+File: hledger-ui.info,  Node: accounts screen,  Next: Register screen,  Prev: screens,  Up: Top -3.1 accounts screen-===================+4 accounts screen+*****************  this is normally the first screen displayed.  it lists accounts and their balances, like hledger's balance command.  by default, it shows@@ -368,10 +365,10 @@    Press 'right' or 'enter' to view an account's transactions register.  -File: hledger-ui.info,  Node: Register screen,  Next: Transaction screen,  Prev: accounts screen,  Up: screens+File: hledger-ui.info,  Node: Register screen,  Next: Transaction screen,  Prev: accounts screen,  Up: Top -3.2 Register screen-===================+5 Register screen+*****************  This screen shows the transactions affecting a particular account, like a check register.  Each line represents one transaction and shows:@@ -415,10 +412,10 @@ detail.  -File: hledger-ui.info,  Node: Transaction screen,  Next: Error screen,  Prev: Register screen,  Up: screens+File: hledger-ui.info,  Node: Transaction screen,  Next: Error screen,  Prev: Register screen,  Up: Top -3.3 Transaction screen-======================+6 Transaction screen+********************  This screen shows a single transaction, as a general journal entry, similar to hledger's print command and journal format@@ -439,10 +436,10 @@ reload).  -File: hledger-ui.info,  Node: Error screen,  Prev: Transaction screen,  Up: screens+File: hledger-ui.info,  Node: Error screen,  Next: ENVIRONMENT,  Prev: Transaction screen,  Up: Top -3.4 Error screen-================+7 Error screen+**************  This screen will appear if there is a problem, such as a parse error, when you press g to reload.  Once you have fixed the problem, press g@@ -450,9 +447,9 @@ to cancel the reload attempt.)  -File: hledger-ui.info,  Node: ENVIRONMENT,  Next: FILES,  Prev: screens,  Up: Top+File: hledger-ui.info,  Node: ENVIRONMENT,  Next: FILES,  Prev: Error screen,  Up: Top -4 ENVIRONMENT+8 ENVIRONMENT *************  *COLUMNS* The screen width to use.  Default: the full terminal width.@@ -480,7 +477,7 @@  File: hledger-ui.info,  Node: FILES,  Next: BUGS,  Prev: ENVIRONMENT,  Up: Top -5 FILES+9 FILES *******  Reads data from one or more files in hledger journal, timeclock,@@ -491,8 +488,8 @@  File: hledger-ui.info,  Node: BUGS,  Prev: FILES,  Up: Top -6 BUGS-******+10 BUGS+*******  The need to precede options with '--' when invoked from hledger is awkward.@@ -519,26 +516,26 @@  Tag Table: Node: Top71-Node: OPTIONS1470-Ref: #options1567-Node: keys5634-Ref: #keys5729-Node: screens10061-Ref: #screens10166-Node: accounts screen10256-Ref: #accounts-screen10384-Node: Register screen12599-Ref: #register-screen12754-Node: Transaction screen14751-Ref: #transaction-screen14909-Node: Error screen15779-Ref: #error-screen15901-Node: ENVIRONMENT16145-Ref: #environment16259-Node: FILES17066-Ref: #files17165-Node: BUGS17378-Ref: #bugs17455+Node: OPTIONS1554+Ref: #options1651+Node: keys5718+Ref: #keys5813+Node: screens10145+Ref: #screens10254+Node: accounts screen10254+Ref: #accounts-screen10390+Node: Register screen12605+Ref: #register-screen12752+Node: Transaction screen14749+Ref: #transaction-screen14899+Node: Error screen15769+Ref: #error-screen15903+Node: ENVIRONMENT16147+Ref: #environment16266+Node: FILES17073+Ref: #files17172+Node: BUGS17385+Ref: #bugs17464  End Tag Table 
hledger-ui.txt view
@@ -447,17 +447,14 @@   COPYRIGHT-       Copyright (C) 2007-2019 Simon Michael.+       Copyright (C) 2007-2020 Simon Michael.        Released under GNU GPL v3 or later.   SEE ALSO-       hledger(1),     hledger-ui(1),     hledger-web(1),      hledger-api(1),-       hledger_csv(5), hledger_journal(5), hledger_timeclock(5), hledger_time--       dot(5), ledger(1)--       http://hledger.org+       hledger(1),     hledger-ui(1),     hledger-web(1),      hledger_csv(5),+       hledger_journal(5), hledger_timeclock(5), hledger_timedot(5), ledger(1)   -hledger-ui 1.20                  November 2020                   hledger-ui(1)+hledger-ui 1.20.1                December 2020                   hledger-ui(1)