From 345227024140ae451f4c859fe6cc89611795c895 Mon Sep 17 00:00:00 2001 From: Simon Michael Date: Tue, 14 Jul 2020 12:08:36 -0700 Subject: [PATCH] cli: --color/--colour option; smart emacs, windows autodetection (#1296) --- hledger-lib/Hledger/Reports/ReportOptions.hs | 22 ++++++++++++++++---- hledger-lib/package.yaml | 2 +- hledger-ui/package.yaml | 2 +- hledger/Hledger/Cli/CliOptions.hs | 11 ++++++++++ hledger/Hledger/Cli/Commands/Balance.md | 8 +++---- hledger/hledger.m4.md | 9 ++++++-- hledger/package.yaml | 2 +- stack8.2.yaml | 1 + stack8.4.yaml | 1 + 9 files changed, 44 insertions(+), 14 deletions(-) diff --git a/hledger-lib/Hledger/Reports/ReportOptions.hs b/hledger-lib/Hledger/Reports/ReportOptions.hs index 181fee90f..cec488a2f 100644 --- a/hledger-lib/Hledger/Reports/ReportOptions.hs +++ b/hledger-lib/Hledger/Reports/ReportOptions.hs @@ -4,7 +4,10 @@ Options common to most hledger reports. -} -{-# LANGUAGE OverloadedStrings, RecordWildCards, LambdaCase, DeriveDataTypeable #-} +{-# LANGUAGE DeriveDataTypeable #-} +{-# LANGUAGE LambdaCase #-} +{-# LANGUAGE OverloadedStrings #-} +{-# LANGUAGE RecordWildCards #-} module Hledger.Reports.ReportOptions ( ReportOpts(..), @@ -54,7 +57,9 @@ import Data.Typeable (Typeable) import Data.Time.Calendar import Data.Default import Safe -import System.Console.ANSI (hSupportsANSI) + +import System.Console.ANSI (hSupportsANSIColor) +import System.Environment (lookupEnv) import System.IO (stdout) import Text.Megaparsec.Custom @@ -129,6 +134,10 @@ data ReportOpts = ReportOpts { -- sign normalisation, converting normally negative subreports to -- normally positive for a more conventional display. ,color_ :: Bool + -- ^ Whether to use ANSI color codes in text output. + -- Influenced by the --color/colour flag (cf CliOptions), + -- whether stdout is an interactive terminal, and the value of + -- TERM and existence of NO_COLOR environment variables. ,forecast_ :: Maybe DateSpan ,transpose_ :: Bool } deriving (Show, Data, Typeable) @@ -172,7 +181,9 @@ rawOptsToReportOpts :: RawOpts -> IO ReportOpts rawOptsToReportOpts rawopts = checkReportOpts <$> do let rawopts' = checkRawOpts rawopts d <- getCurrentDay - color <- hSupportsANSI stdout + no_color <- isJust <$> lookupEnv "NO_COLOR" + supports_color <- hSupportsANSIColor stdout + let colorflag = stringopt "color" rawopts return defreportopts{ today_ = Just d ,period_ = periodFromRawOpts d rawopts' @@ -200,7 +211,10 @@ rawOptsToReportOpts rawopts = checkReportOpts <$> do ,percent_ = boolopt "percent" rawopts' ,invert_ = boolopt "invert" rawopts' ,pretty_tables_ = boolopt "pretty-tables" rawopts' - ,color_ = color + ,color_ = and [not no_color + ,not $ colorflag `elem` ["never","no"] + ,colorflag `elem` ["always","yes"] || supports_color + ] ,forecast_ = forecastPeriodFromRawOpts d rawopts' ,transpose_ = boolopt "transpose" rawopts' } diff --git a/hledger-lib/package.yaml b/hledger-lib/package.yaml index 954148232..1353382b8 100644 --- a/hledger-lib/package.yaml +++ b/hledger-lib/package.yaml @@ -48,7 +48,7 @@ dependencies: - base-compat-batteries >=0.10.1 && <0.12 - aeson >=1 - aeson-pretty -- ansi-terminal >=0.6.2.3 +- ansi-terminal >=0.9 - array - blaze-markup >=0.5.1 - bytestring diff --git a/hledger-ui/package.yaml b/hledger-ui/package.yaml index d3de27b5c..adba20277 100644 --- a/hledger-ui/package.yaml +++ b/hledger-ui/package.yaml @@ -43,7 +43,7 @@ cpp-options: -DVERSION="1.18.99" dependencies: - hledger-lib >=1.18.99 && <1.19 - hledger >=1.18.99 && <1.19 -- ansi-terminal >=0.6.2.3 +- ansi-terminal >=0.9 - async - base >=4.9 && <4.15 - base-compat-batteries >=0.10.1 && <0.12 diff --git a/hledger/Hledger/Cli/CliOptions.hs b/hledger/Hledger/Cli/CliOptions.hs index 870c3701c..550770bbb 100644 --- a/hledger/Hledger/Cli/CliOptions.hs +++ b/hledger/Hledger/Cli/CliOptions.hs @@ -188,6 +188,17 @@ reportflags = [ , "Also, in hledger-ui, make future transactions visible." , "Note that = (and not a space) is required before PERIODEXP if you wish to supply it." ]) + + -- general output-related + + ,flagReq ["color","colour"] (\s opts -> Right $ setopt "color" s opts) "always|never|auto" + (unwords + ["When to use color (or colour) in terminal output." + ,"'auto' is the default; it tries to enable color when the terminal is color-supporting and interactive." + ,"'always' or 'yes' forces color on, useful eg when piping output into 'less -R'." + ,"'never' or 'no' forces color off." + ,"A NO_COLOR environment variable will also force color off, overriding this option." + ]) ] -- | Flags for selecting flat/tree mode, used in accounts/balance reports. diff --git a/hledger/Hledger/Cli/Commands/Balance.md b/hledger/Hledger/Cli/Commands/Balance.md index 045687dbe..d503816ff 100644 --- a/hledger/Hledger/Cli/Commands/Balance.md +++ b/hledger/Hledger/Cli/Commands/Balance.md @@ -124,10 +124,8 @@ Some example formats: ### Colour support -The balance command shows negative amounts in red, if: - -- the `TERM` environment variable is not set to `dumb` -- the output is not being redirected or piped anywhere +In terminal output, when colour is enabled, +the balance command shows negative amounts in red. ### Flat mode @@ -320,7 +318,7 @@ the width of multicommodity reports. When the report is still too wide, a good workaround is to pipe it into `less -RS` (-R for colour, -S to chop long lines). -Eg: `hledger bal -D | less -RS`. +Eg: `hledger bal -D --color=yes | less -RS`. ### Budget report diff --git a/hledger/hledger.m4.md b/hledger/hledger.m4.md index d188e9404..c604746ba 100644 --- a/hledger/hledger.m4.md +++ b/hledger/hledger.m4.md @@ -1723,12 +1723,17 @@ directory. These are typically prototypes and not guaranteed to work. # ENVIRONMENT +m4_dnl Standard LEDGER_FILE description: +_LEDGER_FILE_ + **COLUMNS** The screen width used by the register command. Default: the full terminal width. -m4_dnl Standard LEDGER_FILE description: -_LEDGER_FILE_ +**NO_COLOR** +If this variable exists with any value, +hledger will not use ANSI color codes in terminal output. +This overrides the --color/--colour option. # FILES diff --git a/hledger/package.yaml b/hledger/package.yaml index 8b025df0f..ab1345f98 100644 --- a/hledger/package.yaml +++ b/hledger/package.yaml @@ -110,7 +110,7 @@ ghc-options: dependencies: - hledger-lib >=1.18.99 && <1.19 - aeson >=1 -- ansi-terminal >=0.6.2.3 +- ansi-terminal >=0.9 - base >=4.9 && <4.15 - base-compat-batteries >=0.10.1 && <0.12 - bytestring diff --git a/stack8.2.yaml b/stack8.2.yaml index 459178d32..84fde03c1 100644 --- a/stack8.2.yaml +++ b/stack8.2.yaml @@ -16,6 +16,7 @@ packages: extra-deps: # use the latest base-compat with all ghc versions - aeson-1.3.1.1 +- ansi-terminal-0.10.3 - base-compat-0.10.1 - base-compat-batteries-0.10.1 - cassava-megaparsec-2.0.0 diff --git a/stack8.4.yaml b/stack8.4.yaml index c32bf942c..551bf83b1 100644 --- a/stack8.4.yaml +++ b/stack8.4.yaml @@ -13,6 +13,7 @@ packages: - hledger-web extra-deps: +- ansi-terminal-0.10.3 - cassava-megaparsec-2.0.0 - config-ini-0.2.3.0 - doctest-0.16.3