imp: commodities/payees/tags: used/declared flags, like accounts
And general cleanup of options and help across the accounts, commodities, payees, tags commands.
This commit is contained in:
parent
38aadddf7b
commit
4a5775da71
@ -79,6 +79,7 @@ module Hledger.Data.Amount (
|
||||
amountUnstyled,
|
||||
commodityStylesFromAmounts,
|
||||
-- canonicalStyleFrom,
|
||||
getAmounts,
|
||||
|
||||
-- ** rendering
|
||||
AmountFormat(..),
|
||||
@ -566,6 +567,13 @@ instance HasAmounts Amount where
|
||||
olds)
|
||||
Nothing -> olds
|
||||
|
||||
-- | Get an amount and its attached cost amount if any. Returns one or two amounts.
|
||||
getAmounts :: Amount -> [Amount]
|
||||
getAmounts a@Amount{acost} = a : case acost of
|
||||
Nothing -> []
|
||||
Just (UnitCost c) -> [c]
|
||||
Just (TotalCost c) -> [c]
|
||||
|
||||
-- AmountStyle helpers
|
||||
|
||||
-- | Replace one AmountStyle with another, but don't just replace the display precision;
|
||||
@ -1094,13 +1102,17 @@ mixedAmountSetStyles = styleAmounts
|
||||
-- v4
|
||||
instance HasAmounts MixedAmount where
|
||||
styleAmounts styles = mapMixedAmountUnsafe (styleAmounts styles)
|
||||
-- getAmounts = concatMap getAmounts . amounts
|
||||
|
||||
instance HasAmounts BalanceData where
|
||||
styleAmounts styles balance@BalanceData{bdexcludingsubs,bdincludingsubs} =
|
||||
balance{bdexcludingsubs=styleAmounts styles bdexcludingsubs, bdincludingsubs=styleAmounts styles bdincludingsubs}
|
||||
-- getAmounts BalanceData{bdexcludingsubs, bdincludingsubs} =
|
||||
-- getAmounts bdexcludingsubs <> getAmounts bdincludingsubs
|
||||
|
||||
instance HasAmounts a => HasAmounts (PeriodData a) where
|
||||
styleAmounts styles = fmap (styleAmounts styles)
|
||||
-- getAmounts
|
||||
|
||||
instance HasAmounts a => HasAmounts (Account a) where
|
||||
styleAmounts styles acct@Account{adata} =
|
||||
|
||||
@ -71,9 +71,14 @@ module Hledger.Data.Journal (
|
||||
journalTagsDeclared,
|
||||
journalTagsUsed,
|
||||
journalTagsDeclaredOrUsed,
|
||||
journalAmounts,
|
||||
journalPostingAmounts,
|
||||
journalPostingAndCostAmounts,
|
||||
journalCommoditiesDeclared,
|
||||
journalCommoditiesUsed,
|
||||
journalCommodities,
|
||||
journalCommoditiesFromPriceDirectives,
|
||||
journalCommoditiesFromTransactions,
|
||||
journalDateSpan,
|
||||
journalDateSpanBothDates,
|
||||
journalStartDate,
|
||||
@ -86,8 +91,7 @@ module Hledger.Data.Journal (
|
||||
journalNextTransaction,
|
||||
journalPrevTransaction,
|
||||
journalPostings,
|
||||
journalPostingAmounts,
|
||||
showJournalAmountsDebug,
|
||||
showJournalPostingAmountsDebug,
|
||||
journalTransactionsSimilarTo,
|
||||
-- * Account types
|
||||
journalAccountType,
|
||||
@ -395,25 +399,47 @@ journalPostings = concatMap tpostings . jtxns
|
||||
journalPostingAmounts :: Journal -> [MixedAmount]
|
||||
journalPostingAmounts = map pamount . journalPostings
|
||||
|
||||
-- | Show the journal amounts rendered, suitable for debug logging.
|
||||
showJournalAmountsDebug :: Journal -> String
|
||||
showJournalAmountsDebug = show.map showMixedAmountOneLine.journalPostingAmounts
|
||||
-- | Show the journal posting amounts rendered, suitable for debug logging.
|
||||
showJournalPostingAmountsDebug :: Journal -> String
|
||||
showJournalPostingAmountsDebug = show . map showMixedAmountOneLine . journalPostingAmounts
|
||||
|
||||
-- | All raw amounts used in this journal's postings and costs,
|
||||
-- with MixedAmounts flattened, in parse order.
|
||||
journalPostingAndCostAmounts :: Journal -> [Amount]
|
||||
journalPostingAndCostAmounts = concatMap getAmounts . concatMap (amountsRaw . pamount) . journalPostings
|
||||
|
||||
-- | All raw amounts appearing in this journal, with MixedAmounts flattened, in no particular order.
|
||||
-- (Including from posting amounts, cost amounts, P directives, and the last D directive.)
|
||||
journalAmounts :: Journal -> S.Set Amount
|
||||
journalAmounts = S.fromList . journalStyleInfluencingAmounts True
|
||||
|
||||
-- | Sorted unique commodity symbols declared by commodity directives in this journal.
|
||||
journalCommoditiesDeclared :: Journal -> [CommoditySymbol]
|
||||
journalCommoditiesDeclared = M.keys . jdeclaredcommodities
|
||||
|
||||
-- | Sorted unique commodity symbols used in this journal.
|
||||
-- | Sorted unique commodity symbols used anywhere in this journal, including
|
||||
-- commodity directives, P directives, the last D directive, posting amounts and cost amounts.
|
||||
journalCommoditiesUsed :: Journal -> [CommoditySymbol]
|
||||
journalCommoditiesUsed = S.elems . S.fromList . concatMap (map acommodity . amounts) . journalPostingAmounts
|
||||
journalCommoditiesUsed j = S.elems $
|
||||
journalCommoditiesFromPriceDirectives j <>
|
||||
(S.fromList $ map acommodity $ journalStyleInfluencingAmounts True j)
|
||||
|
||||
-- | Sorted unique commodity symbols mentioned in this journal.
|
||||
-- | Sorted unique commodity symbols mentioned anywhere in this journal.
|
||||
-- (Including commodity directives, P directives, the last D directive, posting amounts and cost amounts.)
|
||||
journalCommodities :: Journal -> S.Set CommoditySymbol
|
||||
journalCommodities j =
|
||||
M.keysSet (jdeclaredcommodities j)
|
||||
<> M.keysSet (jinferredcommoditystyles j)
|
||||
<> S.fromList (concatMap pdcommodities $ jpricedirectives j)
|
||||
where pdcommodities pd = [pdcommodity pd, acommodity $ pdamount pd]
|
||||
<> journalCommoditiesFromPriceDirectives j
|
||||
<> S.fromList (map acommodity $ journalStyleInfluencingAmounts True j)
|
||||
|
||||
-- | Sorted unique commodity symbols mentioned in this journal's P directives.
|
||||
journalCommoditiesFromPriceDirectives :: Journal -> S.Set CommoditySymbol
|
||||
journalCommoditiesFromPriceDirectives = S.fromList . concatMap pdcomms . jpricedirectives
|
||||
where pdcomms pd = [pdcommodity pd, acommodity $ pdamount pd]
|
||||
|
||||
-- | Sorted unique commodity symbols used in transactions, in either posting or cost amounts.
|
||||
journalCommoditiesFromTransactions :: Journal -> S.Set CommoditySymbol
|
||||
journalCommoditiesFromTransactions j = S.fromList $ map acommodity $ journalPostingAndCostAmounts j
|
||||
|
||||
-- | Unique transaction descriptions used in this journal.
|
||||
journalDescriptions :: Journal -> [Text]
|
||||
@ -901,11 +927,11 @@ journalCommodityStylesWith :: Rounding -> Journal -> M.Map CommoditySymbol Amoun
|
||||
journalCommodityStylesWith r = amountStylesSetRounding r . journalCommodityStyles
|
||||
|
||||
-- | Collect and save inferred amount styles for each commodity based on
|
||||
-- the posting amounts in that commodity (excluding price amounts).
|
||||
-- P directive amounts, posting amounts but not cost amounts, and maybe the last D amount, in that commodity.
|
||||
-- Can return an error message eg if inconsistent number formats are found.
|
||||
journalInferCommodityStyles :: Journal -> Either String Journal
|
||||
journalInferCommodityStyles j =
|
||||
case commodityStylesFromAmounts $ journalStyleInfluencingAmounts j of
|
||||
case commodityStylesFromAmounts $ journalStyleInfluencingAmounts False j of
|
||||
Left e -> Left e
|
||||
Right cs -> Right j{jinferredcommoditystyles = dbg7 "journalInferCommodityStyles" cs}
|
||||
|
||||
@ -982,23 +1008,23 @@ journalInferEquityFromCosts verbosetags j =
|
||||
-- Just (UnitCost ma) -> c:(concatMap amountCommodities $ amounts ma)
|
||||
-- Just (TotalCost ma) -> c:(concatMap amountCommodities $ amounts ma)
|
||||
|
||||
-- | Get an ordered list of amounts in this journal which can
|
||||
-- influence canonical amount display styles. Those amounts are, in
|
||||
-- the following order:
|
||||
-- | Get an ordered list of amounts in this journal which can influence
|
||||
-- canonical amount display styles (excluding the ones in commodity directives).
|
||||
-- They are, in the following order:
|
||||
--
|
||||
-- * amounts in market price (P) directives (in parse order)
|
||||
-- * posting amounts in transactions (in parse order)
|
||||
-- * posting amounts and optionally cost amounts (in parse order)
|
||||
-- * the amount in the final default commodity (D) directive
|
||||
--
|
||||
-- Transaction price amounts (posting amounts' acost field) are not included.
|
||||
--
|
||||
journalStyleInfluencingAmounts :: Journal -> [Amount]
|
||||
journalStyleInfluencingAmounts j =
|
||||
journalStyleInfluencingAmounts :: Bool -> Journal -> [Amount]
|
||||
journalStyleInfluencingAmounts includecost j =
|
||||
dbg7 "journalStyleInfluencingAmounts" $
|
||||
catMaybes $ concat [
|
||||
[mdefaultcommodityamt]
|
||||
,map (Just . pdamount) $ jpricedirectives j
|
||||
,map Just . concatMap (amountsRaw . pamount) $ journalPostings j
|
||||
,map Just $ if includecost
|
||||
then journalPostingAndCostAmounts j
|
||||
else concatMap amountsRaw $ journalPostingAmounts j
|
||||
]
|
||||
where
|
||||
-- D's amount style isn't actually stored as an amount, make it into one
|
||||
|
||||
@ -435,7 +435,7 @@ postingStatus Posting{pstatus=s, ptransaction=mt} = case s of
|
||||
postingAllTags :: Posting -> [Tag]
|
||||
postingAllTags p = ptags p ++ maybe [] ttags (ptransaction p)
|
||||
|
||||
-- | Tags for this transaction including any from its postings.
|
||||
-- | Tags for this transaction including any from its postings (which includes any from the postings' accounts).
|
||||
transactionAllTags :: Transaction -> [Tag]
|
||||
transactionAllTags t = ttags t ++ concatMap ptags (tpostings t)
|
||||
|
||||
|
||||
@ -67,7 +67,8 @@ module Hledger.Query (
|
||||
matchesMixedAmount,
|
||||
matchesAmount,
|
||||
matchesCommodity,
|
||||
matchesTags,
|
||||
matchesTag,
|
||||
-- patternsMatchTags,
|
||||
matchesPriceDirective,
|
||||
words'',
|
||||
queryprefixes,
|
||||
@ -883,7 +884,7 @@ matchesAccountExtra atypes atags (And qs ) a = all (\q -> matchesAccountExtra at
|
||||
matchesAccountExtra atypes atags (AnyPosting qs ) a = all (\q -> matchesAccountExtra atypes atags q a) qs
|
||||
matchesAccountExtra atypes atags (AllPostings qs ) a = all (\q -> matchesAccountExtra atypes atags q a) qs
|
||||
matchesAccountExtra atypes _ (Type ts) a = maybe False (\t -> any (t `isAccountSubtypeOf`) ts) $ atypes a
|
||||
matchesAccountExtra _ atags (Tag npat vpat) a = matchesTags npat vpat $ atags a
|
||||
matchesAccountExtra _ atags (Tag npat vpat) a = patternsMatchTags npat vpat $ atags a
|
||||
matchesAccountExtra _ _ q a = matchesAccount q a
|
||||
|
||||
-- | Does the match expression match this posting ?
|
||||
@ -911,7 +912,7 @@ matchesPosting (Sym r) Posting{pamount=as} = any (matchesCommodity (Sym r) . aco
|
||||
matchesPosting (Tag n v) p = case (reString n, v) of
|
||||
("payee", Just v') -> maybe False (regexMatchText v' . transactionPayee) $ ptransaction p
|
||||
("note", Just v') -> maybe False (regexMatchText v' . transactionNote) $ ptransaction p
|
||||
(_, mv) -> matchesTags n mv $ postingAllTags p
|
||||
(_, mv) -> patternsMatchTags n mv $ postingAllTags p
|
||||
matchesPosting (Type _) _ = False
|
||||
|
||||
-- | Like matchesPosting, but if the posting's account's type is provided,
|
||||
@ -958,7 +959,7 @@ matchesTransaction q@(Sym _) t = any (q `matchesPosting`) $ tpostings t
|
||||
matchesTransaction (Tag n v) t = case (reString n, v) of
|
||||
("payee", Just v') -> regexMatchText v' $ transactionPayee t
|
||||
("note", Just v') -> regexMatchText v' $ transactionNote t
|
||||
(_, v') -> matchesTags n v' $ transactionAllTags t
|
||||
(_, v') -> patternsMatchTags n v' $ transactionAllTags t
|
||||
matchesTransaction (Type _) _ = False
|
||||
|
||||
-- | Like matchesTransaction, but if the journal's account types are provided,
|
||||
@ -974,7 +975,7 @@ matchesTransactionExtra atype q@(Type _) t = any (matchesPostingExtra atype q) $
|
||||
matchesTransactionExtra _ q t = matchesTransaction q t
|
||||
|
||||
-- | Does the query match this transaction description ?
|
||||
-- Tests desc: terms, any other terms are ignored.
|
||||
-- Non-desc: query terms are ignored (this might disrupt some boolean queries).
|
||||
matchesDescription :: Query -> Text -> Bool
|
||||
matchesDescription (Not q) d = not $ q `matchesDescription` d
|
||||
matchesDescription (Any) _ = True
|
||||
@ -994,12 +995,25 @@ matchesDescription _ _ = False
|
||||
matchesPayeeWIP :: Query -> Payee -> Bool
|
||||
matchesPayeeWIP = matchesDescription
|
||||
|
||||
-- | Does the query match the name and optionally the value of any of these tags ?
|
||||
matchesTags :: Regexp -> Maybe Regexp -> [Tag] -> Bool
|
||||
matchesTags namepat valuepat = any (matches namepat valuepat)
|
||||
-- | Do this name regex and optional value regex match the name and value of any of these tags ?
|
||||
patternsMatchTags :: Regexp -> Maybe Regexp -> [Tag] -> Bool
|
||||
patternsMatchTags namepat valuepat = any (matches namepat valuepat)
|
||||
where
|
||||
matches npat vpat (n,v) = regexMatchText npat n && maybe (const True) regexMatchText vpat v
|
||||
|
||||
-- | Does the query match the name and optionally the value of this tag ?
|
||||
-- Non-tag: query terms are ignored (this might disrupt some boolean queries).
|
||||
matchesTag :: Query -> Tag -> Bool
|
||||
matchesTag (Not q) t = not $ q `matchesTag` t
|
||||
matchesTag (Any) _ = True
|
||||
matchesTag (None) _ = False
|
||||
matchesTag (Or qs) t = any (`matchesTag` t) $ filter queryIsTag qs
|
||||
matchesTag (And qs) t = all (`matchesTag` t) $ filter queryIsTag qs
|
||||
matchesTag (AnyPosting qs) t = all (`matchesTag` t) $ filter queryIsTag qs
|
||||
matchesTag (AllPostings qs) t = all (`matchesTag` t) $ filter queryIsTag qs
|
||||
matchesTag (Tag npat mvpat) t = patternsMatchTags npat mvpat [t]
|
||||
matchesTag _ _ = False
|
||||
|
||||
-- | Does the query match this market price ?
|
||||
matchesPriceDirective :: Query -> PriceDirective -> Bool
|
||||
matchesPriceDirective (None) _ = False
|
||||
|
||||
@ -388,16 +388,16 @@ journalFinalise iopts@InputOpts{auto_,balancingopts_,infer_costs_,infer_equity_,
|
||||
-- XXX how to force debug output here ?
|
||||
-- >>= Right . dbg0With (concatMap (T.unpack.showTransaction).jtxns)
|
||||
-- >>= \j -> deepseq (concatMap (T.unpack.showTransaction).jtxns $ j) (return j)
|
||||
<&> dbg9With (lbl "amounts after styling, forecasting, auto-posting".showJournalAmountsDebug)
|
||||
<&> dbg9With (lbl "amounts after styling, forecasting, auto-posting".showJournalPostingAmountsDebug)
|
||||
>>= (\j -> if checkordereddates then journalCheckOrdereddates j $> j else Right j) -- check ordereddates before assertions. The outer parentheses are needed.
|
||||
>>= journalBalanceTransactions balancingopts_{ignore_assertions_=not checkassertions} -- infer balance assignments and missing amounts, and maybe check balance assertions.
|
||||
<&> dbg9With (lbl "amounts after transaction-balancing".showJournalAmountsDebug)
|
||||
-- <&> dbg9With (("journalFinalise amounts after styling, forecasting, auto postings, transaction balancing"<>).showJournalAmountsDebug)
|
||||
<&> dbg9With (lbl "amounts after transaction-balancing".showJournalPostingAmountsDebug)
|
||||
-- <&> dbg9With (("journalFinalise amounts after styling, forecasting, auto postings, transaction balancing"<>).showJournalPostingAmountsDebug)
|
||||
>>= journalInferCommodityStyles -- infer commodity styles once more now that all posting amounts are present
|
||||
-- >>= Right . dbg0With (pshow.journalCommodityStyles)
|
||||
>>= (if infer_costs_ then journalTagCostsAndEquityAndMaybeInferCosts verbose_tags_ True else pure) -- With --infer-costs, infer costs from equity postings where possible
|
||||
<&> (if infer_equity_ then journalInferEquityFromCosts verbose_tags_ else id) -- With --infer-equity, infer equity postings from costs where possible
|
||||
<&> dbg9With (lbl "amounts after equity-inferring".showJournalAmountsDebug)
|
||||
<&> dbg9With (lbl "amounts after equity-inferring".showJournalPostingAmountsDebug)
|
||||
<&> journalInferMarketPricesFromTransactions -- infer market prices from commodity-exchanging transactions
|
||||
-- <&> dbg6Msg fname -- debug logging
|
||||
<&> dbgJournalAcctDeclOrder (fname <> ": acct decls : ")
|
||||
|
||||
@ -81,6 +81,8 @@ module Hledger.Cli.CliOptions (
|
||||
|
||||
-- * Other utils
|
||||
topicForMode,
|
||||
UsedOrDeclared(..),
|
||||
usedOrDeclaredFromOpts,
|
||||
|
||||
-- -- * Convenience re-exports
|
||||
-- module Data.String.Here,
|
||||
@ -815,6 +817,29 @@ registerWidthsFromOpts CliOpts{width_=Just s} =
|
||||
eof
|
||||
return (totalwidth, descwidth)
|
||||
|
||||
-- A common choice for filtering lists of declarable things.
|
||||
data UsedOrDeclared
|
||||
= Used
|
||||
| Declared
|
||||
| Undeclared
|
||||
| Unused
|
||||
deriving (Show, Eq)
|
||||
|
||||
-- Get the flag of this kind from opts, or raise an error if there's more than one.
|
||||
usedOrDeclaredFromOpts :: CliOpts -> Maybe UsedOrDeclared
|
||||
usedOrDeclaredFromOpts CliOpts{rawopts_=rawopts} =
|
||||
case ( boolopt "used" rawopts
|
||||
, boolopt "declared" rawopts
|
||||
, boolopt "undeclared" rawopts
|
||||
, boolopt "unused" rawopts
|
||||
) of
|
||||
(False, False, False, False) -> Nothing
|
||||
(True, False, False, False) -> Just Used
|
||||
(False, True, False, False) -> Just Declared
|
||||
(False, False, True, False) -> Just Undeclared
|
||||
(False, False, False, True) -> Just Unused
|
||||
_ -> error' "please pick at most one of --used, --declared, --undeclared, --unused"
|
||||
|
||||
-- Other utils
|
||||
|
||||
-- None of https://hackage.haskell.org/package/directory-1.3.8.1/docs/System-Directory.html#g:5
|
||||
|
||||
@ -36,33 +36,29 @@ import Safe (headDef)
|
||||
accountsmode = hledgerCommandMode
|
||||
$(embedFileRelative "Hledger/Cli/Commands/Accounts.txt")
|
||||
(
|
||||
[flagNone ["used","u"] (setboolopt "used") "show only accounts used by transactions"
|
||||
,flagNone ["declared","d"] (setboolopt "declared") "show only accounts declared by account directive" -- no s to avoid line wrap
|
||||
,flagNone ["unused"] (setboolopt "unused") "show only accounts declared but not used"
|
||||
,flagNone ["undeclared"] (setboolopt "undeclared") "show only accounts used but not declared"
|
||||
[flagNone ["used","u"] (setboolopt "used") "list accounts used"
|
||||
,flagNone ["declared","d"] (setboolopt "declared") "list accounts declared"
|
||||
,flagNone ["undeclared"] (setboolopt "undeclared") "list accounts used but not declared"
|
||||
,flagNone ["unused"] (setboolopt "unused") "list accounts declared but not used"
|
||||
,flagNone ["find"] (setboolopt "find") "list the first account matched by the first argument (a case-insensitive infix regexp)"
|
||||
|
||||
,flagNone ["types"] (setboolopt "types") "also show account types when known"
|
||||
,flagNone ["positions"] (setboolopt "positions") "also show where accounts were declared"
|
||||
,flagNone ["directives"] (setboolopt "directives") "show as account directives, for use in journals"
|
||||
,flagNone ["find"] (setboolopt "find") "find the first account matched by the first argument (a case-insensitive infix regexp or account name)"
|
||||
]
|
||||
++ flattreeflags False ++
|
||||
[flagReq ["drop"] (\s opts -> Right $ setopt "drop" s opts) "N" "flat mode: omit N leading account name parts"]
|
||||
)
|
||||
cligeneralflagsgroups1
|
||||
hiddenflags
|
||||
([], Just $ argsFlag "[QUERY]")
|
||||
([], Just $ argsFlag "[QUERY..]")
|
||||
|
||||
-- | The accounts command.
|
||||
accounts :: CliOpts -> Journal -> IO ()
|
||||
accounts CliOpts{rawopts_=rawopts, reportspec_=ReportSpec{_rsQuery=query,_rsReportOpts=ropts}} j = do
|
||||
accounts opts@CliOpts{rawopts_=rawopts, reportspec_=ReportSpec{_rsQuery=query,_rsReportOpts=ropts}} j = do
|
||||
|
||||
-- 1. identify the accounts we'll show
|
||||
let tree = tree_ ropts
|
||||
used = boolopt "used" rawopts
|
||||
decl = boolopt "declared" rawopts
|
||||
unused = boolopt "unused" rawopts
|
||||
undecl = boolopt "undeclared" rawopts
|
||||
find_ = boolopt "find" rawopts
|
||||
types = boolopt "types" rawopts
|
||||
positions = boolopt "positions" rawopts
|
||||
directives = boolopt "directives" rawopts
|
||||
@ -71,13 +67,13 @@ accounts CliOpts{rawopts_=rawopts, reportspec_=ReportSpec{_rsQuery=query,_rsRepo
|
||||
-- just the acct: part of the query will be reapplied later, after clipping
|
||||
acctq = dbg4 "acctq" $ filterQuery queryIsAcct query
|
||||
dep = dbg4 "depth" $ queryDepth $ filterQuery queryIsDepth query
|
||||
matcheddeclaredaccts = dbg5 "matcheddeclaredaccts" $
|
||||
matchedused = dbg5 "matchedused" $ nub $ map paccount $ journalPostings $ filterJournalPostings nodepthq j
|
||||
matcheddeclared = dbg5 "matcheddeclared" $
|
||||
nub $
|
||||
filter (matchesAccountExtra (journalAccountType j) (journalInheritedAccountTags j) nodepthq) $
|
||||
map fst $ jdeclaredaccounts j
|
||||
matchedusedaccts = dbg5 "matchedusedaccts" $ nub $ map paccount $ journalPostings $ filterJournalPostings nodepthq j
|
||||
matchedunusedaccts = dbg5 "matchedunusedaccts" $ nub $ matcheddeclaredaccts \\ matchedusedaccts
|
||||
matchedundeclaredaccts = dbg5 "matchedundeclaredaccts" $ nub $ matchedusedaccts \\ matcheddeclaredaccts
|
||||
matchedundeclared = dbg5 "matchedundeclared" $ nub $ matchedused \\ matcheddeclared
|
||||
matchedunused = dbg5 "matchedunused" $ nub $ matcheddeclared \\ matchedused
|
||||
-- keep synced with aregister
|
||||
matchedacct = dbg5 "matchedacct" $
|
||||
fromMaybe (error' $ show apat ++ " did not match any account.") -- PARTIAL:
|
||||
@ -89,14 +85,16 @@ accounts CliOpts{rawopts_=rawopts, reportspec_=ReportSpec{_rsQuery=query,_rsRepo
|
||||
apat = headDef
|
||||
(error' "With --find, please provide an account name or\naccount pattern (case-insensitive, infix, regexp) as first command argument.")
|
||||
$ listofstringopt "args" rawopts
|
||||
|
||||
accts = dbg5 "accts to show" $ if
|
||||
| not decl && used -> matchedusedaccts
|
||||
| decl && not used -> matcheddeclaredaccts
|
||||
| unused -> matchedunusedaccts
|
||||
| undecl -> matchedundeclaredaccts
|
||||
| find_ -> [matchedacct]
|
||||
| otherwise -> matcheddeclaredaccts ++ matchedusedaccts
|
||||
matchedall = matcheddeclared ++ matchedused
|
||||
accts = dbg5 "accts to show" $
|
||||
case (usedOrDeclaredFromOpts opts, boolopt "find" rawopts) of
|
||||
(Nothing, False) -> matchedall
|
||||
(Nothing, True) -> [matchedacct]
|
||||
(Just Used, False) -> matchedused
|
||||
(Just Declared, False) -> matcheddeclared
|
||||
(Just Undeclared, False) -> matchedundeclared
|
||||
(Just Unused, False) -> matchedunused
|
||||
_ -> error' "please pick at most one of --used, --declared, --undeclared, --unused, --find"
|
||||
|
||||
-- 2. sort them by declaration order (then undeclared accounts alphabetically)
|
||||
-- within each group of siblings
|
||||
|
||||
@ -1,39 +1,34 @@
|
||||
## accounts
|
||||
|
||||
List account names.
|
||||
List the account names used or declared in the journal.
|
||||
|
||||
```flags
|
||||
Flags:
|
||||
-u --used show only accounts used by transactions
|
||||
-d --declared show only accounts declared by account directive
|
||||
--unused show only accounts declared but not used
|
||||
--undeclared show only accounts used but not declared
|
||||
-u --used list accounts used
|
||||
-d --declared list accounts declared
|
||||
--undeclared list accounts used but not declared
|
||||
--unused list accounts declared but not used
|
||||
--find list the first account matched by the first
|
||||
argument (a case-insensitive infix regexp)
|
||||
--types also show account types when known
|
||||
--positions also show where accounts were declared
|
||||
--directives show as account directives, for use in journals
|
||||
--find find the first account matched by the first
|
||||
argument (a case-insensitive infix regexp or
|
||||
account name)
|
||||
-l --flat list/tree mode: show accounts as a flat list
|
||||
(default)
|
||||
-t --tree list/tree mode: show accounts as a tree
|
||||
--drop=N flat mode: omit N leading account name parts
|
||||
```
|
||||
|
||||
This command lists account names.
|
||||
By default it shows all known accounts, either used in transactions or declared with account directives.
|
||||
This command lists account names - all of them by default.
|
||||
or just the ones which have been used in transactions,
|
||||
or declared with `account` directives,
|
||||
or used but not declared,
|
||||
or declared but not used,
|
||||
or just the first account name matched by a pattern.
|
||||
|
||||
With query arguments, only matched account names and account names referenced by matched postings are shown.
|
||||
You can add query arguments to select a subset of transactions or accounts.
|
||||
|
||||
Or it can show just
|
||||
the used accounts (`--used`/`-u`),
|
||||
the declared accounts (`--declared`/`-d`),
|
||||
the accounts declared but not used (`--unused`),
|
||||
the accounts used but not declared (`--undeclared`),
|
||||
or the first account matched by an account name pattern, if any (`--find`).
|
||||
|
||||
It shows a flat list by default. With `--tree`, it uses indentation to
|
||||
show the account hierarchy.
|
||||
It shows a flat list by default. With `--tree`, it uses indentation to show the account hierarchy.
|
||||
In flat mode you can add `--drop N` to omit the first few account name components.
|
||||
Account names can be depth-clipped with `depth:N` or `--depth N` or `-N`.
|
||||
|
||||
@ -44,8 +39,7 @@ With `--positions`, it also shows the file and line number of each
|
||||
account's declaration, if any, and the account's overall declaration order;
|
||||
these may be useful when troubleshooting account display order.
|
||||
|
||||
With `--directives`, it adds the `account` keyword, showing
|
||||
valid account directives which can be pasted into a journal file.
|
||||
With `--directives`, it shows valid account directives which could be pasted into a journal file.
|
||||
This is useful together with `--undeclared` when updating your account declarations
|
||||
to satisfy `hledger check accounts`.
|
||||
|
||||
|
||||
@ -12,22 +12,47 @@ module Hledger.Cli.Commands.Commodities (
|
||||
,commodities
|
||||
) where
|
||||
|
||||
import qualified Data.Map as M
|
||||
import qualified Data.Set as S
|
||||
import qualified Data.Text.IO as T
|
||||
import System.Console.CmdArgs.Explicit
|
||||
|
||||
import Hledger
|
||||
import Hledger.Cli.CliOptions
|
||||
import Data.List.Extra (nubSort)
|
||||
import Data.List ((\\))
|
||||
|
||||
|
||||
-- | Command line options for this command.
|
||||
commoditiesmode = hledgerCommandMode
|
||||
$(embedFileRelative "Hledger/Cli/Commands/Commodities.txt")
|
||||
[]
|
||||
[flagNone ["used"] (setboolopt "used") "list commodities used"
|
||||
,flagNone ["declared"] (setboolopt "declared") "list commodities declared"
|
||||
,flagNone ["undeclared"] (setboolopt "undeclared") "list commodities used but not declared"
|
||||
,flagNone ["unused"] (setboolopt "unused") "list commodities declared but not used"
|
||||
]
|
||||
[generalflagsgroup2]
|
||||
[]
|
||||
([], Nothing)
|
||||
([], Just $ argsFlag "[QUERY..]")
|
||||
|
||||
commodities :: CliOpts -> Journal -> IO ()
|
||||
commodities _copts =
|
||||
-- TODO support --declared/--used like accounts, payees
|
||||
mapM_ T.putStrLn . S.filter (/= "AUTO") . journalCommodities
|
||||
commodities opts@CliOpts{reportspec_ = ReportSpec{_rsQuery = query}} j = do
|
||||
let
|
||||
used = dbg5 "used" $
|
||||
S.toList $ journalCommoditiesFromPriceDirectives j <> journalCommoditiesFromTransactions j
|
||||
declared' = dbg5 "declared" $ M.keys $ jdeclaredcommodities j
|
||||
unused = dbg5 "unused" $ declared' \\ used
|
||||
undeclared = dbg5 "undeclared" $ used \\ declared'
|
||||
all' = dbg5 "all" $ nubSort $ concat [
|
||||
journalCommoditiesDeclared j
|
||||
,map pdcommodity $ jpricedirectives j -- gets the first symbol from P directives
|
||||
,map acommodity (S.toList $ journalAmounts j) -- includes the second symbol from P directives
|
||||
]
|
||||
|
||||
mapM_ T.putStrLn $ filter (matchesCommodity query) $
|
||||
case usedOrDeclaredFromOpts opts of
|
||||
Nothing -> all'
|
||||
Just Used -> used
|
||||
Just Declared -> declared'
|
||||
Just Undeclared -> undeclared
|
||||
Just Unused -> unused
|
||||
|
||||
@ -1,9 +1,19 @@
|
||||
## commodities
|
||||
|
||||
List all commodity/currency symbols used or declared in the journal.
|
||||
List the commodity symbols used or declared in the journal.
|
||||
|
||||
```flags
|
||||
Flags:
|
||||
no command-specific flags
|
||||
--used list commodities used
|
||||
--declared list commodities declared
|
||||
--undeclared list commodities used but not declared
|
||||
--unused list commodities declared but not used
|
||||
```
|
||||
|
||||
This command lists commodity symbols/names - all of them by default,
|
||||
or just the ones which have been used in transactions or `P` directives,
|
||||
or declared with `commodity` directives,
|
||||
or used but not declared,
|
||||
or declared but not used.
|
||||
|
||||
You can add cur: query arguments to further limit the commodities.
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
## descriptions
|
||||
|
||||
List the unique descriptions that appear in transactions.
|
||||
List the unique descriptions used in transactions.
|
||||
|
||||
```flags
|
||||
Flags:
|
||||
|
||||
@ -14,35 +14,41 @@ module Hledger.Cli.Commands.Payees (
|
||||
,payees
|
||||
) where
|
||||
|
||||
import qualified Data.Set as S
|
||||
import qualified Data.Text.IO as T
|
||||
import System.Console.CmdArgs.Explicit as C
|
||||
import System.Console.CmdArgs.Explicit
|
||||
|
||||
import Hledger
|
||||
import Hledger.Cli.CliOptions
|
||||
import Data.List ((\\))
|
||||
import Data.List.Extra (nubSort)
|
||||
|
||||
|
||||
-- | Command line options for this command.
|
||||
payeesmode = hledgerCommandMode
|
||||
$(embedFileRelative "Hledger/Cli/Commands/Payees.txt")
|
||||
[flagNone ["declared"] (setboolopt "declared") "show payees declared with payee directives"
|
||||
,flagNone ["used"] (setboolopt "used") "show payees referenced by transactions"
|
||||
[flagNone ["used"] (setboolopt "used") "list payees used"
|
||||
,flagNone ["declared"] (setboolopt "declared") "list payees declared"
|
||||
,flagNone ["undeclared"] (setboolopt "undeclared") "list payees used but not declared"
|
||||
,flagNone ["unused"] (setboolopt "unused") "list payees declared but not used"
|
||||
]
|
||||
cligeneralflagsgroups1
|
||||
hiddenflags
|
||||
([], Just $ argsFlag "[QUERY]")
|
||||
([], Just $ argsFlag "[QUERY..]")
|
||||
|
||||
-- | The payees command.
|
||||
payees :: CliOpts -> Journal -> IO ()
|
||||
payees CliOpts{rawopts_=rawopts, reportspec_=ReportSpec{_rsQuery=query}} j = do
|
||||
payees opts@CliOpts{reportspec_=ReportSpec{_rsQuery=query}} j = do
|
||||
let
|
||||
decl = boolopt "declared" rawopts
|
||||
used = boolopt "used" rawopts
|
||||
-- XXX matchesPayee is currently an alias for matchesDescription, not sure if it matters
|
||||
matcheddeclaredpayees = S.fromList . filter (matchesPayeeWIP query) $ journalPayeesDeclared j
|
||||
matchedusedpayees = S.fromList . map transactionPayee $ filter (matchesTransaction query) $ jtxns j
|
||||
payees' =
|
||||
if | decl && not used -> matcheddeclaredpayees
|
||||
| not decl && used -> matchedusedpayees
|
||||
| otherwise -> matcheddeclaredpayees <> matchedusedpayees
|
||||
mapM_ T.putStrLn payees'
|
||||
-- XXX matchesPayeeWIP is currently an alias for matchesDescription, not sure if it matters
|
||||
matchedused = dbg5 "matchedused" $ nubSort $ map transactionPayee $ filter (matchesTransaction query) $ jtxns j
|
||||
matcheddeclared = dbg5 "matcheddeclared" $ nubSort $ filter (matchesPayeeWIP query) $ journalPayeesDeclared j
|
||||
matchedunused = dbg5 "matchedunused" $ nubSort $ matcheddeclared \\ matchedused
|
||||
matchedundeclared = dbg5 "matchedundeclared" $ nubSort $ matchedused \\ matcheddeclared
|
||||
matchedall = dbg5 "matchedall" $ nubSort $ matcheddeclared ++ matchedused
|
||||
mapM_ T.putStrLn $ case usedOrDeclaredFromOpts opts of
|
||||
Nothing -> matchedall
|
||||
Just Used -> matchedused
|
||||
Just Declared -> matcheddeclared
|
||||
Just Undeclared -> matchedundeclared
|
||||
Just Unused -> matchedunused
|
||||
|
||||
|
||||
@ -1,23 +1,25 @@
|
||||
## payees
|
||||
|
||||
List the unique payee/payer names that appear in transactions.
|
||||
List the payee/payer names used or declared in the journal.
|
||||
|
||||
```flags
|
||||
Flags:
|
||||
--declared show payees declared with payee directives
|
||||
--used show payees referenced by transactions
|
||||
--used list payees used
|
||||
--declared list payees declared
|
||||
--undeclared list payees used but not declared
|
||||
--unused list payees declared but not used
|
||||
```
|
||||
|
||||
This command lists unique payee/payer names which have been
|
||||
declared with payee directives (--declared),
|
||||
used in transaction descriptions (--used),
|
||||
or both (the default).
|
||||
This command lists unique payee/payer names - all of them by default,
|
||||
or just the ones which have been used in transaction descriptions,
|
||||
or declared with `payee` directives,
|
||||
or used but not declared,
|
||||
or declared but not used.
|
||||
|
||||
The payee/payer is the part of the transaction description before a | character
|
||||
The payee/payer name is the part of the transaction description before a | character
|
||||
(or if there is no |, the whole description).
|
||||
|
||||
You can add query arguments to select a subset of transactions. This implies --used.
|
||||
|
||||
You can add query arguments to select a subset of transactions or payees.
|
||||
|
||||
Example:
|
||||
```cli
|
||||
|
||||
@ -60,7 +60,7 @@ printmode = hledgerCommandMode
|
||||
flagReq ["match","m"] (\s opts -> Right $ setopt "match" s opts) arg
|
||||
("fuzzy search for one recent transaction with description closest to "++arg)
|
||||
,flagReq ["base-url"] (\s opts -> Right $ setopt "base-url" s opts) "URLPREFIX" "in html output, generate links to hledger-web, with this prefix. (Usually the base url shown by hledger-web; can also be relative.)"
|
||||
,flagNone ["location"] (setboolopt "location") "add file/line number tags to print output"
|
||||
,flagNone ["location"] (setboolopt "location") "add tags showing file paths and line numbers"
|
||||
,outputFormatFlag ["txt","beancount","csv","tsv","html","fods","json","sql"]
|
||||
,outputFileFlag
|
||||
])
|
||||
@ -113,9 +113,9 @@ print' opts@CliOpts{rawopts_=rawopts} j = do
|
||||
let
|
||||
-- lbl = lbl_ "print'"
|
||||
j' = j
|
||||
-- & dbg9With (lbl "amounts before setting full precision".showJournalAmountsDebug)
|
||||
-- & dbg9With (lbl "amounts before setting full precision".showJournalPostingAmountsDebug)
|
||||
& journalMapPostingAmounts mixedAmountSetFullPrecision
|
||||
-- & dbg9With (lbl "amounts after setting full precision: ".showJournalAmountsDebug)
|
||||
-- & dbg9With (lbl "amounts after setting full precision: ".showJournalPostingAmountsDebug)
|
||||
& if boolopt "location" rawopts then journalMapTransactions addLocationTag else id
|
||||
|
||||
case maybestringopt "match" $ rawopts_ opts of
|
||||
|
||||
@ -1,5 +1,6 @@
|
||||
{-# LANGUAGE OverloadedStrings #-}
|
||||
{-# LANGUAGE TemplateHaskell #-}
|
||||
{-# LANGUAGE TupleSections #-}
|
||||
|
||||
module Hledger.Cli.Commands.Tags (
|
||||
tagsmode
|
||||
@ -12,47 +13,73 @@ import Data.List.Extra (nubSort)
|
||||
import qualified Data.Text as T
|
||||
import qualified Data.Text.IO as T
|
||||
import Safe
|
||||
import System.Console.CmdArgs.Explicit as C
|
||||
import System.Console.CmdArgs.Explicit
|
||||
|
||||
import Hledger
|
||||
import Hledger.Cli.CliOptions
|
||||
|
||||
|
||||
tagsmode = hledgerCommandMode
|
||||
$(embedFileRelative "Hledger/Cli/Commands/Tags.txt")
|
||||
[flagNone ["values"] (setboolopt "values") "list tag values instead of tag names"
|
||||
,flagNone ["parsed"] (setboolopt "parsed") "show tags/values in the order they were parsed, including duplicates"
|
||||
[
|
||||
flagNone ["used"] (setboolopt "used") "list tags used"
|
||||
,flagNone ["declared"] (setboolopt "declared") "list tags declared"
|
||||
,flagNone ["undeclared"] (setboolopt "undeclared") "list tags used but not declared"
|
||||
,flagNone ["unused"] (setboolopt "unused") "list tags declared but not used"
|
||||
,flagNone ["values"] (setboolopt "values") "list tag values instead of tag names"
|
||||
,flagNone ["parsed"] (setboolopt "parsed") "show them in the order they were parsed (mostly), including duplicates"
|
||||
]
|
||||
cligeneralflagsgroups1
|
||||
hiddenflags
|
||||
([], Just $ argsFlag "[TAGREGEX [QUERY...]]")
|
||||
([], Just $ argsFlag "[TAGREGEX [QUERY..]]")
|
||||
|
||||
tags :: CliOpts -> Journal -> IO ()
|
||||
tags CliOpts{rawopts_=rawopts,reportspec_=rspec} j = do
|
||||
tags opts@CliOpts{rawopts_=rawopts, reportspec_=rspec@ReportSpec{_rsQuery=_q, _rsReportOpts=ropts}} j = do
|
||||
let today = _rsDay rspec
|
||||
args = listofstringopt "args" rawopts
|
||||
-- first argument is a tag name pattern, others are a hledger query: hledger tags [TAGREGEX [QUERYARGS..]]
|
||||
-- For convenience/power, the first argument is a tag name regex,
|
||||
-- separate from the main query arguments: hledger tags [TAGREGEX [QUERYARGS..]]
|
||||
-- So we have to re-parse the query here. Overcomplicated ?
|
||||
mtagpat <- mapM (either Fail.fail pure . toRegexCI . T.pack) $ headMay args
|
||||
let
|
||||
querystr = map T.pack $ drop 1 args
|
||||
values = boolopt "values" rawopts
|
||||
parsed = boolopt "parsed" rawopts
|
||||
empty = empty_ $ _rsReportOpts rspec
|
||||
empty = empty_ ropts
|
||||
querystr = map T.pack $ drop 1 args
|
||||
query <- either usageError (return . fst) $ parseQueryList today querystr
|
||||
let
|
||||
q = simplifyQuery $ And [queryFromFlags $ _rsReportOpts rspec, query]
|
||||
matchedtxns = filter (q `matchesTransaction`) $ jtxns $ journalApplyValuationFromOpts rspec j
|
||||
-- also list tags from matched account declarations, but not if there is
|
||||
-- a query for something transaction-related, like date: or amt:.
|
||||
matchedaccts = dbg4 "accts" $
|
||||
if dbg4 "queryIsTransactionRelated" $ queryIsTransactionRelated $ dbg4 "q" q
|
||||
q = simplifyQuery $ And [queryFromFlags ropts, query]
|
||||
txns = filter (q `matchesTransaction`) $ jtxns $ journalApplyValuationFromOpts rspec j
|
||||
accts =
|
||||
-- also search for tags in matched account declarations,
|
||||
-- unless there is a query for something transaction-specific, like date: or amt:.
|
||||
if dbg5 "queryIsTransactionRelated" $ queryIsTransactionRelated $ dbg4 "q" q
|
||||
then []
|
||||
else filter (matchesAccountExtra (journalAccountType j) (journalInheritedAccountTags j) q) $
|
||||
map fst $ jdeclaredaccounts j
|
||||
tagsorvalues =
|
||||
|
||||
used = dbg5 "used" $ concatMap (journalAccountTags j) accts ++ concatMap transactionAllTags txns
|
||||
declared' = dbg5 "declared" $ filter (q `matchesTag`) $ map (,"") $ journalTagsDeclared j
|
||||
(usednames, declarednames) = (map fst used, map fst declared')
|
||||
unused = dbg5 "unused" $ filter (not . (`elem` usednames) . fst) declared'
|
||||
undeclared = dbg5 "undeclared" $ filter (not . (`elem` declarednames) . fst) used
|
||||
all' = dbg5 "all" $ declared' <> used
|
||||
|
||||
tags' =
|
||||
case usedOrDeclaredFromOpts opts of
|
||||
Nothing -> all'
|
||||
Just Used -> used
|
||||
Just Declared -> declared'
|
||||
Just Undeclared -> undeclared
|
||||
Just Unused -> unused
|
||||
|
||||
results =
|
||||
(if parsed then id else nubSort)
|
||||
[ r
|
||||
| (t,v) <- concatMap (journalAccountTags j) matchedaccts ++ concatMap transactionAllTags matchedtxns
|
||||
| (t,v) <- tags'
|
||||
, maybe True (`regexMatchText` t) mtagpat
|
||||
, let r = if values then v else t
|
||||
, not (values && T.null v && not empty)
|
||||
]
|
||||
mapM_ T.putStrLn tagsorvalues
|
||||
|
||||
mapM_ T.putStrLn results
|
||||
|
||||
@ -1,32 +1,39 @@
|
||||
## tags
|
||||
|
||||
List the tags used in the journal, or their values.
|
||||
<!-- same section name as Journal > Tags; if reordering this and that, update all #tags[-1] links -->
|
||||
List the tag names used or declared in the journal, or their values.
|
||||
<!-- This section has the same name as Journal > Tags;
|
||||
if reordering this and that, update all #tags[-1] links -->
|
||||
|
||||
```flags
|
||||
Flags:
|
||||
--used list tags used
|
||||
--declared list tags declared
|
||||
--undeclared list tags used but not declared
|
||||
--unused list tags declared but not used
|
||||
--values list tag values instead of tag names
|
||||
--parsed show tags/values in the order they were parsed,
|
||||
--parsed show them in the order they were parsed (mostly),
|
||||
including duplicates
|
||||
```
|
||||
|
||||
This command lists the tag names used in the journal,
|
||||
whether on transactions, postings, or account declarations.
|
||||
This command lists tag names - all of them by default,
|
||||
or just the ones which have been used on transactions/postings/accounts,
|
||||
or declared with `tag` directives,
|
||||
or used but not declared,
|
||||
or declared but not used.
|
||||
|
||||
With a TAGREGEX argument, only tag names matching this regular expression
|
||||
(case insensitive, infix matched) are shown.
|
||||
You can add one TAGREGEX argument, to show only tags whose name is
|
||||
matched by this case-insensitive, infix-matching regular expression.
|
||||
|
||||
With QUERY arguments, only transactions and accounts matching this query are considered.
|
||||
If the query involves transaction fields (date:, desc:, amt:, ...),
|
||||
the search is restricted to the matched transactions and their accounts.
|
||||
After that, you can add query arguments to filter the
|
||||
transactions, postings, or accounts providing tags.
|
||||
|
||||
With the --values flag, the tags' unique non-empty values are listed instead.
|
||||
With -E/--empty, blank/empty values are also shown.
|
||||
With `--values`, the tags' unique non-empty values are listed instead.
|
||||
|
||||
With --parsed, tags or values are shown in the order they were parsed, with duplicates included.
|
||||
With `-E`/`--empty`, blank/empty values are also shown.
|
||||
|
||||
With `--parsed`, tags or values are shown in the order they were parsed, with duplicates included.
|
||||
(Except, tags from account declarations are always shown first.)
|
||||
|
||||
Tip: remember,
|
||||
accounts also acquire tags from their parents,
|
||||
postings also acquire tags from their account and transaction,
|
||||
transactions also acquire tags from their postings.
|
||||
Remember that accounts also acquire tags from their parents;
|
||||
postings also acquire tags from their account and transaction;
|
||||
and transactions also acquire tags from their postings.
|
||||
|
||||
73
hledger/test/commodities.test
Normal file
73
hledger/test/commodities.test
Normal file
@ -0,0 +1,73 @@
|
||||
# * commodities command
|
||||
# "This command lists commodity symbols/names - all of them by default,
|
||||
# or just the ones which have been used in transactions or `P` directives,
|
||||
# or declared with `commodity` directives,
|
||||
# or used but not declared,
|
||||
# or declared but not used."
|
||||
|
||||
# ** 1. all commodities
|
||||
<
|
||||
commodity 1. CA
|
||||
commodity 1. CB
|
||||
commodity 1. CC
|
||||
commodity 1. CD
|
||||
commodity 1. CE
|
||||
|
||||
D 1. DH
|
||||
|
||||
P 2025-01-01 CA 1 CB
|
||||
P 2025-01-01 PI 1 PJ
|
||||
|
||||
2025-01-01
|
||||
a 1 CC @ 1 CD
|
||||
b 1 TK @ 1 TL
|
||||
d
|
||||
|
||||
$ hledger -f - commodities
|
||||
CA
|
||||
CB
|
||||
CC
|
||||
CD
|
||||
CE
|
||||
DH
|
||||
PI
|
||||
PJ
|
||||
TK
|
||||
TL
|
||||
|
||||
# ** 2. used
|
||||
$ hledger -f - commodities --used
|
||||
CA
|
||||
CB
|
||||
CC
|
||||
CD
|
||||
PI
|
||||
PJ
|
||||
TK
|
||||
TL
|
||||
|
||||
# ** 3. declared
|
||||
$ hledger -f - commodities --declared
|
||||
CA
|
||||
CB
|
||||
CC
|
||||
CD
|
||||
CE
|
||||
|
||||
# ** 4. undeclared
|
||||
$ hledger -f - commodities --undeclared
|
||||
PI
|
||||
PJ
|
||||
TK
|
||||
TL
|
||||
|
||||
# ** 5. unused
|
||||
$ hledger -f - commodities --unused
|
||||
CE
|
||||
|
||||
# ** 6. with a query
|
||||
$ hledger -f - commodities --used expr:"cur:CA or cur:'P.*'"
|
||||
CA
|
||||
PI
|
||||
PJ
|
||||
|
||||
@ -1,5 +1,19 @@
|
||||
# * tags command
|
||||
|
||||
# ** 1. show account tags even when there are no transactions (#1857)
|
||||
<
|
||||
account a ; t1:
|
||||
|
||||
$ hledger -f- tags
|
||||
t1
|
||||
|
||||
# ** 2. show all tags
|
||||
<
|
||||
tag t1
|
||||
tag t3
|
||||
tag t4
|
||||
tag t7
|
||||
|
||||
account a ; t1:v1, an account tag
|
||||
account b:bb ; t2:v2, an unused account, depth 2
|
||||
|
||||
@ -9,7 +23,6 @@ account b:bb ; t2:v2, an unused account, depth 2
|
||||
2000/1/2 ; t5:v4, a reused value
|
||||
(c) 1 ; t6:v6, an undeclared account
|
||||
|
||||
# ** 1. show all tags
|
||||
$ hledger -f- tags
|
||||
t1
|
||||
t2
|
||||
@ -17,8 +30,35 @@ t3
|
||||
t4
|
||||
t5
|
||||
t6
|
||||
t7
|
||||
|
||||
# ** 2. show all tag values
|
||||
# ** . used
|
||||
$ hledger -f- tags --used
|
||||
t1
|
||||
t2
|
||||
t3
|
||||
t4
|
||||
t5
|
||||
t6
|
||||
|
||||
# ** . declared
|
||||
$ hledger -f- tags --declared
|
||||
t1
|
||||
t3
|
||||
t4
|
||||
t7
|
||||
|
||||
# ** . undeclared
|
||||
$ hledger -f- tags --undeclared
|
||||
t2
|
||||
t5
|
||||
t6
|
||||
|
||||
# ** . unused
|
||||
$ hledger -f- tags --unused
|
||||
t7
|
||||
|
||||
# ** . show (non empty) values
|
||||
$ hledger -f- tags --values
|
||||
v1
|
||||
v2
|
||||
@ -26,14 +66,14 @@ v3
|
||||
v4
|
||||
v6
|
||||
|
||||
# ** 3. show tags matching a regex
|
||||
# ** . show tags matching a regex
|
||||
$ hledger -f- tags '[1-4]'
|
||||
t1
|
||||
t2
|
||||
t3
|
||||
t4
|
||||
|
||||
# ** 4. show tags matching (a regex and) a hledger query.
|
||||
# ** . show tags matching (a regex and) a hledger query.
|
||||
# If the query is applicable to both transactions and account declarations,
|
||||
# both are searched for tags.
|
||||
$ hledger -f- tags . b c
|
||||
@ -41,16 +81,10 @@ t2
|
||||
t5
|
||||
t6
|
||||
|
||||
# ** 5. If the query involves transaction attributes,
|
||||
# only accounts used by the matched transactions will contribute tags.
|
||||
# ** . If the query involves transaction attributes,
|
||||
# only the matched transactions and accounts they use will contribute tags.
|
||||
$ hledger -f- tags . date:2000/1/1
|
||||
t1
|
||||
t3
|
||||
t4
|
||||
|
||||
# ** 6. show account tags even when there are no transactions (#1857)
|
||||
<
|
||||
account a ; t1:
|
||||
|
||||
$ hledger -f- tags
|
||||
t1
|
||||
|
||||
Loading…
Reference in New Issue
Block a user