diff --git a/hledger-ui/Hledger/UI/AccountsScreen.hs b/hledger-ui/Hledger/UI/AccountsScreen.hs index e60b7550c..1cc9e7343 100644 --- a/hledger-ui/Hledger/UI/AccountsScreen.hs +++ b/hledger-ui/Hledger/UI/AccountsScreen.hs @@ -23,7 +23,7 @@ import Data.Maybe import Data.Monoid #endif import qualified Data.Text as T -import Data.Time.Calendar (Day) +import Data.Time.Calendar (Day, addDays) import qualified Data.Vector as V import Graphics.Vty (Event(..),Key(..),Modifier(..)) import Lens.Micro.Platform @@ -82,7 +82,10 @@ asInit d reset ui@UIState{ uopts' = uopts{cliopts_=copts{reportopts_=ropts'}} ropts' = ropts{accountlistmode_=if tree_ ropts then ALTree else ALFlat} - q = queryFromOpts d ropts + pfq | presentorfuture_ uopts == PFFuture = Any + | otherwise = Date $ DateSpan Nothing (Just $ addDays 1 d) + q = And [queryFromOpts d ropts, pfq] + -- run the report (items,_total) = report ropts' q j @@ -116,7 +119,7 @@ asInit d reset ui@UIState{ asInit _ _ _ = error "init function called with wrong screen type, should not happen" asDraw :: UIState -> [Widget Name] -asDraw UIState{aopts=UIOpts{cliopts_=copts@CliOpts{reportopts_=ropts}} +asDraw UIState{aopts=uopts@UIOpts{cliopts_=copts@CliOpts{reportopts_=ropts}} ,ajournal=j ,aScreen=s@AccountsScreen{} ,aMode=mode @@ -223,6 +226,10 @@ asDraw UIState{aopts=UIOpts{cliopts_=copts@CliOpts{reportopts_=ropts}} ,if tree_ ropts then str "flat/" <+> selectedstr "tree" else selectedstr "flat" <+> str "/tree") + ,("F" + ,if presentorfuture_ uopts == PFFuture + then str "present/" <+> selectedstr "future" + else selectedstr "present" <+> str "/future") ,("-+", str "depth") --,("/", "filter") --,("DEL", "unfilter") @@ -338,6 +345,7 @@ asHandle ui0@UIState{ VtyEvent (EvKey (KChar 'U') []) -> asCenterAndContinue $ regenerateScreens j d $ toggleUnmarked ui VtyEvent (EvKey (KChar 'P') []) -> asCenterAndContinue $ regenerateScreens j d $ togglePending ui VtyEvent (EvKey (KChar 'C') []) -> asCenterAndContinue $ regenerateScreens j d $ toggleCleared ui + VtyEvent (EvKey (KChar 'F') []) -> asCenterAndContinue $ regenerateScreens j d $ toggleFuture ui VtyEvent (EvKey (KDown) [MShift]) -> continue $ regenerateScreens j d $ shrinkReportPeriod d ui VtyEvent (EvKey (KUp) [MShift]) -> continue $ regenerateScreens j d $ growReportPeriod d ui diff --git a/hledger-ui/Hledger/UI/RegisterScreen.hs b/hledger-ui/Hledger/UI/RegisterScreen.hs index c8508f20f..a418ae799 100644 --- a/hledger-ui/Hledger/UI/RegisterScreen.hs +++ b/hledger-ui/Hledger/UI/RegisterScreen.hs @@ -59,7 +59,7 @@ rsSetAccount a forceinclusive scr@RegisterScreen{} = rsSetAccount _ _ scr = scr rsInit :: Day -> Bool -> UIState -> UIState -rsInit d reset ui@UIState{aopts=UIOpts{cliopts_=CliOpts{reportopts_=ropts}}, ajournal=j, aScreen=s@RegisterScreen{..}} = +rsInit d reset ui@UIState{aopts=uopts@UIOpts{cliopts_=CliOpts{reportopts_=ropts}}, ajournal=j, aScreen=s@RegisterScreen{..}} = ui{aScreen=s{rsList=newitems'}} where -- gather arguments and queries @@ -69,7 +69,9 @@ rsInit d reset ui@UIState{aopts=UIOpts{cliopts_=CliOpts{reportopts_=ropts}}, ajo ropts' = ropts{ depth_=Nothing } - q = queryFromOpts d ropts' + pfq | presentorfuture_ uopts == PFFuture = Any + | otherwise = Date $ DateSpan Nothing (Just $ addDays 1 d) + q = And [queryFromOpts d ropts', pfq] -- reportq = filterQuery (not . queryIsDepth) q (_label,items) = accountTransactionsReport ropts' j q thisacctq @@ -131,7 +133,7 @@ rsInit d reset ui@UIState{aopts=UIOpts{cliopts_=CliOpts{reportopts_=ropts}}, ajo rsInit _ _ _ = error "init function called with wrong screen type, should not happen" rsDraw :: UIState -> [Widget Name] -rsDraw UIState{aopts=UIOpts{cliopts_=copts@CliOpts{reportopts_=ropts}} +rsDraw UIState{aopts=uopts@UIOpts{cliopts_=copts@CliOpts{reportopts_=ropts}} ,aScreen=RegisterScreen{..} ,aMode=mode } = @@ -235,8 +237,12 @@ rsDraw UIState{aopts=UIOpts{cliopts_=copts@CliOpts{reportopts_=ropts}} else str "historical/" <+> selectedstr "period") ,("T" ,if inclusive - then str "this/" <+> selectedstr "+subs" - else selectedstr "this" <+> str "/+subs") + then str "flat/" <+> selectedstr "tree" + else selectedstr "flat" <+> str "/tree") + ,("F" + ,if presentorfuture_ uopts == PFFuture + then str "present/" <+> selectedstr "future" + else selectedstr "present" <+> str "/future") -- ,("a", "add") -- ,("g", "reload") -- ,("q", "quit") @@ -329,6 +335,7 @@ rsHandle ui@UIState{ VtyEvent (EvKey (KChar 'U') []) -> rsCenterAndContinue $ regenerateScreens j d $ toggleUnmarked ui VtyEvent (EvKey (KChar 'P') []) -> rsCenterAndContinue $ regenerateScreens j d $ togglePending ui VtyEvent (EvKey (KChar 'C') []) -> rsCenterAndContinue $ regenerateScreens j d $ toggleCleared ui + VtyEvent (EvKey (KChar 'F') []) -> rsCenterAndContinue $ regenerateScreens j d $ toggleFuture ui VtyEvent (EvKey (KChar '/') []) -> continue $ regenerateScreens j d $ showMinibuffer ui VtyEvent (EvKey (KDown) [MShift]) -> continue $ regenerateScreens j d $ shrinkReportPeriod d ui diff --git a/hledger-ui/Hledger/UI/UIOptions.hs b/hledger-ui/Hledger/UI/UIOptions.hs index cc989ee7b..2f4aeb507 100644 --- a/hledger-ui/Hledger/UI/UIOptions.hs +++ b/hledger-ui/Hledger/UI/UIOptions.hs @@ -1,11 +1,14 @@ {-# LANGUAGE CPP #-} +{-# LANGUAGE DeriveDataTypeable #-} {-| -} module Hledger.UI.UIOptions where +import Data.Data (Data) import Data.Default +import Data.Typeable (Typeable) import Data.List (intercalate) import System.Environment @@ -35,6 +38,8 @@ uiflags = [ -- "show historical ending balance in each period (includes postings before report start date)\n " ,flagNone ["flat","F"] (\opts -> setboolopt "flat" opts) "show full account names, unindented (default)" ,flagNone ["tree","T"] (\opts -> setboolopt "tree" opts) "show accounts as a tree" + ,flagNone ["present"] (\opts -> setboolopt "present" opts) "exclude transactions dated later than today (default)" + ,flagNone ["future"] (\opts -> setboolopt "future" opts) "include transactions dated later than today" -- ,flagReq ["drop"] (\s opts -> Right $ setopt "drop" s opts) "N" "with --flat, omit this many leading account name components" -- ,flagReq ["format"] (\s opts -> Right $ setopt "format" s opts) "FORMATSTR" "use this custom line format" -- ,flagNone ["no-elide"] (\opts -> setboolopt "no-elide" opts) "don't compress empty parent accounts on one line" @@ -67,6 +72,7 @@ uimode = (mode "hledger-ui" [("command","ui")] data UIOpts = UIOpts { watch_ :: Bool ,change_ :: Bool + ,presentorfuture_ :: PresentOrFutureOpt ,cliopts_ :: CliOpts } deriving (Show) @@ -74,6 +80,7 @@ defuiopts = UIOpts def def def + def -- instance Default CliOpts where def = defcliopts @@ -83,9 +90,22 @@ rawOptsToUIOpts rawopts = checkUIOpts <$> do return defuiopts { watch_ = boolopt "watch" rawopts ,change_ = boolopt "change" rawopts + ,presentorfuture_ = presentorfutureopt rawopts ,cliopts_ = cliopts } +-- | Should transactions dated later than today be included ? +-- Like flat/tree mode, there are three states, and the meaning of default can vary by command. +data PresentOrFutureOpt = PFDefault | PFPresent | PFFuture deriving (Eq, Show, Data, Typeable) +instance Default PresentOrFutureOpt where def = PFDefault + +presentorfutureopt :: RawOpts -> PresentOrFutureOpt +presentorfutureopt rawopts = + case reverse $ filter (`elem` ["present","future"]) $ map fst rawopts of + ("present":_) -> PFPresent + ("future":_) -> PFFuture + _ -> PFDefault + checkUIOpts :: UIOpts -> UIOpts checkUIOpts opts = either usageError (const opts) $ do diff --git a/hledger-ui/Hledger/UI/UIState.hs b/hledger-ui/Hledger/UI/UIState.hs index d03cf4e43..615ddc6c5 100644 --- a/hledger-ui/Hledger/UI/UIState.hs +++ b/hledger-ui/Hledger/UI/UIState.hs @@ -124,6 +124,14 @@ toggleHistorical ui@UIState{aopts=uopts@UIOpts{cliopts_=copts@CliOpts{reportopts b | balancetype_ ropts == HistoricalBalance = PeriodChange | otherwise = HistoricalBalance +-- | Toggle between including and excluding transactions dated later than today. +toggleFuture :: UIState -> UIState +toggleFuture ui@UIState{aopts=uopts@UIOpts{presentorfuture_=pf}} = + ui{aopts=uopts{presentorfuture_=pf'}} + where + pf' | pf == PFFuture = PFPresent + | otherwise = PFFuture + -- | Toggle between showing all and showing only real (non-virtual) items. toggleReal :: UIState -> UIState toggleReal ui@UIState{aopts=uopts@UIOpts{cliopts_=copts@CliOpts{reportopts_=ropts}}} = diff --git a/hledger-ui/Hledger/UI/UIUtils.hs b/hledger-ui/Hledger/UI/UIUtils.hs index b325f9afb..67c008c36 100644 --- a/hledger-ui/Hledger/UI/UIUtils.hs +++ b/hledger-ui/Hledger/UI/UIUtils.hs @@ -92,6 +92,7 @@ helpDialog copts = ,"cycle cleared/not cleared/all" ,"toggle cleared filter" ] !! (statusstyle-1)) + ,renderKey ("F", "toggle future/present") ,renderKey ("R", "toggle real/all") ,renderKey ("Z", "toggle nonzero/all") ,renderKey ("DEL/BS", "remove filters") diff --git a/hledger-ui/hledger-ui.m4.md b/hledger-ui/hledger-ui.m4.md index a8106b2e1..3003647ea 100644 --- a/hledger-ui/hledger-ui.m4.md +++ b/hledger-ui/hledger-ui.m4.md @@ -44,6 +44,7 @@ hledger-ui is hledger's curses-style interface, providing an efficient full-wind for viewing accounts and transactions, and some limited data entry capability. It is easier than hledger's command-line interface, and sometimes quicker and more convenient than the web interface. +Note hledger-ui hides transactions dated in the future, by default. Like hledger, it reads _files_ For more about this see hledger(1), hledger_journal(5) etc. @@ -72,7 +73,13 @@ Any QUERYARGS are interpreted as a hledger search query which filters the data. `-T --tree` : show accounts as a tree -hledger input options: +`--present` +: exclude transactions dated later than today (default) (experimental) + +`--future` +: include transactions dated later than today (experimental) + + hledger input options: _inputoptions_ @@ -122,6 +129,12 @@ press `ENTER` to set it, or `ESCAPE`to cancel. There are also keys for quickly adjusting some common filters like account depth and transaction status (see below). `BACKSPACE` or `DELETE` removes all filters, showing all transactions. +As mentioned above, hledger-ui hides transactions in the future by default. +`F` toggles showing and hiding these future transactions. +This is similar to using a query like `date:-tomorrow`, but more convenient. +(experimental) + + `ESCAPE` removes all filters and jumps back to the top screen. Or, it cancels a minibuffer edit or help dialog in progress. @@ -211,10 +224,10 @@ Similar to the accounts screen, the historical total is affected by transactions If the historical total is not disturbed by a filter query, it will be the running historical balance you would see on a bank register for the current account. -Transactions affecting this account's subaccounts will be shown if -the accounts screen was in tree mode, -or if it was in flat mode but the selected account had depth-clipped subaccounts. -In other words, the register always shows just the transactions contributing to the balance on the accounts screen. +Transactions affecting this account's subaccounts will be included in the register +if the accounts screen is in tree mode, +or if it's in flat mode but this account has subaccounts which are not shown due to a depth limit. +In other words, the register always shows the transactions contributing to the balance shown on the accounts screen. Tree mode/flat mode can be toggled with `T` here also. `U` toggles filtering by [unmarked status](/journal.html#status), showing or hiding unmarked transactions.