imp: cli: try to ensure less (and its more mode) show ANSI (fix #2015)
If you use some other $PAGER, you will have to configure it to show ANSI yourself (or disable ANSI, eg by setting NO_COLOR=1).
This commit is contained in:
parent
c661fa7763
commit
1de8600067
@ -21,6 +21,7 @@ module Hledger.Utils.IO (
|
|||||||
|
|
||||||
-- * Viewing with pager
|
-- * Viewing with pager
|
||||||
pager,
|
pager,
|
||||||
|
setupPager,
|
||||||
|
|
||||||
-- * Terminal size
|
-- * Terminal size
|
||||||
getTerminalHeightWidth,
|
getTerminalHeightWidth,
|
||||||
@ -108,7 +109,7 @@ import System.Console.ANSI (Color(..),ColorIntensity(..),
|
|||||||
ConsoleLayer(..), SGR(..), hSupportsANSIColor, setSGRCode, getLayerColor)
|
ConsoleLayer(..), SGR(..), hSupportsANSIColor, setSGRCode, getLayerColor)
|
||||||
import System.Console.Terminal.Size (Window (Window), size)
|
import System.Console.Terminal.Size (Window (Window), size)
|
||||||
import System.Directory (getHomeDirectory)
|
import System.Directory (getHomeDirectory)
|
||||||
import System.Environment (getArgs, lookupEnv)
|
import System.Environment (getArgs, lookupEnv, setEnv)
|
||||||
import System.FilePath (isRelative, (</>))
|
import System.FilePath (isRelative, (</>))
|
||||||
import System.IO
|
import System.IO
|
||||||
(Handle, IOMode (..), hGetEncoding, hSetEncoding, hSetNewlineMode,
|
(Handle, IOMode (..), hGetEncoding, hSetEncoding, hSetNewlineMode,
|
||||||
@ -160,6 +161,10 @@ pprint' = pPrintOpt CheckColorTty prettyopts'
|
|||||||
-- | Display the given text on the terminal, using the user's $PAGER if the text is taller
|
-- | Display the given text on the terminal, using the user's $PAGER if the text is taller
|
||||||
-- than the current terminal and stdout is interactive and TERM is not "dumb"
|
-- than the current terminal and stdout is interactive and TERM is not "dumb"
|
||||||
-- (except on Windows, where a pager will not be used).
|
-- (except on Windows, where a pager will not be used).
|
||||||
|
-- If the text contains ANSI codes, because hledger thinks the current terminal
|
||||||
|
-- supports those, the pager should be configured to display those, otherwise
|
||||||
|
-- users will see junk on screen (#2015).
|
||||||
|
-- We call "setLessR" at hledger startup to make that less likely.
|
||||||
pager :: String -> IO ()
|
pager :: String -> IO ()
|
||||||
#ifdef mingw32_HOST_OS
|
#ifdef mingw32_HOST_OS
|
||||||
pager = putStrLn
|
pager = putStrLn
|
||||||
@ -183,13 +188,21 @@ getTerminalHeight = fmap fst <$> getTerminalHeightWidth
|
|||||||
getTerminalWidth :: IO (Maybe Int)
|
getTerminalWidth :: IO (Maybe Int)
|
||||||
getTerminalWidth = fmap snd <$> getTerminalHeightWidth
|
getTerminalWidth = fmap snd <$> getTerminalHeightWidth
|
||||||
|
|
||||||
-- | Make sure our $LESS environment variable contains R, to help pager
|
-- | Make sure our $LESS and $MORE environment variables contain R,
|
||||||
-- call less (if it does) in a way that it will show any ANSI output properly.
|
-- to help ensure the common pager `less` will show our ANSI output properly.
|
||||||
setLessR :: IO ()
|
-- less uses $LESS by default, and $MORE when it is invoked as `more`.
|
||||||
setLessR = do
|
-- What the original `more` program does, I'm not sure.
|
||||||
less <- getEnvDefault "LESS" ""
|
-- If $PAGER is configured to something else, this probably will have no effect.
|
||||||
let less' = if 'R' `elem` less then less else 'R':less
|
setupPager :: IO ()
|
||||||
setEnv "LESS" less'
|
setupPager = do
|
||||||
|
let
|
||||||
|
addR var = do
|
||||||
|
mv <- lookupEnv var
|
||||||
|
setEnv var $ case mv of
|
||||||
|
Nothing -> "R"
|
||||||
|
Just v -> ('R':v)
|
||||||
|
addR "LESS"
|
||||||
|
addR "MORE"
|
||||||
|
|
||||||
-- Command line arguments
|
-- Command line arguments
|
||||||
|
|
||||||
|
|||||||
@ -40,6 +40,7 @@ etc.
|
|||||||
|
|
||||||
module Hledger.Cli.Main where
|
module Hledger.Cli.Main where
|
||||||
|
|
||||||
|
import Control.Monad (when)
|
||||||
import Data.List
|
import Data.List
|
||||||
import Safe
|
import Safe
|
||||||
import qualified System.Console.CmdArgs.Explicit as C
|
import qualified System.Console.CmdArgs.Explicit as C
|
||||||
@ -97,6 +98,8 @@ mainmode addons = defMode {
|
|||||||
main :: IO ()
|
main :: IO ()
|
||||||
main = do
|
main = do
|
||||||
starttime <- getPOSIXTime
|
starttime <- getPOSIXTime
|
||||||
|
-- if we will be showing ANSI, try to ensure user's $PAGER will display it properly
|
||||||
|
when useColorOnStdout setupPager
|
||||||
|
|
||||||
-- Choose and run the appropriate internal or external command based
|
-- Choose and run the appropriate internal or external command based
|
||||||
-- on the raw command-line arguments, cmdarg's interpretation of
|
-- on the raw command-line arguments, cmdarg's interpretation of
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user