imp:cli: detect --color more safely in most cases
--color now also works in a config file, like --pager, except for two cases: it does not affect colouring of debug output, or the colouring helpers used in the check recentassertions error message.
This commit is contained in:
parent
711d921774
commit
b940254025
@ -9,7 +9,6 @@ more easily by hledger commands/scripts in this and other packages.
|
|||||||
|
|
||||||
module Hledger.Data.RawOptions (
|
module Hledger.Data.RawOptions (
|
||||||
RawOpts,
|
RawOpts,
|
||||||
YNA,
|
|
||||||
mkRawOpts,
|
mkRawOpts,
|
||||||
overRawOpts,
|
overRawOpts,
|
||||||
setopt,
|
setopt,
|
||||||
@ -153,8 +152,6 @@ maybeynopt name rawopts =
|
|||||||
Just _ -> error' $ name <> " value should be one of " <> (intercalate ", " ["y","yes","n","no"])
|
Just _ -> error' $ name <> " value should be one of " <> (intercalate ", " ["y","yes","n","no"])
|
||||||
_ -> Nothing
|
_ -> Nothing
|
||||||
|
|
||||||
data YNA = Yes | No | Auto deriving (Eq,Show)
|
|
||||||
|
|
||||||
maybeynaopt :: String -> RawOpts -> Maybe YNA
|
maybeynaopt :: String -> RawOpts -> Maybe YNA
|
||||||
maybeynaopt name rawopts =
|
maybeynaopt name rawopts =
|
||||||
case maybestringopt name rawopts of
|
case maybestringopt name rawopts of
|
||||||
|
|||||||
@ -192,14 +192,14 @@ instance Show (Reader m) where show r = show (rFormat r) ++ " reader"
|
|||||||
|
|
||||||
-- | Parse an InputOpts from a RawOpts and a provided date.
|
-- | Parse an InputOpts from a RawOpts and a provided date.
|
||||||
-- This will fail with a usage error if the forecast period expression cannot be parsed.
|
-- This will fail with a usage error if the forecast period expression cannot be parsed.
|
||||||
rawOptsToInputOpts :: Day -> RawOpts -> InputOpts
|
rawOptsToInputOpts :: Day -> Bool -> RawOpts -> InputOpts
|
||||||
rawOptsToInputOpts day rawopts =
|
rawOptsToInputOpts day usecoloronstdout rawopts =
|
||||||
|
|
||||||
let noinferbalancingcosts = boolopt "strict" rawopts || stringopt "args" rawopts == "balanced"
|
let noinferbalancingcosts = boolopt "strict" rawopts || stringopt "args" rawopts == "balanced"
|
||||||
|
|
||||||
-- Do we really need to do all this work just to get the requested end date? This is duplicating
|
-- Do we really need to do all this work just to get the requested end date? This is duplicating
|
||||||
-- much of reportOptsToSpec.
|
-- much of reportOptsToSpec.
|
||||||
ropts = rawOptsToReportOpts day rawopts
|
ropts = rawOptsToReportOpts day usecoloronstdout rawopts
|
||||||
argsquery = map fst . rights . map (parseQueryTerm day) $ querystring_ ropts
|
argsquery = map fst . rights . map (parseQueryTerm day) $ querystring_ ropts
|
||||||
datequery = simplifyQuery . filterQuery queryIsDate . And $ queryFromFlags ropts : argsquery
|
datequery = simplifyQuery . filterQuery queryIsDate . And $ queryFromFlags ropts : argsquery
|
||||||
|
|
||||||
|
|||||||
@ -226,14 +226,14 @@ defreportopts = ReportOpts
|
|||||||
, layout_ = LayoutWide Nothing
|
, layout_ = LayoutWide Nothing
|
||||||
}
|
}
|
||||||
|
|
||||||
-- | Generate a ReportOpts from raw command-line input, given a day.
|
-- | Generate a ReportOpts from raw command-line input, given a day and whether to use ANSI colour/styles in standard output.
|
||||||
-- This will fail with a usage error if it is passed
|
-- This will fail with a usage error if it is passed
|
||||||
-- - an invalid --format argument,
|
-- - an invalid --format argument,
|
||||||
-- - an invalid --value argument,
|
-- - an invalid --value argument,
|
||||||
-- - if --valuechange is called with a valuation type other than -V/--value=end.
|
-- - if --valuechange is called with a valuation type other than -V/--value=end.
|
||||||
-- - an invalid --pretty argument,
|
-- - an invalid --pretty argument,
|
||||||
rawOptsToReportOpts :: Day -> RawOpts -> ReportOpts
|
rawOptsToReportOpts :: Day -> Bool -> RawOpts -> ReportOpts
|
||||||
rawOptsToReportOpts d rawopts =
|
rawOptsToReportOpts d usecoloronstdout rawopts =
|
||||||
|
|
||||||
let formatstring = T.pack <$> maybestringopt "format" rawopts
|
let formatstring = T.pack <$> maybestringopt "format" rawopts
|
||||||
querystring = map T.pack $ listofstringopt "args" rawopts -- doesn't handle an arg like "" right
|
querystring = map T.pack $ listofstringopt "args" rawopts -- doesn't handle an arg like "" right
|
||||||
@ -277,7 +277,7 @@ rawOptsToReportOpts d rawopts =
|
|||||||
,percent_ = boolopt "percent" rawopts
|
,percent_ = boolopt "percent" rawopts
|
||||||
,invert_ = boolopt "invert" rawopts
|
,invert_ = boolopt "invert" rawopts
|
||||||
,pretty_ = pretty
|
,pretty_ = pretty
|
||||||
,color_ = useColorOnStdout -- a lower-level helper
|
,color_ = usecoloronstdout
|
||||||
,transpose_ = boolopt "transpose" rawopts
|
,transpose_ = boolopt "transpose" rawopts
|
||||||
,layout_ = layoutopt rawopts
|
,layout_ = layoutopt rawopts
|
||||||
}
|
}
|
||||||
@ -941,5 +941,5 @@ updateReportSpecWith = overEither reportOpts
|
|||||||
|
|
||||||
-- | Generate a ReportSpec from RawOpts and a provided day, or return an error
|
-- | Generate a ReportSpec from RawOpts and a provided day, or return an error
|
||||||
-- string if there are regular expression errors.
|
-- string if there are regular expression errors.
|
||||||
rawOptsToReportSpec :: Day -> RawOpts -> Either String ReportSpec
|
rawOptsToReportSpec :: Day -> Bool -> RawOpts -> Either String ReportSpec
|
||||||
rawOptsToReportSpec day = reportOptsToSpec day . rawOptsToReportOpts day
|
rawOptsToReportSpec day coloronstdout = reportOptsToSpec day . rawOptsToReportOpts day coloronstdout
|
||||||
|
|||||||
@ -33,13 +33,17 @@ module Hledger.Utils.IO (
|
|||||||
outputFileOption,
|
outputFileOption,
|
||||||
hasOutputFile,
|
hasOutputFile,
|
||||||
splitFlagsAndVals,
|
splitFlagsAndVals,
|
||||||
getLongOpt,
|
getOpt,
|
||||||
parseYN,
|
parseYN,
|
||||||
|
parseYNA,
|
||||||
|
YNA(..),
|
||||||
|
|
||||||
-- * ANSI color
|
-- * ANSI color
|
||||||
colorOption,
|
|
||||||
useColorOnStdout,
|
useColorOnStdout,
|
||||||
useColorOnStderr,
|
useColorOnStderr,
|
||||||
|
colorOption,
|
||||||
|
useColorOnStdoutUnsafe,
|
||||||
|
useColorOnStderrUnsafe,
|
||||||
-- XXX needed for using color/bgColor/colorB/bgColorB, but clashing with UIUtils:
|
-- XXX needed for using color/bgColor/colorB/bgColorB, but clashing with UIUtils:
|
||||||
-- Color(..),
|
-- Color(..),
|
||||||
-- ColorIntensity(..),
|
-- ColorIntensity(..),
|
||||||
@ -142,11 +146,12 @@ import Data.Char (toLower)
|
|||||||
|
|
||||||
-- | pretty-simple options with colour enabled if allowed.
|
-- | pretty-simple options with colour enabled if allowed.
|
||||||
prettyopts =
|
prettyopts =
|
||||||
(if useColorOnStderr then defaultOutputOptionsDarkBg else defaultOutputOptionsNoColor)
|
(if useColorOnStderrUnsafe then defaultOutputOptionsDarkBg else defaultOutputOptionsNoColor)
|
||||||
{ outputOptionsIndentAmount = 2
|
{ outputOptionsIndentAmount = 2
|
||||||
-- , outputOptionsCompact = True -- fills lines, but does not respect page width (https://github.com/cdepillabout/pretty-simple/issues/126)
|
-- , outputOptionsCompact = True -- fills lines, but does not respect page width (https://github.com/cdepillabout/pretty-simple/issues/126)
|
||||||
-- , outputOptionsPageWidth = fromMaybe 80 $ unsafePerformIO getTerminalWidth
|
-- , outputOptionsPageWidth = fromMaybe 80 $ unsafePerformIO getTerminalWidth
|
||||||
}
|
}
|
||||||
|
-- XXX unsafe detection of color option for debug output, does not respect config file (perhaps evaluated before withArgs ?)
|
||||||
|
|
||||||
-- | pretty-simple options with colour disabled.
|
-- | pretty-simple options with colour disabled.
|
||||||
prettyoptsNoColor =
|
prettyoptsNoColor =
|
||||||
@ -155,7 +160,7 @@ prettyoptsNoColor =
|
|||||||
}
|
}
|
||||||
|
|
||||||
-- | Pretty show. An easier alias for pretty-simple's pShow.
|
-- | Pretty show. An easier alias for pretty-simple's pShow.
|
||||||
-- This will probably show in colour if useColorOnStderr is true.
|
-- This will probably show in colour if useColorOnStderrUnsafe is true.
|
||||||
pshow :: Show a => a -> String
|
pshow :: Show a => a -> String
|
||||||
pshow = TL.unpack . pShowOpt prettyopts
|
pshow = TL.unpack . pShowOpt prettyopts
|
||||||
|
|
||||||
@ -164,9 +169,9 @@ pshow' :: Show a => a -> String
|
|||||||
pshow' = TL.unpack . pShowOpt prettyoptsNoColor
|
pshow' = TL.unpack . pShowOpt prettyoptsNoColor
|
||||||
|
|
||||||
-- | Pretty print a showable value. An easier alias for pretty-simple's pPrint.
|
-- | Pretty print a showable value. An easier alias for pretty-simple's pPrint.
|
||||||
-- This will print in colour if useColorOnStderr is true.
|
-- This will print in colour if useColorOnStderrUnsafe is true.
|
||||||
pprint :: Show a => a -> IO ()
|
pprint :: Show a => a -> IO ()
|
||||||
pprint = pPrintOpt (if useColorOnStderr then CheckColorTty else NoCheckColorTty) prettyopts
|
pprint = pPrintOpt (if useColorOnStderrUnsafe then CheckColorTty else NoCheckColorTty) prettyopts
|
||||||
|
|
||||||
-- | Monochrome version of pprint. This will never print in colour.
|
-- | Monochrome version of pprint. This will never print in colour.
|
||||||
pprint' :: Show a => a -> IO ()
|
pprint' :: Show a => a -> IO ()
|
||||||
@ -224,7 +229,7 @@ runPager = putStr
|
|||||||
#else
|
#else
|
||||||
runPager s = do
|
runPager s = do
|
||||||
-- disable pager with --pager=no
|
-- disable pager with --pager=no
|
||||||
mpager <- getLongOpt "pager"
|
mpager <- getOpt ["pager"]
|
||||||
let nopager = not $ maybe True parseYN mpager
|
let nopager = not $ maybe True parseYN mpager
|
||||||
-- disable pager when TERM=dumb (for Emacs shell users)
|
-- disable pager when TERM=dumb (for Emacs shell users)
|
||||||
dumbterm <- (== Just "dumb") <$> lookupEnv "TERM"
|
dumbterm <- (== Just "dumb") <$> lookupEnv "TERM"
|
||||||
@ -247,24 +252,28 @@ runPager s = do
|
|||||||
s
|
s
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
-- | Given a list of arguments, split any of the form --flag=val into --flag, val.
|
-- | Given a list of arguments, split any of the form --flag=VAL or -fVAL
|
||||||
|
-- into separate list items. Multiple valueless short flags joined together is not supported.
|
||||||
splitFlagsAndVals :: [String] -> [String]
|
splitFlagsAndVals :: [String] -> [String]
|
||||||
splitFlagsAndVals =
|
splitFlagsAndVals = concatMap $
|
||||||
concatMap
|
\case
|
||||||
(\a ->
|
a@('-':'-':_) | '=' `elem` a -> let (x,y) = break (=='=') a in [x, drop 1 y]
|
||||||
if "--" `isPrefixOf` a && '=' `elem` a
|
a@('-':f:_:_) | not $ f=='-' -> [take 2 a, drop 2 a]
|
||||||
then let (x,y) = break (=='=') a in [x, drop 1 y]
|
a -> [a]
|
||||||
else [a])
|
|
||||||
|
|
||||||
-- | Read the value of the rightmost long option of this name from the command line arguments.
|
toFlag [c] = ['-',c]
|
||||||
|
toFlag s = '-':'-':s
|
||||||
|
|
||||||
|
-- | Given one or more long or short option names, read the rightmost value of this option from the command line arguments.
|
||||||
-- If the value is missing raise an error.
|
-- If the value is missing raise an error.
|
||||||
getLongOpt :: String -> IO (Maybe String)
|
getOpt :: [String] -> IO (Maybe String)
|
||||||
getLongOpt name = do
|
getOpt names = do
|
||||||
rargs <- reverse . splitFlagsAndVals <$> getArgs
|
rargs <- reverse . splitFlagsAndVals <$> getArgs
|
||||||
let flag = "--"<>name
|
let flags = map toFlag names
|
||||||
return $
|
return $
|
||||||
case break (==flag) rargs of
|
case break ((`elem` flags)) rargs of
|
||||||
([],_) -> error' $ flag <> " requires a value"
|
(_,[]) -> Nothing
|
||||||
|
([],flag:_) -> error' $ flag <> " requires a value"
|
||||||
(argsafter,_) -> Just $ last argsafter
|
(argsafter,_) -> Just $ last argsafter
|
||||||
|
|
||||||
-- | Parse y/yes/always or n/no/never to true or false, or with any other value raise an error.
|
-- | Parse y/yes/always or n/no/never to true or false, or with any other value raise an error.
|
||||||
@ -275,6 +284,17 @@ parseYN s
|
|||||||
| otherwise = error' $ "value should be one of " <> (intercalate ", " ["y","yes","n","no"])
|
| otherwise = error' $ "value should be one of " <> (intercalate ", " ["y","yes","n","no"])
|
||||||
where l = map toLower s
|
where l = map toLower s
|
||||||
|
|
||||||
|
data YNA = Yes | No | Auto deriving (Eq,Show)
|
||||||
|
|
||||||
|
-- | Parse y/yes/always or n/no/never or a/auto to a YNA choice, or with any other value raise an error.
|
||||||
|
parseYNA :: String -> YNA
|
||||||
|
parseYNA s
|
||||||
|
| l `elem` ["y","yes","always"] = Yes
|
||||||
|
| l `elem` ["n","no","never"] = No
|
||||||
|
| l `elem` ["a","auto"] = Auto
|
||||||
|
| otherwise = error' $ "value should be one of " <> (intercalate ", " ["y","yes","n","no","a","auto"])
|
||||||
|
where l = map toLower s
|
||||||
|
|
||||||
-- Command line arguments
|
-- Command line arguments
|
||||||
|
|
||||||
-- | The command line arguments that were used at program startup.
|
-- | The command line arguments that were used at program startup.
|
||||||
@ -290,39 +310,25 @@ progArgs = unsafePerformIO getArgs
|
|||||||
-- the enabling of orderdates and assertions checks in journalFinalise
|
-- the enabling of orderdates and assertions checks in journalFinalise
|
||||||
-- Separate these into unsafe and safe variants and try to use the latter more
|
-- Separate these into unsafe and safe variants and try to use the latter more
|
||||||
|
|
||||||
-- | Read the value of the -o/--output-file command line option provided at program startup,
|
outputFileOption :: IO (Maybe String)
|
||||||
-- if any, using unsafePerformIO.
|
outputFileOption = getOpt ["output-file","o"]
|
||||||
outputFileOption :: Maybe String
|
|
||||||
outputFileOption =
|
|
||||||
-- keep synced with output-file flag definition in hledger:CliOptions.
|
|
||||||
let args = progArgs in
|
|
||||||
case dropWhile (not . ("-o" `isPrefixOf`)) args of
|
|
||||||
-- -oARG
|
|
||||||
('-':'o':v@(_:_)):_ -> Just v
|
|
||||||
-- -o ARG
|
|
||||||
"-o":v:_ -> Just v
|
|
||||||
_ ->
|
|
||||||
case dropWhile (/="--output-file") args of
|
|
||||||
-- --output-file ARG
|
|
||||||
"--output-file":v:_ -> Just v
|
|
||||||
_ ->
|
|
||||||
case take 1 $ filter ("--output-file=" `isPrefixOf`) args of
|
|
||||||
-- --output=file=ARG
|
|
||||||
['-':'-':'o':'u':'t':'p':'u':'t':'-':'f':'i':'l':'e':'=':v] -> Just v
|
|
||||||
_ -> Nothing
|
|
||||||
|
|
||||||
-- | Check whether the -o/--output-file option has been used at program startup
|
hasOutputFile :: IO Bool
|
||||||
-- with an argument other than "-", using unsafePerformIO.
|
hasOutputFile = do
|
||||||
hasOutputFile :: Bool
|
mv <- getOpt ["output-file","o"]
|
||||||
hasOutputFile = outputFileOption `notElem` [Nothing, Just "-"]
|
return $
|
||||||
-- XXX shouldn't we check that stdout is interactive. instead ?
|
case mv of
|
||||||
|
Nothing -> False
|
||||||
|
Just "-" -> False
|
||||||
|
_ -> True
|
||||||
|
|
||||||
-- ANSI colour
|
-- ANSI colour
|
||||||
|
-- XXX unsafe detection of --color option. At the moment this is always true in ghci,
|
||||||
ifAnsi f = if useColorOnStdout then f else id
|
-- respects the command line --color if compiled, and ignores the config file.
|
||||||
|
ifAnsi f = if useColorOnStdoutUnsafe then f else id
|
||||||
|
|
||||||
-- | Versions of some of text-ansi's string colors/styles which are more careful
|
-- | Versions of some of text-ansi's string colors/styles which are more careful
|
||||||
-- to not print junk onscreen. These use our useColorOnStdout.
|
-- to not print junk onscreen. These use our useColorOnStdoutUnsafe.
|
||||||
bold' :: String -> String
|
bold' :: String -> String
|
||||||
bold' = ifAnsi bold
|
bold' = ifAnsi bold
|
||||||
|
|
||||||
@ -380,29 +386,30 @@ brightWhite' = ifAnsi brightWhite
|
|||||||
rgb' :: Word8 -> Word8 -> Word8 -> String -> String
|
rgb' :: Word8 -> Word8 -> Word8 -> String -> String
|
||||||
rgb' r g b = ifAnsi (rgb r g b)
|
rgb' r g b = ifAnsi (rgb r g b)
|
||||||
|
|
||||||
-- | Read the value of the --color or --colour command line option provided at program startup
|
-- | Get the value of the rightmost --color option from the command line arguments.
|
||||||
-- using unsafePerformIO. If this option was not provided, returns the empty string.
|
useColorOnStdout :: IO Bool
|
||||||
colorOption :: String
|
useColorOnStdout = do
|
||||||
colorOption =
|
nooutputfile <- not <$> hasOutputFile
|
||||||
-- similar to debugLevel
|
usecolor <- useColorOnHandle stdout
|
||||||
-- keep synced with color/colour flag definition in hledger:CliOptions
|
return $ nooutputfile && usecolor
|
||||||
let args = progArgs in
|
|
||||||
case dropWhile (/="--color") args of
|
-- traceWith (("USE COLOR ON STDOUT: "<>).show) <$>
|
||||||
-- --color ARG
|
|
||||||
"--color":v:_ -> v
|
useColorOnStderr :: IO Bool
|
||||||
_ ->
|
useColorOnStderr = useColorOnHandle stderr
|
||||||
case take 1 $ filter ("--color=" `isPrefixOf`) args of
|
|
||||||
-- --color=ARG
|
-- | Should ANSI color & styling be used with this output handle ?
|
||||||
['-':'-':'c':'o':'l':'o':'r':'=':v] -> v
|
useColorOnHandle :: Handle -> IO Bool
|
||||||
_ ->
|
useColorOnHandle h = do
|
||||||
case dropWhile (/="--colour") args of
|
no_color <- isJust <$> lookupEnv "NO_COLOR"
|
||||||
-- --colour ARG
|
supports_color <- hSupportsANSIColor h
|
||||||
"--colour":v:_ -> v
|
yna <- colorOption
|
||||||
_ ->
|
return $ yna==Yes || (yna==Auto && not no_color && supports_color)
|
||||||
case take 1 $ filter ("--colour=" `isPrefixOf`) args of
|
|
||||||
-- --colour=ARG
|
colorOption :: IO YNA
|
||||||
['-':'-':'c':'o':'l':'o':'u':'r':'=':v] -> v
|
colorOption = do
|
||||||
_ -> ""
|
mcolor <- getOpt ["color","colour"]
|
||||||
|
return $ maybe Auto parseYNA mcolor
|
||||||
|
|
||||||
-- | Check the IO environment to see if ANSI colour codes should be used on stdout.
|
-- | Check the IO environment to see if ANSI colour codes should be used on stdout.
|
||||||
-- This is done using unsafePerformIO so it can be used anywhere, eg in
|
-- This is done using unsafePerformIO so it can be used anywhere, eg in
|
||||||
@ -415,21 +422,13 @@ colorOption =
|
|||||||
-- and stdout supports ANSI color
|
-- and stdout supports ANSI color
|
||||||
-- and -o/--output-file was not used, or its value is "-"
|
-- and -o/--output-file was not used, or its value is "-"
|
||||||
-- ).
|
-- ).
|
||||||
useColorOnStdout :: Bool
|
useColorOnStdoutUnsafe :: Bool
|
||||||
useColorOnStdout = not hasOutputFile && useColorOnHandle stdout
|
useColorOnStdoutUnsafe = unsafePerformIO useColorOnStdout
|
||||||
|
|
||||||
-- | Like useColorOnStdout, but checks for ANSI color support on stderr,
|
-- | Like useColorOnStdoutUnsafe, but checks for ANSI color support on stderr,
|
||||||
-- and is not affected by -o/--output-file.
|
-- and is not affected by -o/--output-file.
|
||||||
useColorOnStderr :: Bool
|
useColorOnStderrUnsafe :: Bool
|
||||||
useColorOnStderr = useColorOnHandle stderr
|
useColorOnStderrUnsafe = unsafePerformIO useColorOnStderr
|
||||||
|
|
||||||
useColorOnHandle :: Handle -> Bool
|
|
||||||
useColorOnHandle h = unsafePerformIO $ do
|
|
||||||
no_color <- isJust <$> lookupEnv "NO_COLOR"
|
|
||||||
supports_color <- hSupportsANSIColor h
|
|
||||||
let coloroption = colorOption
|
|
||||||
return $ coloroption `elem` ["always","yes","y"]
|
|
||||||
|| (coloroption `notElem` ["never","no","n"] && not no_color && supports_color)
|
|
||||||
|
|
||||||
-- | Wrap a string in ANSI codes to set and reset foreground colour.
|
-- | Wrap a string in ANSI codes to set and reset foreground colour.
|
||||||
-- ColorIntensity is @Dull@ or @Vivid@ (ie normal and bold).
|
-- ColorIntensity is @Dull@ or @Vivid@ (ie normal and bold).
|
||||||
|
|||||||
@ -66,7 +66,8 @@ hledgerUiMain = withGhcDebug' $ withProgName "hledger-ui.log" $ do -- force Hle
|
|||||||
dbg1IO "debugLevel" debugLevel
|
dbg1IO "debugLevel" debugLevel
|
||||||
|
|
||||||
-- try to encourage user's $PAGER to properly display ANSI (in command line help)
|
-- try to encourage user's $PAGER to properly display ANSI (in command line help)
|
||||||
when useColorOnStdout setupPager
|
usecolor <- useColorOnStdout
|
||||||
|
when usecolor setupPager
|
||||||
|
|
||||||
opts@UIOpts{uoCliOpts=copts@CliOpts{inputopts_=iopts,rawopts_=rawopts}} <- getHledgerUIOpts
|
opts@UIOpts{uoCliOpts=copts@CliOpts{inputopts_=iopts,rawopts_=rawopts}} <- getHledgerUIOpts
|
||||||
-- when (debug_ $ cliopts_ opts) $ printf "%s\n" prognameandversion >> printf "opts: %s\n" (show opts)
|
-- when (debug_ $ cliopts_ opts) $ printf "%s\n" prognameandversion >> printf "opts: %s\n" (show opts)
|
||||||
|
|||||||
@ -50,7 +50,8 @@ hledgerWebMain = withGhcDebug' $ do
|
|||||||
when (ghcDebugMode == GDPauseAtStart) $ ghcDebugPause'
|
when (ghcDebugMode == GDPauseAtStart) $ ghcDebugPause'
|
||||||
|
|
||||||
-- try to encourage user's $PAGER to properly display ANSI (in command line help)
|
-- try to encourage user's $PAGER to properly display ANSI (in command line help)
|
||||||
when useColorOnStdout setupPager
|
usecolor <- useColorOnStdout
|
||||||
|
when usecolor setupPager
|
||||||
|
|
||||||
wopts@WebOpts{cliopts_=copts@CliOpts{debug_, rawopts_}} <- getHledgerWebOpts
|
wopts@WebOpts{cliopts_=copts@CliOpts{debug_, rawopts_}} <- getHledgerWebOpts
|
||||||
when (debug_ > 0) $ printf "%s\n" prognameandversion >> printf "opts: %s\n" (show wopts)
|
when (debug_ > 0) $ printf "%s\n" prognameandversion >> printf "opts: %s\n" (show wopts)
|
||||||
|
|||||||
@ -126,9 +126,10 @@ hledgerWebTest = do
|
|||||||
|
|
||||||
-- yit "can add transactions" $ do
|
-- yit "can add transactions" $ do
|
||||||
|
|
||||||
|
usecolor <- useColorOnStdout
|
||||||
let
|
let
|
||||||
rawopts = [("forecast","")]
|
rawopts = [("forecast","")]
|
||||||
iopts = rawOptsToInputOpts d $ mkRawOpts rawopts
|
iopts = rawOptsToInputOpts d usecolor $ mkRawOpts rawopts
|
||||||
f = "fake" -- need a non-null filename so forecast transactions get index 0
|
f = "fake" -- need a non-null filename so forecast transactions get index 0
|
||||||
pj <- readJournal' (T.pack $ unlines -- PARTIAL: readJournal' should not fail
|
pj <- readJournal' (T.pack $ unlines -- PARTIAL: readJournal' should not fail
|
||||||
["~ monthly"
|
["~ monthly"
|
||||||
|
|||||||
14
hledger.conf
14
hledger.conf
@ -1,6 +1,14 @@
|
|||||||
# This is an empty config file, to disable your personal hledger config
|
# This is an empty config file, to disable your personal hledger config
|
||||||
# while developing and testing hledger in this directory.
|
# while developing and testing hledger in this directory.
|
||||||
# For an example config, see hledger.conf.sample.
|
# For an example config, see hledger.conf.sample.
|
||||||
--pager yes
|
|
||||||
# --color=no
|
# --pager n
|
||||||
# --debug
|
# this works
|
||||||
|
|
||||||
|
# --color n
|
||||||
|
# this mostly works, but does not affect
|
||||||
|
# 1. debug output
|
||||||
|
# 2. the ansi helpers used by check recentassertions
|
||||||
|
|
||||||
|
#--debug
|
||||||
|
# this doesn't work in config files yet
|
||||||
|
|||||||
@ -204,7 +204,8 @@ main = withGhcDebug' $ do
|
|||||||
-- give ghc-debug a chance to take control
|
-- give ghc-debug a chance to take control
|
||||||
when (ghcDebugMode == GDPauseAtStart) $ ghcDebugPause'
|
when (ghcDebugMode == GDPauseAtStart) $ ghcDebugPause'
|
||||||
-- try to encourage user's $PAGER to display ANSI when supported
|
-- try to encourage user's $PAGER to display ANSI when supported
|
||||||
when useColorOnStdout setupPager
|
usecolor <- useColorOnStdout
|
||||||
|
when usecolor setupPager
|
||||||
-- Search PATH for addon commands. Exclude any that match builtin command names.
|
-- Search PATH for addon commands. Exclude any that match builtin command names.
|
||||||
addons <- hledgerAddons <&> filter (not . (`elem` builtinCommandNames) . dropExtension)
|
addons <- hledgerAddons <&> filter (not . (`elem` builtinCommandNames) . dropExtension)
|
||||||
|
|
||||||
@ -269,6 +270,7 @@ main = withGhcDebug' $ do
|
|||||||
-- the command line contains a bad flag or wrongly present/missing flag value,
|
-- the command line contains a bad flag or wrongly present/missing flag value,
|
||||||
-- cmdname will be "".
|
-- cmdname will be "".
|
||||||
args = [confcmdarg | not $ null confcmdarg] <> cliargswithcmdfirstwithoutclispecific
|
args = [confcmdarg | not $ null confcmdarg] <> cliargswithcmdfirstwithoutclispecific
|
||||||
|
-- XXX Unknown flag: --depth while parsing these args for command name
|
||||||
cmdname = stringopt "command" $ cmdargsParse "for command name" (mainmode addons) args
|
cmdname = stringopt "command" $ cmdargsParse "for command name" (mainmode addons) args
|
||||||
badcmdprovided = null cmdname && not nocmdprovided
|
badcmdprovided = null cmdname && not nocmdprovided
|
||||||
isaddoncmd = not (null cmdname) && cmdname `elem` addons
|
isaddoncmd = not (null cmdname) && cmdname `elem` addons
|
||||||
|
|||||||
@ -493,7 +493,7 @@ showModeUsage =
|
|||||||
|
|
||||||
-- | Add some ANSI decoration to cmdargs' help output.
|
-- | Add some ANSI decoration to cmdargs' help output.
|
||||||
highlightHelp
|
highlightHelp
|
||||||
| not useColorOnStdout = id
|
| not useColorOnStdoutUnsafe = id -- XXX unsafe boldening help headings - seems to work, even respecting config file
|
||||||
| otherwise = unlines . zipWith (curry f) [1..] . lines
|
| otherwise = unlines . zipWith (curry f) [1..] . lines
|
||||||
where
|
where
|
||||||
f (n,l)
|
f (n,l)
|
||||||
@ -606,8 +606,9 @@ rawOptsToCliOpts rawopts = do
|
|||||||
Nothing -> currentDay
|
Nothing -> currentDay
|
||||||
Just d -> either (const err) fromEFDay $ fixSmartDateStrEither' currentDay (T.pack d)
|
Just d -> either (const err) fromEFDay $ fixSmartDateStrEither' currentDay (T.pack d)
|
||||||
where err = error' $ "Unable to parse date \"" ++ d ++ "\""
|
where err = error' $ "Unable to parse date \"" ++ d ++ "\""
|
||||||
let iopts = rawOptsToInputOpts day rawopts
|
usecolor <- useColorOnStdout
|
||||||
rspec <- either error' pure $ rawOptsToReportSpec day rawopts -- PARTIAL:
|
let iopts = rawOptsToInputOpts day usecolor rawopts
|
||||||
|
rspec <- either error' pure $ rawOptsToReportSpec day usecolor rawopts -- PARTIAL:
|
||||||
mcolumns <- readMay <$> getEnvSafe "COLUMNS"
|
mcolumns <- readMay <$> getEnvSafe "COLUMNS"
|
||||||
mtermwidth <-
|
mtermwidth <-
|
||||||
#ifdef mingw32_HOST_OS
|
#ifdef mingw32_HOST_OS
|
||||||
|
|||||||
@ -163,7 +163,7 @@ _banner_speed = drop 1 [""
|
|||||||
-- picking one that will contrast with the current terminal background colour.
|
-- picking one that will contrast with the current terminal background colour.
|
||||||
accent :: String -> String
|
accent :: String -> String
|
||||||
accent
|
accent
|
||||||
| not useColorOnStdout = id
|
| not useColorOnStdoutUnsafe = id -- XXX unsafe accenting the title banner - seems to work, even respecting config file
|
||||||
| terminalIsLight == Just False = brightWhite
|
| terminalIsLight == Just False = brightWhite
|
||||||
| terminalIsLight == Just True = brightBlack
|
| terminalIsLight == Just True = brightBlack
|
||||||
| otherwise = id
|
| otherwise = id
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user