From 9de238757b8c441a70e56b10649b13837e0c928d Mon Sep 17 00:00:00 2001 From: Stephen Morgan Date: Tue, 22 Sep 2020 16:31:09 +1000 Subject: [PATCH] lib,cli,ui: Introduce showMixed*Unnormalised, eliminate most direct calls of strWidth. This introduces some new helper functions which are exactly the same as what we had before, but do not call normaliseMixedAmountSquashPricesForDisplay, so that we can use the new functions for displaying Transaction and Posting. It also goes through and gets rid of most uses of the old showMixed* functions which would benefit from using the new interface. --- hledger-lib/Hledger/Data/Amount.hs | 19 +++++++++++--- hledger-lib/Hledger/Data/Transaction.hs | 6 ++--- hledger-ui/Hledger/UI/RegisterScreen.hs | 20 +++++++-------- hledger-ui/Hledger/UI/UITypes.hs | 4 +-- hledger/Hledger/Cli/Commands/Aregister.hs | 30 ++++++++++------------- tests/close.test | 8 +++--- tests/csv.test | 6 ++--- tests/i18n/wide-char-layout.test | 2 +- tests/print/explicit.test | 2 +- tests/rewrite.test | 8 +++--- 10 files changed, 56 insertions(+), 49 deletions(-) diff --git a/hledger-lib/Hledger/Data/Amount.hs b/hledger-lib/Hledger/Data/Amount.hs index 54e9b5e39..064f553a7 100644 --- a/hledger-lib/Hledger/Data/Amount.hs +++ b/hledger-lib/Hledger/Data/Amount.hs @@ -117,7 +117,9 @@ module Hledger.Data.Amount ( showMixedAmountWithZeroCommodity, showMixedAmountWithPrecision, showMixed, + showMixedUnnormalised, showMixedOneLine, + showMixedOneLineUnnormalised, setMixedAmountPrecision, canonicaliseMixedAmount, -- * misc. @@ -659,12 +661,16 @@ showMixedAmountDebug m | m == missingmixedamt = "(missing)" -- width (if given) will be elided. The function also returns the actual -- width of the output string. showMixed :: (Amount -> String) -> Maybe Int -> Maybe Int -> Bool -> MixedAmount -> (String, Int) -showMixed showamt mmin mmax c mixed = +showMixed showamt mmin mmax c = + showMixedUnnormalised showamt mmin mmax c . normaliseMixedAmountSquashPricesForDisplay + +-- | Like showMixed, but does not normalise the MixedAmount before displaying. +showMixedUnnormalised :: (Amount -> String) -> Maybe Int -> Maybe Int -> Bool -> MixedAmount -> (String, Int) +showMixedUnnormalised showamt mmin mmax c (Mixed as) = (intercalate "\n" $ map finalise elided, width) where width = maximum $ fromMaybe 0 mmin : map adLength elided astrs = amtDisplayList sepwidth showamt as - Mixed as = normaliseMixedAmountSquashPricesForDisplay mixed sepwidth = 0 -- "\n" has width 0 finalise = adString . pad . if c then colourise else id @@ -683,12 +689,17 @@ showMixed showamt mmin mmax c mixed = -- as it can in the maximum width (if given), and further Amounts will be -- elided. The function also returns the actual width of the output string. showMixedOneLine :: (Amount -> String) -> Maybe Int -> Maybe Int -> Bool -> MixedAmount -> (String, Int) -showMixedOneLine showamt mmin mmax c mixed = +showMixedOneLine showamt mmin mmax c = + showMixedOneLineUnnormalised showamt mmin mmax c . normaliseMixedAmountSquashPricesForDisplay + +-- | Like showMixedOneLine, but does not normalise the MixedAmount before +-- displaying. +showMixedOneLineUnnormalised :: (Amount -> String) -> Maybe Int -> Maybe Int -> Bool -> MixedAmount -> (String, Int) +showMixedOneLineUnnormalised showamt mmin mmax c (Mixed as) = (pad . intercalate ", " $ map finalise elided, max width $ fromMaybe 0 mmin) where width = maybe 0 adTotal $ lastMay elided astrs = amtDisplayList sepwidth showamt as - Mixed as = normaliseMixedAmountSquashPricesForDisplay mixed sepwidth = 2 -- ", " has width 2 n = length as diff --git a/hledger-lib/Hledger/Data/Transaction.hs b/hledger-lib/Hledger/Data/Transaction.hs index 326e1540a..1258f9a2a 100644 --- a/hledger-lib/Hledger/Data/Transaction.hs +++ b/hledger-lib/Hledger/Data/Transaction.hs @@ -256,11 +256,11 @@ postingAsLines elideamount onelineamounts pstoalignwith p = concat [ -- currently prices are considered part of the amount string when right-aligning amounts shownAmounts | elideamount = [""] - | onelineamounts = [fitString (Just amtwidth) Nothing False False $ showMixedAmountOneLine $ pamount p] + | onelineamounts = [fst . showMixedOneLineUnnormalised showAmount (Just amtwidth) Nothing False $ pamount p] | null (amounts $ pamount p) = [""] - | otherwise = map (fitStringMulti (Just amtwidth) Nothing False False . showAmount ) . amounts $ pamount p + | otherwise = lines . fst . showMixedUnnormalised showAmount (Just amtwidth) Nothing False $ pamount p where - amtwidth = maximum $ 12 : map (strWidth . showMixedAmount . pamount) pstoalignwith -- min. 12 for backwards compatibility + amtwidth = maximum $ map (snd . showMixed showAmount (Just 12) Nothing False . pamount) pstoalignwith -- min. 12 for backwards compatibility (samelinecomment, newlinecomments) = case renderCommentLines (pcomment p) of [] -> ("",[]) diff --git a/hledger-ui/Hledger/UI/RegisterScreen.hs b/hledger-ui/Hledger/UI/RegisterScreen.hs index 1f8611312..309bd8244 100644 --- a/hledger-ui/Hledger/UI/RegisterScreen.hs +++ b/hledger-ui/Hledger/UI/RegisterScreen.hs @@ -93,8 +93,8 @@ rsInit d reset ui@UIState{aopts=_uopts@UIOpts{cliopts_=CliOpts{reportspec_=rspec [s] -> s ss -> intercalate ", " ss -- _ -> "" -- should do this if accounts field width < 30 - ,rsItemChangeAmount = showMixedAmountElided 22 False change - ,rsItemBalanceAmount = showMixedAmountElided 22 False bal + ,rsItemChangeAmount = showMixed showAmountWithoutPrice Nothing (Just 22) False change + ,rsItemBalanceAmount = showMixed showAmountWithoutPrice Nothing (Just 22) False bal ,rsItemTransaction = t } -- blank items are added to allow more control of scroll position; we won't allow movement over these @@ -103,8 +103,8 @@ rsInit d reset ui@UIState{aopts=_uopts@UIOpts{cliopts_=CliOpts{reportspec_=rspec ,rsItemStatus = Unmarked ,rsItemDescription = "" ,rsItemOtherAccounts = "" - ,rsItemChangeAmount = "" - ,rsItemBalanceAmount = "" + ,rsItemChangeAmount = ("", 0) + ,rsItemBalanceAmount = ("", 0) ,rsItemTransaction = nulltransaction } -- build the List @@ -162,8 +162,8 @@ rsDraw UIState{aopts=_uopts@UIOpts{cliopts_=copts@CliOpts{reportspec_=rspec}} whitespacewidth = 10 -- inter-column whitespace, fixed width minnonamtcolswidth = datewidth + 1 + 2 + 2 -- date column plus at least 1 for status and 2 for desc and accts maxamtswidth = max 0 (totalwidth - minnonamtcolswidth - whitespacewidth) - maxchangewidthseen = maximum' $ map (strWidth . rsItemChangeAmount) displayitems - maxbalwidthseen = maximum' $ map (strWidth . rsItemBalanceAmount) displayitems + maxchangewidthseen = maximum' $ map (snd . rsItemChangeAmount) displayitems + maxbalwidthseen = maximum' $ map (snd . rsItemBalanceAmount) displayitems changewidthproportion = fromIntegral maxchangewidthseen / fromIntegral (maxchangewidthseen + maxbalwidthseen) maxchangewidth = round $ changewidthproportion * fromIntegral maxamtswidth maxbalwidth = maxamtswidth - maxchangewidth @@ -261,13 +261,13 @@ rsDrawItem (datewidth,descwidth,acctswidth,changewidth,balwidth) selected Regist str " " <+> str (fitString (Just acctswidth) (Just acctswidth) True True rsItemOtherAccounts) <+> str " " <+> - withAttr changeattr (str (fitString (Just changewidth) (Just changewidth) True False rsItemChangeAmount)) <+> + withAttr changeattr (str (fitString (Just changewidth) (Just changewidth) True False $ fst rsItemChangeAmount)) <+> str " " <+> - withAttr balattr (str (fitString (Just balwidth) (Just balwidth) True False rsItemBalanceAmount)) + withAttr balattr (str (fitString (Just balwidth) (Just balwidth) True False $ fst rsItemBalanceAmount)) where - changeattr | '-' `elem` rsItemChangeAmount = sel $ "list" <> "amount" <> "decrease" + changeattr | '-' `elem` fst rsItemChangeAmount = sel $ "list" <> "amount" <> "decrease" | otherwise = sel $ "list" <> "amount" <> "increase" - balattr | '-' `elem` rsItemBalanceAmount = sel $ "list" <> "balance" <> "negative" + balattr | '-' `elem` fst rsItemBalanceAmount = sel $ "list" <> "balance" <> "negative" | otherwise = sel $ "list" <> "balance" <> "positive" sel | selected = (<> "selected") | otherwise = id diff --git a/hledger-ui/Hledger/UI/UITypes.hs b/hledger-ui/Hledger/UI/UITypes.hs index a5d2c96ae..785df3f5f 100644 --- a/hledger-ui/Hledger/UI/UITypes.hs +++ b/hledger-ui/Hledger/UI/UITypes.hs @@ -146,8 +146,8 @@ data RegisterScreenItem = RegisterScreenItem { ,rsItemStatus :: Status -- ^ transaction status ,rsItemDescription :: String -- ^ description ,rsItemOtherAccounts :: String -- ^ other accounts - ,rsItemChangeAmount :: String -- ^ the change to the current account from this transaction - ,rsItemBalanceAmount :: String -- ^ the balance or running total after this transaction + ,rsItemChangeAmount :: (String, Int) -- ^ the change to the current account from this transaction + ,rsItemBalanceAmount :: (String, Int) -- ^ the balance or running total after this transaction ,rsItemTransaction :: Transaction -- ^ the full transaction } deriving (Show) diff --git a/hledger/Hledger/Cli/Commands/Aregister.hs b/hledger/Hledger/Cli/Commands/Aregister.hs index ad0506ed1..58b6bc85c 100644 --- a/hledger/Hledger/Cli/Commands/Aregister.hs +++ b/hledger/Hledger/Cli/Commands/Aregister.hs @@ -147,11 +147,10 @@ accountTransactionsReportAsText = unlines $ title : map (accountTransactionsReportItemAsText copts reportq thisacctq amtwidth balwidth) items where - amtwidth = maximumStrict $ 12 : map (strWidth . showamt . itemamt) items - balwidth = maximumStrict $ 12 : map (strWidth . showamt . itembal) items - showamt - | no_elide_ = showMixedAmountOneLineWithoutPrice False -- color_ - | otherwise = showMixedAmountElided 22 False + amtwidth = maximumStrict $ 12 : map (snd . showamt . itemamt) items + balwidth = maximumStrict $ 12 : map (snd . showamt . itembal) items + showamt = showMixedOneLine showAmountWithoutPrice (Just 12) mmax False -- color_ + where mmax = if no_elide_ then Nothing else Just 22 itemamt (_,_,_,_,a,_) = a itembal (_,_,_,_,_,a) = a -- show a title indicating which account was picked, which can be confusing otherwise @@ -176,7 +175,7 @@ accountTransactionsReportAsText -- accountTransactionsReportItemAsText :: CliOpts -> Query -> Query -> Int -> Int -> AccountTransactionsReportItem -> String accountTransactionsReportItemAsText - copts@CliOpts{reportspec_=ReportSpec{rsOpts=ReportOpts{color_,no_elide_}}} + copts@CliOpts{reportspec_=ReportSpec{rsOpts=ReportOpts{color_}}} reportq thisacctq preferredamtwidth preferredbalwidth (t@Transaction{tdescription}, _, _issplit, otheracctsstr, change, balance) -- Transaction -- the transaction, unmodified @@ -193,15 +192,15 @@ accountTransactionsReportItemAsText ," " ,fitString (Just acctwidth) (Just acctwidth) True True accts ," " - ,fitString (Just amtwidth) (Just amtwidth) True False amtfirstline + ,amtfirstline ," " - ,fitString (Just balwidth) (Just balwidth) True False balfirstline + ,balfirstline ] : [concat [spacer - ,fitString (Just amtwidth) (Just amtwidth) True False a + ,a ," " - ,fitString (Just balwidth) (Just balwidth) True False b + ,b ] | (a,b) <- zip amtrest balrest ] @@ -229,19 +228,16 @@ accountTransactionsReportItemAsText desc = T.unpack tdescription accts = -- T.unpack $ elideAccountName acctwidth $ T.pack otheracctsstr - showamt - | no_elide_ = showMixedAmountOneLineWithoutPrice color_ - | otherwise = showMixedAmountElided 22 color_ - amt = showamt change - bal = showamt balance + amt = fst $ showMixed showAmountWithoutPrice (Just amtwidth) (Just balwidth) color_ change + bal = fst $ showMixed showAmountWithoutPrice (Just balwidth) (Just balwidth) color_ balance -- alternate behaviour, show null amounts as 0 instead of blank -- amt = if null amt' then "0" else amt' -- bal = if null bal' then "0" else bal' (amtlines, ballines) = (lines amt, lines bal) (amtlen, ballen) = (length amtlines, length ballines) numlines = max 1 (max amtlen ballen) - (amtfirstline:amtrest) = take numlines $ amtlines ++ repeat "" -- posting amount is top-aligned - (balfirstline:balrest) = take numlines $ replicate (numlines - ballen) "" ++ ballines -- balance amount is bottom-aligned + (amtfirstline:amtrest) = take numlines $ amtlines ++ repeat (replicate amtwidth ' ') -- posting amount is top-aligned + (balfirstline:balrest) = take numlines $ replicate (numlines - ballen) (replicate balwidth ' ') ++ ballines -- balance amount is bottom-aligned spacer = replicate (totalwidth - (amtwidth + 2 + balwidth)) ' ' -- tests diff --git a/tests/close.test b/tests/close.test index 0f6b3c0a0..b2d1c17d9 100644 --- a/tests/close.test +++ b/tests/close.test @@ -207,10 +207,10 @@ $ hledger -f- close -p 2016 assets liabilities --show-costs -x liabilities:employer $5,000.00 @ 0.93 EUR liabilities:employer $5,000.00 @ 0.95 EUR = $0.00 liabilities:employer -1.00 EUR = 0.00 EUR - equity:opening/closing balances $10,000.00 + equity:opening/closing balances $10,000.00 equity:opening/closing balances $-5,000.00 @ 0.93 EUR equity:opening/closing balances $-5,000.00 @ 0.95 EUR - equity:opening/closing balances 5,734.00 EUR + equity:opening/closing balances 5,734.00 EUR 2017-01-01 opening balances assets:bank 5,733.00 EUR = 5,733.00 EUR @@ -274,9 +274,9 @@ $ hledger -f- close -p 2019 assets --show-costs -x assets:aaa AAA -510.00000000 = AAA 0.00000000 assets:usd $-49.50 assets:usd $49.390001 @ AAA 10.3528242505 = $0.00 - equity:opening/closing balances $49.50 + equity:opening/closing balances $49.50 equity:opening/closing balances $-49.390001 @ AAA 10.3528242505 - equity:opening/closing balances AAA 510.00000000 + equity:opening/closing balances AAA 510.00000000 2020-01-01 opening balances assets:aaa AAA 510.00000000 = AAA 510.00000000 diff --git a/tests/csv.test b/tests/csv.test index 22a28f57c..272b24a3b 100644 --- a/tests/csv.test +++ b/tests/csv.test @@ -408,15 +408,15 @@ account1 assets account2 income $ ./csvtest.sh 2018-10-15 Assets Update - assets = EUR 100 + assets = EUR 100 income 2018-10-16 Assets Update - assets = EUR 200 + assets = EUR 200 income 2018-10-17 Assets Update - assets = EUR 300 + assets = EUR 300 income >=0 diff --git a/tests/i18n/wide-char-layout.test b/tests/i18n/wide-char-layout.test index d52e688fc..ff3898a6f 100644 --- a/tests/i18n/wide-char-layout.test +++ b/tests/i18n/wide-char-layout.test @@ -21,7 +21,7 @@ hledger -f - print >>> 2000-01-01 transaction 1 㐀 㐃㐃1 @ 2 㐂㐂㐂㐂㐂㐂㐂㐂㐂㐂㐂 - 㐀:㐁 ; 㐃㐃-1 + 㐀:㐁 ; 㐃㐃-1 2000-01-02 transaction 2 㐀:㐁:㐂 USD 1 diff --git a/tests/print/explicit.test b/tests/print/explicit.test index 60cacb0da..1c1fdd82e 100644 --- a/tests/print/explicit.test +++ b/tests/print/explicit.test @@ -64,7 +64,7 @@ hledger -f - print equity >>> 2017-01-01 - assets = $100 + assets = $100 equity >>>2 diff --git a/tests/rewrite.test b/tests/rewrite.test index e858cb619..66a913eea 100644 --- a/tests/rewrite.test +++ b/tests/rewrite.test @@ -42,7 +42,7 @@ hledger rewrite -f- expenses:gifts --add-posting '(budget:gifts) *-1' 2016-01-01 gift ; modified: assets:cash $-15 - expenses:gifts ; [1/2] + expenses:gifts ; [1/2] (budget:gifts) $-15 ; [2016-01-02], generated-posting: = expenses:gifts >>>2 @@ -107,17 +107,17 @@ hledger rewrite -f- -B 2017-04-24 * 09:00-09:25 ; modified: (assets:unbilled:client1) 0.42h assets:to bill:client1 $42.00 ; generated-posting: = ^assets:unbilled:client1 - income:consulting:client1 ; generated-posting: = ^assets:unbilled:client1 + income:consulting:client1 ; generated-posting: = ^assets:unbilled:client1 2017-04-25 * 10:00-11:15 ; modified: (assets:unbilled:client1) 1.25h assets:to bill:client1 $125.00 ; generated-posting: = ^assets:unbilled:client1 - income:consulting:client1 ; generated-posting: = ^assets:unbilled:client1 + income:consulting:client1 ; generated-posting: = ^assets:unbilled:client1 2017-04-25 * 14:00-15:32 ; modified: (assets:unbilled:client2) 1.54h assets:to bill:client2 $231.00 ; generated-posting: = ^assets:unbilled:client2 - income:consulting:client2 ; generated-posting: = ^assets:unbilled:client2 + income:consulting:client2 ; generated-posting: = ^assets:unbilled:client2 >>>2 >>>=0