ui: don't force --auto/--forecast on; merge --future with --forecast (#1193)

Periodic transactions were always on, which meant that periodic
transactions occurring today were always shown, in future or present
mode.

Now, both periodic transactions and display of future transactions are
controlled by --forecast, and toggleable by the F key ("forecast
mode"). The --future flag has been dropped (it still works as a hidden
alias for --forecast, but is deprecated).

It seemed to also make sense to leave auto postings off by default,
like hledger.
This commit is contained in:
Simon Michael 2020-02-16 05:27:09 -08:00
parent e8e1566083
commit 4eba930a5c
7 changed files with 63 additions and 64 deletions

View File

@ -83,12 +83,13 @@ asInit d reset ui@UIState{
uopts' = uopts{cliopts_=copts{reportopts_=ropts'}}
ropts' = ropts{accountlistmode_=if tree_ ropts then ALTree else ALFlat}
-- Add a date:-tomorrow to the query to exclude future txns, by default.
-- XXX this necessitates special handling in multiBalanceReport, at least
pfq | presentorfuture_ uopts == PFFuture = Any
| otherwise = Date $ DateSpan Nothing (Just $ addDays 1 d)
q = And [queryFromOpts d ropts, pfq]
q = And [queryFromOpts d ropts
-- Exclude future transactions except in forecast mode
-- XXX this necessitates special handling in multiBalanceReport, at least
,if forecast_ ropts
then Any
else Date $ DateSpan Nothing (Just $ addDays 1 d)
]
-- run the report
(items,_total) = report ropts' q j
@ -123,7 +124,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=uopts@UIOpts{cliopts_=copts@CliOpts{reportopts_=ropts}}
asDraw UIState{aopts=_uopts@UIOpts{cliopts_=copts@CliOpts{reportopts_=ropts}}
,ajournal=j
,aScreen=s@AccountsScreen{}
,aMode=mode
@ -215,7 +216,7 @@ asDraw UIState{aopts=uopts@UIOpts{cliopts_=copts@CliOpts{reportopts_=ropts}}
,("-+", str "depth")
,("T", renderToggle (tree_ ropts) "flat" "tree")
,("H", renderToggle (not ishistorical) "end-bals" "changes")
,("F", renderToggle (presentorfuture_ uopts == PFFuture) "present" "future")
,("F", renderToggle1 (forecast_ ropts) "forecast")
--,("/", "filter")
--,("DEL", "unfilter")
--,("ESC", "cancel/top")
@ -336,7 +337,9 @@ 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 (KChar 'F') []) ->
let ui'@UIState{aopts=UIOpts{cliopts_=copts'}} = toggleForecast ui
in liftIO (uiReloadJournal copts' d ui') >>= continue
VtyEvent (EvKey (KDown) [MShift]) -> continue $ regenerateScreens j d $ shrinkReportPeriod d ui
VtyEvent (EvKey (KUp) [MShift]) -> continue $ regenerateScreens j d $ growReportPeriod d ui

View File

@ -63,14 +63,8 @@ writeChan = BC.writeBChan
main :: IO ()
main = do
opts <- getHledgerUIOpts
let copts = cliopts_ opts
copts' = copts
{ inputopts_ = (inputopts_ copts) { auto_ = True }
, reportopts_ = (reportopts_ copts) { forecast_ = True }
}
-- when (debug_ $ cliopts_ opts) $ printf "%s\n" prognameandversion >> printf "opts: %s\n" (show opts)
run $ opts { cliopts_ = copts' }
run opts
where
run opts
| "help" `inRawOpts` (rawopts_ $ cliopts_ opts) = putStr (showModeUsage uimode) >> exitSuccess

View File

@ -59,7 +59,7 @@ rsSetAccount a forceinclusive scr@RegisterScreen{} =
rsSetAccount _ _ scr = scr
rsInit :: Day -> Bool -> UIState -> UIState
rsInit d reset ui@UIState{aopts=uopts@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,9 +69,13 @@ rsInit d reset ui@UIState{aopts=uopts@UIOpts{cliopts_=CliOpts{reportopts_=ropts}
ropts' = ropts{
depth_=Nothing
}
pfq | presentorfuture_ uopts == PFFuture = Any
| otherwise = Date $ DateSpan Nothing (Just $ addDays 1 d)
q = And [queryFromOpts d ropts', pfq]
q = And [queryFromOpts d ropts'
-- Exclude future transactions except in forecast mode
-- XXX this necessitates special handling in multiBalanceReport, at least
,if forecast_ ropts
then Any
else Date $ DateSpan Nothing (Just $ addDays 1 d)
]
-- reportq = filterQuery (not . queryIsDepth) q
(_label,items) = accountTransactionsReport ropts' j q thisacctq
@ -133,7 +137,7 @@ rsInit d reset ui@UIState{aopts=uopts@UIOpts{cliopts_=CliOpts{reportopts_=ropts}
rsInit _ _ _ = error "init function called with wrong screen type, should not happen"
rsDraw :: UIState -> [Widget Name]
rsDraw UIState{aopts=uopts@UIOpts{cliopts_=copts@CliOpts{reportopts_=ropts}}
rsDraw UIState{aopts=_uopts@UIOpts{cliopts_=copts@CliOpts{reportopts_=ropts}}
,aScreen=RegisterScreen{..}
,aMode=mode
} =
@ -232,7 +236,7 @@ rsDraw UIState{aopts=uopts@UIOpts{cliopts_=copts@CliOpts{reportopts_=ropts}}
-- ,("RIGHT", str "transaction")
,("T", renderToggle (tree_ ropts) "flat(-subs)" "tree(+subs)") -- rsForceInclusive may override, but use tree_ to ensure a visible toggle effect
,("H", renderToggle (not ishistorical) "historical" "period")
,("F", renderToggle (presentorfuture_ uopts == PFFuture) "present" "future")
,("F", renderToggle1 (forecast_ ropts) "forecast")
-- ,("a", "add")
-- ,("g", "reload")
-- ,("q", "quit")
@ -331,7 +335,9 @@ 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 'F') []) ->
let ui'@UIState{aopts=UIOpts{cliopts_=copts'}} = toggleForecast ui
in liftIO (uiReloadJournal copts' d ui') >>= rsCenterAndContinue
VtyEvent (EvKey (KChar '/') []) -> continue $ regenerateScreens j d $ showMinibuffer ui
VtyEvent (EvKey (KDown) [MShift]) -> continue $ regenerateScreens j d $ shrinkReportPeriod d ui

View File

@ -7,11 +7,8 @@
module Hledger.UI.UIOptions
where
import Data.Data (Data)
import Data.Default
import Data.Typeable (Typeable)
import Data.List (intercalate)
import Data.Maybe (fromMaybe)
import System.Environment
import Hledger.Cli hiding (progname,version,prognameandversion)
@ -41,7 +38,6 @@ uiflags = [
,flagNone ["flat","F"] (setboolopt "flat") "show accounts as a list (default)"
,flagNone ["tree","T"] (setboolopt "tree") "show accounts as a tree"
-- ,flagNone ["present"] (setboolopt "present") "exclude transactions dated later than today (default)"
,flagNone ["future"] (setboolopt "future") "show transactions dated later than today (normally hidden)"
-- ,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"] (setboolopt "no-elide") "don't compress empty parent accounts on one line"
@ -54,6 +50,7 @@ uimode = (mode "hledger-ui" (setopt "command" "ui" def)
modeGroupFlags = Group {
groupUnnamed = uiflags
,groupHidden = hiddenflags
++ [flagNone ["future"] (setboolopt "forecast") "compatibility alias, use --forecast instead"]
,groupNamed = [(generalflagsgroup1)]
}
,modeHelpSuffix=[
@ -65,7 +62,6 @@ uimode = (mode "hledger-ui" (setopt "command" "ui" def)
data UIOpts = UIOpts {
watch_ :: Bool
,change_ :: Bool
,presentorfuture_ :: PresentOrFutureOpt
,cliopts_ :: CliOpts
} deriving (Show)
@ -73,7 +69,6 @@ defuiopts = UIOpts
def
def
def
def
-- instance Default CliOpts where def = defcliopts
@ -83,23 +78,9 @@ 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 =
fromMaybe PFDefault . choiceopt parse where
parse = \case
"present" -> Just PFPresent
"future" -> Just PFFuture
_ -> Nothing
checkUIOpts :: UIOpts -> UIOpts
checkUIOpts opts =
either usageError (const opts) $ do

View File

@ -151,13 +151,24 @@ 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'}}
-- | 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.
--
toggleForecast :: UIState -> UIState
toggleForecast ui@UIState{aopts=uopts@UIOpts{cliopts_=copts@CliOpts{reportopts_=ropts}}} =
ui{aopts=uopts{cliopts_=copts'}}
where
pf' | pf == PFFuture = PFPresent
| otherwise = PFFuture
copts' = copts{reportopts_=ropts{forecast_=not $ forecast_ ropts}}
-- | Toggle between showing all and showing only real (non-virtual) items.
toggleReal :: UIState -> UIState

View File

@ -19,6 +19,7 @@ module Hledger.UI.UIUtils (
,moveUpEvents
,normaliseMovementKeys
,renderToggle
,renderToggle1
,replaceHiddenAccountsNameWith
,scrollSelectionToMiddle
,suspend
@ -122,7 +123,7 @@ helpDialog _copts =
withAttr ("help" <> "heading") $ str "Filtering"
,renderKey ("/ ", "set a filter query")
,renderKey ("UPC ", "show unmarked/pending/cleared")
,renderKey ("F ", "show future/present txns")
,renderKey ("F ", "show future & periodic txns")
,renderKey ("R ", "show real/all postings")
,renderKey ("Z ", "show nonzero/all amounts")
,renderKey ("DEL ", "remove filters")
@ -210,7 +211,7 @@ borderKeysStr' keydescs =
-- sep = str " | "
sep = str " "
-- | Render the two states of a toggle, highlighting the active one.
-- | Show both states of a toggle ("aaa/bbb"), highlighting the active one.
renderToggle :: Bool -> String -> String -> Widget Name
renderToggle isright l r =
let bold = withAttr ("border" <> "selected") in
@ -218,6 +219,14 @@ renderToggle isright l r =
then str (l++"/") <+> bold (str r)
else bold (str l) <+> str ("/"++r)
-- | Show a toggle's label, highlighted (bold) when the toggle is active.
renderToggle1 :: Bool -> String -> Widget Name
renderToggle1 isactive l =
let bold = withAttr ("border" <> "selected") in
if isactive
then bold (str l)
else str l
-- temporary shenanigans:
-- | Convert the special account name "*" (from balance report with depth limit 0) to something clearer.

View File

@ -44,14 +44,13 @@ 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 has some different defaults (experimental):
- it generates rule-based transactions and postings by default (--forecast and --auto are always on).
- it hides transactions dated in the future by default (change this with --future or the F key).
Like hledger, it reads _files_
For more about this see hledger(1), hledger_journal(5) etc.
Unlike hledger, hledger-ui hides all future-dated transactions by default.
They can be revealed, along with any rule-generated periodic transactions,
by pressing the F key (or starting with --forecast) to enable "forecast mode".
# OPTIONS
Note: if invoking hledger-ui as a hledger subcommand, write `--` before options as shown above.
@ -76,9 +75,6 @@ Any QUERYARGS are interpreted as a hledger search query which filters the data.
`-T --tree`
: show accounts as a tree
`--future`
: show transactions dated later than today (normally hidden)
hledger input options:
_inputoptions_
@ -129,11 +125,10 @@ 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 shows auto-generated periodic transactions,
and hides future transactions (auto-generated or not) by default.
`F` toggles showing and hiding these future transactions.
This is similar to using a query like `date:-tomorrow`, but more convenient.
(experimental)
As mentioned above, by default hledger-ui hides future transactions -
both ordinary transactions recorded in the journal, and periodic
transactions generated by rule. `F` toggles forecast mode, in which
future/forecasted transactions are shown. (experimental)
`ESCAPE` removes all filters and jumps back to the top screen.
Or, it cancels a minibuffer edit or help dialog in progress.