imp: ui: show menu screen by default; drop the --menu flag

It's a simpler and more natural default; power users can use a flag to
start in the desired screen.
This commit is contained in:
Simon Michael 2023-03-24 10:07:53 -10:00
parent 3705e4c15e
commit 6cbf354206
4 changed files with 66 additions and 112 deletions

View File

@ -18,7 +18,6 @@ import Data.Bifunctor (first)
import Data.Function ((&)) import Data.Function ((&))
import Data.List (find) import Data.List (find)
import Data.List.Extra (nubSort) import Data.List.Extra (nubSort)
import qualified Data.Map as M (elems)
import Data.Maybe (fromMaybe) import Data.Maybe (fromMaybe)
import qualified Data.Text as T import qualified Data.Text as T
import Graphics.Vty (mkVty, Mode (Mouse), Vty (outputIface), Output (setMode)) import Graphics.Vty (mkVty, Mode (Mouse), Vty (outputIface), Output (setMode))
@ -45,6 +44,7 @@ import Hledger.UI.IncomestatementScreen
import Hledger.UI.RegisterScreen import Hledger.UI.RegisterScreen
import Hledger.UI.TransactionScreen import Hledger.UI.TransactionScreen
import Hledger.UI.ErrorScreen import Hledger.UI.ErrorScreen
import Hledger.UI.UIScreens
---------------------------------------------------------------------- ----------------------------------------------------------------------
@ -141,26 +141,25 @@ runBrickUi uopts0@UIOpts{uoCliOpts=copts@CliOpts{inputopts_=_iopts,reportspec_=r
where filtered = filterQuery (\x -> not $ queryIsDepth x || queryIsDate x) where filtered = filterQuery (\x -> not $ queryIsDepth x || queryIsDate x)
-- Choose the initial screen to display. -- Choose the initial screen to display.
-- We like to show the balance sheet accounts screen by default, -- We also set up a stack of previous screens, as if you had navigated down to it from the top.
-- but that can change eg if we can't detect any accounts for it, -- Note the previous screens list is ordered nearest-first, with the top-most (menu) screen last.
-- or if an account query has been provided at startup, -- Keep all of this synced with msNew.
-- or if a specific screen has been requested by command line flag.
-- Whichever is the initial screen, we also set up a stack of previous screens,
-- as if you had navigated down to it from the top.
-- (remember, the previous screens list is ordered nearest/lowest first)
rawopts = rawopts_ $ uoCliOpts $ uopts rawopts = rawopts_ $ uoCliOpts $ uopts
(prevscrs, currscr) = (prevscrs, currscr) =
dbg1With (showScreenStack "initial" showScreenSelection . uncurry2 (uiState defuiopts nulljournal)) $ dbg1With (showScreenStack "initial" showScreenSelection . uncurry2 (uiState defuiopts nulljournal)) $
if if
| boolopt "menu" rawopts -> ([], menuscr) -- An accounts screen is specified. Its previous screen will be the menu screen with it selected.
| boolopt "all" rawopts -> ([msSetSelectedScreen 0 menuscr], allacctsscr) | boolopt "cash" rawopts -> ([msSetSelectedScreen csItemIndex menuscr], csacctsscr)
| boolopt "bs" rawopts -> ([menuscr], bsacctsscr) | boolopt "bs" rawopts -> ([msSetSelectedScreen bsItemIndex menuscr], bsacctsscr)
| boolopt "is" rawopts -> ([msSetSelectedScreen 2 menuscr], isacctsscr) | boolopt "is" rawopts -> ([msSetSelectedScreen isItemIndex menuscr], isacctsscr)
| boolopt "all" rawopts -> ([msSetSelectedScreen asItemIndex menuscr], allacctsscr)
-- With --register=ACCT, the initial screen stack is: -- A register screen is specified with --register=ACCT. The initial screen stack will be:
-- menu screen, with ACCTSSCR selected --
-- ACCTSSCR (the accounts screen containing ACCT), with ACCT selected -- menu screen, with ACCTSSCR selected
-- register screen for ACCT -- ACCTSSCR (the accounts screen containing ACCT), with ACCT selected
-- register screen for ACCT
--
| Just apat <- uoRegister uopts -> | Just apat <- uoRegister uopts ->
let let
-- the account being requested -- the account being requested
@ -193,17 +192,13 @@ runBrickUi uopts0@UIOpts{uoCliOpts=copts@CliOpts{inputopts_=_iopts,reportspec_=r
menuscr' = msSetSelectedScreen selidx menuscr menuscr' = msSetSelectedScreen selidx menuscr
in ([acctsscr, menuscr'], regscr) in ([acctsscr, menuscr'], regscr)
-- No balance sheet accounts detected, or an initial account query specified: -- Otherwise, start on the menu screen.
| not hasbsaccts || hasacctquery -> ([msSetSelectedScreen 0 menuscr], allacctsscr) | otherwise -> ([], menuscr)
| otherwise -> ([menuscr], bsacctsscr)
where where
hasbsaccts = any (`elem` accttypes) [Asset, Liability, Equity]
where accttypes = M.elems $ jaccounttypes j
hasacctquery = matchesQuery queryIsAcct $ _rsQuery rspec
menuscr = msNew menuscr = msNew
allacctsscr = asNew uopts today j Nothing allacctsscr = asNew uopts today j Nothing
csacctsscr = csNew uopts today j Nothing
bsacctsscr = bsNew uopts today j Nothing bsacctsscr = bsNew uopts today j Nothing
isacctsscr = isNew uopts today j Nothing isacctsscr = isNew uopts today j Nothing

View File

@ -36,7 +36,6 @@ uiflags = [
-- flagNone ["debug-ui"] (setboolopt "rules-file") "run with no terminal output, showing console" -- flagNone ["debug-ui"] (setboolopt "rules-file") "run with no terminal output, showing console"
flagNone ["watch","w"] (setboolopt "watch") "watch for data and date changes and reload automatically" flagNone ["watch","w"] (setboolopt "watch") "watch for data and date changes and reload automatically"
,flagReq ["theme"] (\s opts -> Right $ setopt "theme" s opts) "THEME" ("use this custom display theme ("++intercalate ", " themeNames++")") ,flagReq ["theme"] (\s opts -> Right $ setopt "theme" s opts) "THEME" ("use this custom display theme ("++intercalate ", " themeNames++")")
,flagNone ["menu"] (setboolopt "menu") "start in the menu screen"
,flagNone ["cash"] (setboolopt "cash") "start in the cash accounts screen" ,flagNone ["cash"] (setboolopt "cash") "start in the cash accounts screen"
,flagNone ["bs"] (setboolopt "bs") "start in the balance sheet accounts screen" ,flagNone ["bs"] (setboolopt "bs") "start in the balance sheet accounts screen"
,flagNone ["is"] (setboolopt "is") "start in the income statement accounts screen" ,flagNone ["is"] (setboolopt "is") "start in the income statement accounts screen"
@ -58,7 +57,7 @@ uiflags = [
--uimode :: Mode RawOpts --uimode :: Mode RawOpts
uimode = (mode "hledger-ui" (setopt "command" "ui" def) uimode = (mode "hledger-ui" (setopt "command" "ui" def)
"browse accounts, postings and entries in a full-window TUI" "browse accounts, postings and entries in a full-window TUI"
(argsFlag "[--menu|--cash|--bs|--is|--all|--register=ACCT] [QUERY]") []){ (argsFlag "[--cash|--bs|--is|--all|--register=ACCT] [QUERY]") []){
modeGroupFlags = Group { modeGroupFlags = Group {
groupUnnamed = uiflags groupUnnamed = uiflags
,groupHidden = hiddenflags ,groupHidden = hiddenflags

View File

@ -22,12 +22,16 @@ module Hledger.UI.UIScreens
,msUpdate ,msUpdate
,asNew ,asNew
,asUpdate ,asUpdate
,bsNew ,asItemIndex
,bsUpdate
,csNew ,csNew
,csUpdate ,csUpdate
,csItemIndex
,bsNew
,bsUpdate
,bsItemIndex
,isNew ,isNew
,isUpdate ,isUpdate
,isItemIndex
,rsNew ,rsNew
,rsUpdate ,rsUpdate
,tsNew ,tsNew
@ -76,24 +80,29 @@ esNew msg =
esUpdate :: ErrorScreenState -> ErrorScreenState esUpdate :: ErrorScreenState -> ErrorScreenState
esUpdate = dbgui "esUpdate`" esUpdate = dbgui "esUpdate`"
-- | Construct a menu screen. -- | Construct a menu screen, with the first item selected.
-- Screen-specific arguments: none. -- Screen-specific arguments: none.
msNew :: Screen msNew :: Screen
msNew = msNew =
dbgui "msNew" $ dbgui "msNew" $
MS MSS { MS MSS { _mssList = list MenuList (V.fromList items ) 1, _mssUnused = () }
_mssList = list MenuList (V.fromList [ where
-- keep initial screen stack setup in UI.Main synced with these -- keep synced with: indexes below, initial screen stack setup in UI.Main
items = [
MenuScreenItem "Cash accounts" CashScreen MenuScreenItem "Cash accounts" CashScreen
,MenuScreenItem "Balance sheet accounts" Balancesheet ,MenuScreenItem "Balance sheet accounts" Balancesheet
,MenuScreenItem "Income statement accounts" Incomestatement ,MenuScreenItem "Income statement accounts" Incomestatement
,MenuScreenItem "All accounts" Accounts ,MenuScreenItem "All accounts" Accounts
]) 1 ]
& listMoveTo defaultscreenitem
,_mssUnused = () -- keep synced with items above.
} where -- | Positions of menu screen items, so we can move selection to them.
-- select balance sheet accounts at startup (currently this screen is constructed only then) [
defaultscreenitem = 1 csItemIndex,
bsItemIndex,
isItemIndex,
asItemIndex
] = [0..3] :: [Int]
-- | Update a menu screen. Currently a no-op since menu screen -- | Update a menu screen. Currently a no-op since menu screen
-- has unchanging content. -- has unchanging content.

View File

@ -64,9 +64,6 @@ Any QUERYARGS are interpreted as a hledger search query which filters the data.
`--menu` `--menu`
: start in the menu screen : start in the menu screen
`--all`
: start in the all accounts screen
`--cash` `--cash`
: start in the cash accounts screen : start in the cash accounts screen
@ -76,6 +73,9 @@ Any QUERYARGS are interpreted as a hledger search query which filters the data.
`--is` `--is`
: start in the income statement accounts screen : start in the income statement accounts screen
`--all`
: start in the all accounts screen
`--register=ACCTREGEX` `--register=ACCTREGEX`
: start in the (first) matched account's register screen : start in the (first) matched account's register screen
@ -216,92 +216,44 @@ Additional screen-specific keys are described below.
# SCREENS # SCREENS
hledger-ui shows several different screens, described below. At startup, hledger-ui shows a menu screen by default.
It shows the "Balance sheet accounts" screen to start with, except in the following situations: From here you can navigate to other screens using the cursor keys:
`UP`/`DOWN` to select, `RIGHT` to move to the selected screen, `LEFT` to return to the previous screen.
Or you can use `ESC` to return directly to the top menu screen.
- If no asset/liability/equity accounts can be detected, You can also use a command line flag to specific a different startup screen
or if an account query has been given on the command line, (`--cs`, `--bs`, `--is`, `--all`, or `--register=ACCT`).
it starts in the "All accounts" screen.
- If a starting screen is specified with --menu/--all/--bs/--is/--register
on the command line, it starts in that screen.
From any screen you can press `LEFT` or `ESC` to navigate back to the top level "Menu" screen.
## Menu ## Menu
The top-most screen. This is the top-most screen.
From here you can navigate to three accounts screens: From here you can navigate to several screens listing accounts of various types.
Note some of these may not show anything until you have configured [account types](/hledger.html#account-types).
## All accounts
This screen shows all accounts (possibly filtered by a query),
and their end balances on the date shown in the title bar
(or their balance changes in the period shown in the title bar, toggleable with `H`).
It is like the `hledger balance` command.
## Cash accounts ## Cash accounts
This screen shows "cash" (ie, liquid asset) accounts (like `hledger balancesheet type:c`), This screen shows "cash" (ie, liquid asset) accounts (like `hledger balancesheet type:c`).
if these can be detected (see [account types](/hledger.html#account-types)). It always shows balances (historical ending balances on the date shown in the title line).
It always shows end balances.
## Balance sheet accounts ## Balance sheet accounts
This screen shows asset, liability and equity accounts (like `hledger balancesheetequity`). This screen shows asset, liability and equity accounts (like `hledger balancesheetequity`).
It always shows end balances. It always shows balances.
## Income statement accounts ## Income statement accounts
This screen shows revenue and expense accounts (like `hledger incomestatement`). This screen shows revenue and expense accounts (like `hledger incomestatement`).
It always shows balance changes. It always shows changes (balance changes in the period shown in the title line).
All of these accounts screens work in much the same way: ## All accounts
They show accounts which have been posted to by transactions, This screen shows all accounts in your journal (unless filtered by a query; like `hledger balance`).
as well as accounts which have been declared with an [account directive](#account) It shows balances by default; you can toggle showing changes with the `H` key.
(except for empty parent accounts).
If you specify a query on the command line or with `/` in the app,
they show just the matched accounts, and the balances from matched transactions.
hledger-ui shows accounts with zero balances by default (unlike command-line hledger).
To hide these, press `z` to toggle nonzero mode.
Account names are shown as a flat list by default; press `t` to toggle tree mode.
In list mode, account balances are exclusive of subaccounts, except where subaccounts are hidden by a depth limit (see below).
In tree mode, all account balances are inclusive of subaccounts.
To see less detail, press a number key, `1` to `9`, to set a depth limit.
Or use `-` to decrease and `+`/`=` to increase the depth limit.
`0` shows even less detail, collapsing all accounts to a single total.
To remove the depth limit, set it higher than the maximum account depth, or press `ESCAPE`.
`H` toggles between showing historical balances or period balances (on the "All accounts" screen).
Historical balances (the default) are ending balances at the end of the report period,
taking into account all transactions before that date (filtered by the filter query if any),
including transactions before the start of the report period. In other words, historical
balances are what you would see on a bank statement for that account (unless disturbed by
a filter query). Period balances ignore transactions before the report start date, so they
show the change in balance during the report period. They are more useful eg when viewing a time log.
`U` toggles filtering by [unmarked status](hledger.html#status),
including or excluding unmarked postings in the balances.
Similarly, `P` toggles pending postings,
and `C` toggles cleared postings.
(By default, balances include all postings;
if you activate one or two status filters, only those postings are included;
and if you activate all three, the filter is removed.)
`R` toggles real mode, in which [virtual postings](hledger.html#virtual-postings) are ignored.
Press `RIGHT` to view an account's register screen,
Or, `LEFT` to see the menu screen.
## Register ## Register
This screen shows the transactions affecting a particular account, like a check register. This screen shows the transactions affecting a particular account.
Each line represents one transaction and shows: Each line represents one transaction, and shows:
- the other account(s) involved, in abbreviated form. - the other account(s) involved, in abbreviated form.
(If there are both real and virtual postings, it (If there are both real and virtual postings, it
@ -310,12 +262,11 @@ Each line represents one transaction and shows:
- the overall change to the current account's balance; - the overall change to the current account's balance;
positive for an inflow to this account, negative for an outflow. positive for an inflow to this account, negative for an outflow.
- the running historical total or period total for the current account, after the transaction. - the running total after the transaction.
This can be toggled with `H`. With the `H` key you can toggle between
Similar to the accounts screen, the historical total is affected by transactions - the period total, which is from just the transactions displayed
(filtered by the filter query) before the report start date, while the period total is not. - or the historical total, which includes any undisplayed transactions before the start of the report period (and matching the filter query if any).
If the historical total is not disturbed by a filter query, it will be the This will be the running historical balance (what you would see on a bank's website, eg) if not disturbed by a query.
running historical balance you would see on a bank register for the current account.
Transactions affecting this account's subaccounts will be included in the register Transactions affecting this account's subaccounts will be included in the register
if the accounts screen is in tree mode, if the accounts screen is in tree mode,