dev: Use realLength from doclayout instead of strWidth and textWidth. (#895)
This gives us more accurate string length calculations. In particular, it handles emoji and other scripts properly.
This commit is contained in:
parent
d1ae0c10d6
commit
ff0132df28
@ -46,6 +46,7 @@ import qualified Data.Set as S
|
|||||||
import Data.Text (Text)
|
import Data.Text (Text)
|
||||||
import qualified Data.Text as T
|
import qualified Data.Text as T
|
||||||
import Data.Tree (Tree(..))
|
import Data.Tree (Tree(..))
|
||||||
|
import Text.DocLayout (realLength)
|
||||||
|
|
||||||
import Hledger.Data.Types
|
import Hledger.Data.Types
|
||||||
import Hledger.Utils
|
import Hledger.Utils
|
||||||
@ -186,7 +187,7 @@ elideAccountName width s
|
|||||||
where
|
where
|
||||||
elideparts :: Int -> [Text] -> [Text] -> [Text]
|
elideparts :: Int -> [Text] -> [Text] -> [Text]
|
||||||
elideparts width done ss
|
elideparts width done ss
|
||||||
| textWidth (accountNameFromComponents $ done++ss) <= width = done++ss
|
| realLength (accountNameFromComponents $ done++ss) <= width = done++ss
|
||||||
| length ss > 1 = elideparts width (done++[textTakeWidth 2 $ head ss]) (tail ss)
|
| length ss > 1 = elideparts width (done++[textTakeWidth 2 $ head ss]) (tail ss)
|
||||||
| otherwise = done++ss
|
| otherwise = done++ss
|
||||||
|
|
||||||
|
|||||||
@ -171,7 +171,7 @@ import Test.Tasty.HUnit ((@?=), assertBool, testCase)
|
|||||||
import Hledger.Data.Types
|
import Hledger.Data.Types
|
||||||
import Hledger.Utils (colorB)
|
import Hledger.Utils (colorB)
|
||||||
import Hledger.Utils.Text (textQuoteIfNeeded)
|
import Hledger.Utils.Text (textQuoteIfNeeded)
|
||||||
import Text.WideString (WideBuilder(..), textWidth, wbToText, wbUnpack)
|
import Text.WideString (WideBuilder(..), wbFromText, wbToText, wbUnpack)
|
||||||
|
|
||||||
|
|
||||||
-- A 'Commodity' is a symbol representing a currency or some other kind of
|
-- A 'Commodity' is a symbol representing a currency or some other kind of
|
||||||
@ -469,14 +469,13 @@ showAmountB :: AmountDisplayOpts -> Amount -> WideBuilder
|
|||||||
showAmountB _ Amount{acommodity="AUTO"} = mempty
|
showAmountB _ Amount{acommodity="AUTO"} = mempty
|
||||||
showAmountB opts a@Amount{astyle=style} =
|
showAmountB opts a@Amount{astyle=style} =
|
||||||
color $ case ascommodityside style of
|
color $ case ascommodityside style of
|
||||||
L -> showC c' space <> quantity' <> price
|
L -> showC (wbFromText c) space <> quantity' <> price
|
||||||
R -> quantity' <> showC space c' <> price
|
R -> quantity' <> showC space (wbFromText c) <> price
|
||||||
where
|
where
|
||||||
quantity = showamountquantity a
|
quantity = showamountquantity a
|
||||||
(quantity',c) | amountLooksZero a && not (displayZeroCommodity opts) = (WideBuilder (TB.singleton '0') 1,"")
|
(quantity',c) | amountLooksZero a && not (displayZeroCommodity opts) = (WideBuilder (TB.singleton '0') 1,"")
|
||||||
| otherwise = (quantity, quoteCommoditySymbolIfNeeded $ acommodity a)
|
| otherwise = (quantity, quoteCommoditySymbolIfNeeded $ acommodity a)
|
||||||
space = if not (T.null c) && ascommodityspaced style then WideBuilder (TB.singleton ' ') 1 else mempty
|
space = if not (T.null c) && ascommodityspaced style then WideBuilder (TB.singleton ' ') 1 else mempty
|
||||||
c' = WideBuilder (TB.fromText c) (textWidth c)
|
|
||||||
showC l r = if isJust (displayOrder opts) then mempty else l <> r
|
showC l r = if isJust (displayOrder opts) then mempty else l <> r
|
||||||
price = if displayPrice opts then showAmountPrice a else mempty
|
price = if displayPrice opts then showAmountPrice a else mempty
|
||||||
color = if displayColour opts && isNegativeAmount a then colorB Dull Red else id
|
color = if displayColour opts && isNegativeAmount a then colorB Dull Red else id
|
||||||
|
|||||||
@ -89,6 +89,7 @@ import qualified Data.Text.Lazy as TL
|
|||||||
import qualified Data.Text.Lazy.Builder as TB
|
import qualified Data.Text.Lazy.Builder as TB
|
||||||
import Data.Time.Calendar (Day)
|
import Data.Time.Calendar (Day)
|
||||||
import Safe (headDef, maximumDef)
|
import Safe (headDef, maximumDef)
|
||||||
|
import Text.DocLayout (realLength)
|
||||||
|
|
||||||
import Text.Tabular.AsciiWide
|
import Text.Tabular.AsciiWide
|
||||||
|
|
||||||
@ -255,7 +256,7 @@ postingAsLines elideamount onelineamounts acctwidth amtwidth p =
|
|||||||
assertion = maybe mempty ((WideBuilder (TB.singleton ' ') 1 <>).showBalanceAssertion) $ pbalanceassertion p
|
assertion = maybe mempty ((WideBuilder (TB.singleton ' ') 1 <>).showBalanceAssertion) $ pbalanceassertion p
|
||||||
-- pad to the maximum account name width, plus 2 to leave room for status flags, to keep amounts aligned
|
-- pad to the maximum account name width, plus 2 to leave room for status flags, to keep amounts aligned
|
||||||
statusandaccount = lineIndent . fitText (Just $ 2 + acctwidth) Nothing False True $ pstatusandacct p
|
statusandaccount = lineIndent . fitText (Just $ 2 + acctwidth) Nothing False True $ pstatusandacct p
|
||||||
thisacctwidth = textWidth $ pacctstr p
|
thisacctwidth = realLength $ pacctstr p
|
||||||
|
|
||||||
pacctstr p' = showAccountName Nothing (ptype p') (paccount p')
|
pacctstr p' = showAccountName Nothing (ptype p') (paccount p')
|
||||||
pstatusandacct p' = pstatusprefix p' <> pacctstr p'
|
pstatusandacct p' = pstatusprefix p' <> pacctstr p'
|
||||||
|
|||||||
@ -42,7 +42,7 @@ import Text.Printf (printf)
|
|||||||
|
|
||||||
import Hledger.Utils.Parse
|
import Hledger.Utils.Parse
|
||||||
import Hledger.Utils.Regex (toRegex', regexReplace)
|
import Hledger.Utils.Regex (toRegex', regexReplace)
|
||||||
import Text.WideString (charWidth, strWidth)
|
import Text.DocLayout (charWidth, realLength)
|
||||||
|
|
||||||
|
|
||||||
-- | Take elements from the end of a list.
|
-- | Take elements from the end of a list.
|
||||||
@ -174,6 +174,10 @@ takeWidth w (c:cs) | cw <= w = c:takeWidth (w-cw) cs
|
|||||||
strWidthAnsi :: String -> Int
|
strWidthAnsi :: String -> Int
|
||||||
strWidthAnsi = strWidth . stripAnsi
|
strWidthAnsi = strWidth . stripAnsi
|
||||||
|
|
||||||
|
-- | Alias for 'realLength'.
|
||||||
|
strWidth :: String -> Int
|
||||||
|
strWidth = realLength
|
||||||
|
|
||||||
-- | Strip ANSI escape sequences from a string.
|
-- | Strip ANSI escape sequences from a string.
|
||||||
--
|
--
|
||||||
-- >>> stripAnsi "\ESC[31m-1\ESC[m"
|
-- >>> stripAnsi "\ESC[31m-1\ESC[m"
|
||||||
|
|||||||
@ -43,7 +43,6 @@ module Hledger.Utils.Text
|
|||||||
wbToText,
|
wbToText,
|
||||||
wbFromText,
|
wbFromText,
|
||||||
wbUnpack,
|
wbUnpack,
|
||||||
textWidth,
|
|
||||||
textTakeWidth,
|
textTakeWidth,
|
||||||
-- * Reading
|
-- * Reading
|
||||||
readDecimal,
|
readDecimal,
|
||||||
@ -58,12 +57,13 @@ import Data.Text (Text)
|
|||||||
import qualified Data.Text as T
|
import qualified Data.Text as T
|
||||||
import qualified Data.Text.Lazy as TL
|
import qualified Data.Text.Lazy as TL
|
||||||
import qualified Data.Text.Lazy.Builder as TB
|
import qualified Data.Text.Lazy.Builder as TB
|
||||||
|
import Text.DocLayout (charWidth, realLength)
|
||||||
|
|
||||||
import Test.Tasty (testGroup)
|
import Test.Tasty (testGroup)
|
||||||
import Test.Tasty.HUnit ((@?=), testCase)
|
import Test.Tasty.HUnit ((@?=), testCase)
|
||||||
import Text.Tabular.AsciiWide
|
import Text.Tabular.AsciiWide
|
||||||
(Align(..), Header(..), Properties(..), TableOpts(..), renderRow, textCell)
|
(Align(..), Header(..), Properties(..), TableOpts(..), renderRow, textCell)
|
||||||
import Text.WideString (WideBuilder(..), wbToText, wbFromText, wbUnpack, charWidth, textWidth)
|
import Text.WideString (WideBuilder(..), wbToText, wbFromText, wbUnpack)
|
||||||
|
|
||||||
|
|
||||||
-- lowercase, uppercase :: String -> String
|
-- lowercase, uppercase :: String -> String
|
||||||
@ -206,7 +206,7 @@ fitText mminwidth mmaxwidth ellipsify rightside = clip . pad
|
|||||||
clip s =
|
clip s =
|
||||||
case mmaxwidth of
|
case mmaxwidth of
|
||||||
Just w
|
Just w
|
||||||
| textWidth s > w ->
|
| realLength s > w ->
|
||||||
if rightside
|
if rightside
|
||||||
then textTakeWidth (w - T.length ellipsis) s <> ellipsis
|
then textTakeWidth (w - T.length ellipsis) s <> ellipsis
|
||||||
else ellipsis <> T.reverse (textTakeWidth (w - T.length ellipsis) $ T.reverse s)
|
else ellipsis <> T.reverse (textTakeWidth (w - T.length ellipsis) $ T.reverse s)
|
||||||
@ -224,7 +224,7 @@ fitText mminwidth mmaxwidth ellipsify rightside = clip . pad
|
|||||||
else T.replicate (w - sw) " " <> s
|
else T.replicate (w - sw) " " <> s
|
||||||
| otherwise -> s
|
| otherwise -> s
|
||||||
Nothing -> s
|
Nothing -> s
|
||||||
where sw = textWidth s
|
where sw = realLength s
|
||||||
|
|
||||||
-- | Double-width-character-aware string truncation. Take as many
|
-- | Double-width-character-aware string truncation. Take as many
|
||||||
-- characters as possible from a string without exceeding the
|
-- characters as possible from a string without exceeding the
|
||||||
|
|||||||
@ -35,7 +35,7 @@ import qualified Data.Text.Lazy as TL
|
|||||||
import Data.Text.Lazy.Builder (Builder, fromString, fromText, singleton, toLazyText)
|
import Data.Text.Lazy.Builder (Builder, fromString, fromText, singleton, toLazyText)
|
||||||
import Safe (maximumMay)
|
import Safe (maximumMay)
|
||||||
import Text.Tabular
|
import Text.Tabular
|
||||||
import Text.WideString (WideBuilder(..), wbFromText, textWidth)
|
import Text.WideString (WideBuilder(..), wbFromText)
|
||||||
|
|
||||||
|
|
||||||
-- | The options to use for rendering a table.
|
-- | The options to use for rendering a table.
|
||||||
@ -63,7 +63,7 @@ emptyCell = Cell TopRight []
|
|||||||
|
|
||||||
-- | Create a single-line cell from the given contents with its natural width.
|
-- | Create a single-line cell from the given contents with its natural width.
|
||||||
textCell :: Align -> Text -> Cell
|
textCell :: Align -> Text -> Cell
|
||||||
textCell a x = Cell a . map (\x -> WideBuilder (fromText x) (textWidth x)) $ if T.null x then [""] else T.lines x
|
textCell a x = Cell a . map wbFromText $ if T.null x then [""] else T.lines x
|
||||||
|
|
||||||
-- | Create a multi-line cell from the given contents with its natural width.
|
-- | Create a multi-line cell from the given contents with its natural width.
|
||||||
textsCell :: Align -> [Text] -> Cell
|
textsCell :: Align -> [Text] -> Cell
|
||||||
|
|||||||
@ -1,10 +1,6 @@
|
|||||||
-- | Calculate the width of String and Text, being aware of wide characters.
|
-- | Calculate the width of String and Text, being aware of wide characters.
|
||||||
|
|
||||||
module Text.WideString (
|
module Text.WideString (
|
||||||
-- * wide-character-aware layout
|
|
||||||
strWidth,
|
|
||||||
textWidth,
|
|
||||||
charWidth,
|
|
||||||
-- * Text Builders which keep track of length
|
-- * Text Builders which keep track of length
|
||||||
WideBuilder(..),
|
WideBuilder(..),
|
||||||
wbUnpack,
|
wbUnpack,
|
||||||
@ -16,6 +12,7 @@ import Data.Text (Text)
|
|||||||
import qualified Data.Text as T
|
import qualified Data.Text as T
|
||||||
import qualified Data.Text.Lazy as TL
|
import qualified Data.Text.Lazy as TL
|
||||||
import qualified Data.Text.Lazy.Builder as TB
|
import qualified Data.Text.Lazy.Builder as TB
|
||||||
|
import Text.DocLayout (realLength)
|
||||||
|
|
||||||
|
|
||||||
-- | Helper for constructing Builders while keeping track of text width.
|
-- | Helper for constructing Builders while keeping track of text width.
|
||||||
@ -36,68 +33,8 @@ wbToText = TL.toStrict . TB.toLazyText . wbBuilder
|
|||||||
|
|
||||||
-- | Convert a strict Text to a WideBuilder.
|
-- | Convert a strict Text to a WideBuilder.
|
||||||
wbFromText :: Text -> WideBuilder
|
wbFromText :: Text -> WideBuilder
|
||||||
wbFromText t = WideBuilder (TB.fromText t) (textWidth t)
|
wbFromText t = WideBuilder (TB.fromText t) (realLength t)
|
||||||
|
|
||||||
-- | Convert a WideBuilder to a String.
|
-- | Convert a WideBuilder to a String.
|
||||||
wbUnpack :: WideBuilder -> String
|
wbUnpack :: WideBuilder -> String
|
||||||
wbUnpack = TL.unpack . TB.toLazyText . wbBuilder
|
wbUnpack = TL.unpack . TB.toLazyText . wbBuilder
|
||||||
|
|
||||||
|
|
||||||
-- | Calculate the render width of a string, considering
|
|
||||||
-- wide characters (counted as double width)
|
|
||||||
strWidth :: String -> Int
|
|
||||||
strWidth = foldr (\a b -> charWidth a + b) 0
|
|
||||||
|
|
||||||
-- | Calculate the render width of a string, considering
|
|
||||||
-- wide characters (counted as double width)
|
|
||||||
textWidth :: Text -> Int
|
|
||||||
textWidth = T.foldr (\a b -> charWidth a + b) 0
|
|
||||||
|
|
||||||
-- from Pandoc (copyright John MacFarlane, GPL)
|
|
||||||
-- see also http://unicode.org/reports/tr11/#Description
|
|
||||||
|
|
||||||
-- | Get the designated render width of a character: 0 for a combining
|
|
||||||
-- character, 1 for a regular character, 2 for a wide character.
|
|
||||||
-- (Wide characters are rendered as exactly double width in apps and
|
|
||||||
-- fonts that support it.) (From Pandoc.)
|
|
||||||
charWidth :: Char -> Int
|
|
||||||
charWidth c
|
|
||||||
| c < '\x0300' = 1
|
|
||||||
| c >= '\x0300' && c <= '\x036F' = 0 -- combining
|
|
||||||
| c >= '\x0370' && c <= '\x10FC' = 1
|
|
||||||
| c >= '\x1100' && c <= '\x115F' = 2
|
|
||||||
| c >= '\x1160' && c <= '\x11A2' = 1
|
|
||||||
| c >= '\x11A3' && c <= '\x11A7' = 2
|
|
||||||
| c >= '\x11A8' && c <= '\x11F9' = 1
|
|
||||||
| c >= '\x11FA' && c <= '\x11FF' = 2
|
|
||||||
| c >= '\x1200' && c <= '\x2328' = 1
|
|
||||||
| c >= '\x2329' && c <= '\x232A' = 2
|
|
||||||
| c >= '\x232B' && c <= '\x2E31' = 1
|
|
||||||
| c >= '\x2E80' && c <= '\x303E' = 2
|
|
||||||
| c == '\x303F' = 1
|
|
||||||
| c >= '\x3041' && c <= '\x3247' = 2
|
|
||||||
| c >= '\x3248' && c <= '\x324F' = 1 -- ambiguous
|
|
||||||
| c >= '\x3250' && c <= '\x4DBF' = 2
|
|
||||||
| c >= '\x4DC0' && c <= '\x4DFF' = 1
|
|
||||||
| c >= '\x4E00' && c <= '\xA4C6' = 2
|
|
||||||
| c >= '\xA4D0' && c <= '\xA95F' = 1
|
|
||||||
| c >= '\xA960' && c <= '\xA97C' = 2
|
|
||||||
| c >= '\xA980' && c <= '\xABF9' = 1
|
|
||||||
| c >= '\xAC00' && c <= '\xD7FB' = 2
|
|
||||||
| c >= '\xD800' && c <= '\xDFFF' = 1
|
|
||||||
| c >= '\xE000' && c <= '\xF8FF' = 1 -- ambiguous
|
|
||||||
| c >= '\xF900' && c <= '\xFAFF' = 2
|
|
||||||
| c >= '\xFB00' && c <= '\xFDFD' = 1
|
|
||||||
| c >= '\xFE00' && c <= '\xFE0F' = 1 -- ambiguous
|
|
||||||
| c >= '\xFE10' && c <= '\xFE19' = 2
|
|
||||||
| c >= '\xFE20' && c <= '\xFE26' = 1
|
|
||||||
| c >= '\xFE30' && c <= '\xFE6B' = 2
|
|
||||||
| c >= '\xFE70' && c <= '\xFEFF' = 1
|
|
||||||
| c >= '\xFF01' && c <= '\xFF60' = 2
|
|
||||||
| c >= '\xFF61' && c <= '\x16A38' = 1
|
|
||||||
| c >= '\x1B000' && c <= '\x1B001' = 2
|
|
||||||
| c >= '\x1D000' && c <= '\x1F1FF' = 1
|
|
||||||
| c >= '\x1F200' && c <= '\x1F251' = 2
|
|
||||||
| c >= '\x1F300' && c <= '\x1F773' = 1
|
|
||||||
| c >= '\x20000' && c <= '\x3FFFD' = 2
|
|
||||||
| otherwise = 1
|
|
||||||
|
|||||||
@ -109,6 +109,7 @@ library
|
|||||||
, containers >=0.5.9
|
, containers >=0.5.9
|
||||||
, data-default >=0.5
|
, data-default >=0.5
|
||||||
, directory
|
, directory
|
||||||
|
, doclayout ==0.3.*
|
||||||
, extra >=1.6.3
|
, extra >=1.6.3
|
||||||
, file-embed >=0.0.10
|
, file-embed >=0.0.10
|
||||||
, filepath
|
, filepath
|
||||||
@ -158,6 +159,7 @@ test-suite doctest
|
|||||||
, containers >=0.5.9
|
, containers >=0.5.9
|
||||||
, data-default >=0.5
|
, data-default >=0.5
|
||||||
, directory
|
, directory
|
||||||
|
, doclayout ==0.3.*
|
||||||
, doctest >=0.18.1
|
, doctest >=0.18.1
|
||||||
, extra >=1.6.3
|
, extra >=1.6.3
|
||||||
, file-embed >=0.0.10
|
, file-embed >=0.0.10
|
||||||
@ -210,6 +212,7 @@ test-suite unittest
|
|||||||
, containers >=0.5.9
|
, containers >=0.5.9
|
||||||
, data-default >=0.5
|
, data-default >=0.5
|
||||||
, directory
|
, directory
|
||||||
|
, doclayout ==0.3.*
|
||||||
, extra >=1.6.3
|
, extra >=1.6.3
|
||||||
, file-embed >=0.0.10
|
, file-embed >=0.0.10
|
||||||
, filepath
|
, filepath
|
||||||
|
|||||||
@ -47,6 +47,7 @@ dependencies:
|
|||||||
- data-default >=0.5
|
- data-default >=0.5
|
||||||
- Decimal >=0.5.1
|
- Decimal >=0.5.1
|
||||||
- directory
|
- directory
|
||||||
|
- doclayout >=0.3 && <0.4
|
||||||
- file-embed >=0.0.10
|
- file-embed >=0.0.10
|
||||||
- filepath
|
- filepath
|
||||||
- hashtables >=1.2.3.1
|
- hashtables >=1.2.3.1
|
||||||
|
|||||||
@ -26,6 +26,7 @@ import Lens.Micro.Platform
|
|||||||
import Safe
|
import Safe
|
||||||
import System.Console.ANSI
|
import System.Console.ANSI
|
||||||
import System.FilePath (takeFileName)
|
import System.FilePath (takeFileName)
|
||||||
|
import Text.DocLayout (realLength)
|
||||||
|
|
||||||
import Hledger
|
import Hledger
|
||||||
import Hledger.Cli hiding (progname,prognameandversion)
|
import Hledger.Cli hiding (progname,prognameandversion)
|
||||||
@ -122,7 +123,7 @@ asDraw UIState{aopts=_uopts@UIOpts{uoCliOpts=copts@CliOpts{reportspec_=rspec}}
|
|||||||
- 2 -- XXX due to margin ? shouldn't be necessary (cf UIUtils)
|
- 2 -- XXX due to margin ? shouldn't be necessary (cf UIUtils)
|
||||||
displayitems = s ^. asList . listElementsL
|
displayitems = s ^. asList . listElementsL
|
||||||
|
|
||||||
acctwidths = V.map (\AccountsScreenItem{..} -> asItemIndentLevel + Hledger.Cli.textWidth asItemDisplayAccountName) displayitems
|
acctwidths = V.map (\AccountsScreenItem{..} -> asItemIndentLevel + realLength asItemDisplayAccountName) displayitems
|
||||||
balwidths = V.map (maybe 0 (wbWidth . showMixedAmountB oneLine) . asItemMixedAmount) displayitems
|
balwidths = V.map (maybe 0 (wbWidth . showMixedAmountB oneLine) . asItemMixedAmount) displayitems
|
||||||
preferredacctwidth = V.maximum acctwidths
|
preferredacctwidth = V.maximum acctwidths
|
||||||
totalacctwidthseen = V.sum acctwidths
|
totalacctwidthseen = V.sum acctwidths
|
||||||
|
|||||||
@ -73,6 +73,7 @@ executable hledger-ui
|
|||||||
, containers >=0.5.9
|
, containers >=0.5.9
|
||||||
, data-default
|
, data-default
|
||||||
, directory
|
, directory
|
||||||
|
, doclayout ==0.3.*
|
||||||
, extra >=1.6.3
|
, extra >=1.6.3
|
||||||
, filepath
|
, filepath
|
||||||
, fsnotify >=0.2.1.2 && <0.4
|
, fsnotify >=0.2.1.2 && <0.4
|
||||||
|
|||||||
@ -50,6 +50,7 @@ dependencies:
|
|||||||
- containers >=0.5.9
|
- containers >=0.5.9
|
||||||
- data-default
|
- data-default
|
||||||
- directory
|
- directory
|
||||||
|
- doclayout >=0.3 && <0.4
|
||||||
- extra >=1.6.3
|
- extra >=1.6.3
|
||||||
- filepath
|
- filepath
|
||||||
- fsnotify >=0.2.1.2 && <0.4
|
- fsnotify >=0.2.1.2 && <0.4
|
||||||
|
|||||||
@ -15,6 +15,8 @@ packages:
|
|||||||
extra-deps:
|
extra-deps:
|
||||||
# for Shake.hs (regex doesn't support base-compat-0.11):
|
# for Shake.hs (regex doesn't support base-compat-0.11):
|
||||||
- regex-1.0.2.0@rev:1
|
- regex-1.0.2.0@rev:1
|
||||||
|
- doclayout-0.3.1.1
|
||||||
|
- emojis-0.1.2
|
||||||
# for testing base-compat 0.11 compatibility (mutually exclusive with the above):
|
# for testing base-compat 0.11 compatibility (mutually exclusive with the above):
|
||||||
# - aeson-1.4.6.0
|
# - aeson-1.4.6.0
|
||||||
# - aeson-compat-0.3.9
|
# - aeson-compat-0.3.9
|
||||||
|
|||||||
@ -17,6 +17,8 @@ extra-deps:
|
|||||||
- pretty-simple-4.0.0.0
|
- pretty-simple-4.0.0.0
|
||||||
- prettyprinter-1.7.0
|
- prettyprinter-1.7.0
|
||||||
- doctest-0.18.1
|
- doctest-0.18.1
|
||||||
|
- doclayout-0.3.1.1
|
||||||
|
- emojis-0.1.2
|
||||||
# for hledger:
|
# for hledger:
|
||||||
# for hledger-ui:
|
# for hledger-ui:
|
||||||
# for hledger-web:
|
# for hledger-web:
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user