imp: lib: export more terminal size, ANSI style/color helpers

Hledger.Utils.IO (and therefore Hledger and Hledger.Cli.Script) added:

    getTerminalHeightWidth
    getTerminalHeight
    getTerminalWidth
    Color(..)
    ColorIntensity(..)
    bold'
    faint'
    black'
    red'
    green'
    yellow'
    blue'
    magenta'
    cyan'
    white'
    brightBlack'
    brightRed'
    brightGreen'
    brightYellow'
    brightBlue'
    brightMagenta'
    brightCyan'
    brightWhite'
    rgb'
This commit is contained in:
Simon Michael 2023-03-18 19:59:00 -10:00
parent 96b2cede0b
commit be8e64e498
4 changed files with 110 additions and 6 deletions

View File

@ -22,6 +22,11 @@ module Hledger.Utils.IO (
-- * Viewing with pager
pager,
-- * Terminal size
getTerminalHeightWidth,
getTerminalHeight,
getTerminalWidth,
-- * Command line arguments
progArgs,
outputFileOption,
@ -31,10 +36,31 @@ module Hledger.Utils.IO (
colorOption,
useColorOnStdout,
useColorOnStderr,
Color(..),
ColorIntensity(..),
color,
bgColor,
colorB,
bgColorB,
bold',
faint',
black',
red',
green',
yellow',
blue',
magenta',
cyan',
white',
brightBlack',
brightRed',
brightGreen',
brightYellow',
brightBlue',
brightMagenta',
brightCyan',
brightWhite',
rgb',
terminalIsLight,
terminalLightness,
terminalFgColor,
@ -73,10 +99,12 @@ import qualified Data.Text.Lazy.Builder as TB
import Data.Time.Clock (getCurrentTime)
import Data.Time.LocalTime
(LocalTime, ZonedTime, getCurrentTimeZone, utcToLocalTime, utcToZonedTime)
import Data.Word (Word16)
import Data.Word (Word8, Word16)
import Language.Haskell.TH.Syntax (Q, Exp)
import System.Console.ANSI
(Color,ColorIntensity,ConsoleLayer(..), SGR(..), hSupportsANSIColor, setSGRCode, getLayerColor)
import String.ANSI
import System.Console.ANSI (Color(..),ColorIntensity(..),
ConsoleLayer(..), SGR(..), hSupportsANSIColor, setSGRCode, getLayerColor)
import System.Console.Terminal.Size (Window (Window), size)
import System.Directory (getHomeDirectory)
import System.Environment (getArgs, lookupEnv)
import System.FilePath (isRelative, (</>))
@ -138,6 +166,19 @@ pager s = do
(if dumbterm then putStrLn else printOrPage . T.pack) s
#endif
-- | An alternative to ansi-terminal's getTerminalSize, based on
-- the more robust-looking terminal-size package.
-- Tries to get stdout's terminal's current height and width.
getTerminalHeightWidth :: IO (Maybe (Int,Int))
getTerminalHeightWidth = fmap (fmap unwindow) size
where unwindow (Window h w) = (h,w)
getTerminalHeight :: IO (Maybe Int)
getTerminalHeight = fmap fst <$> getTerminalHeightWidth
getTerminalWidth :: IO (Maybe Int)
getTerminalWidth = fmap snd <$> getTerminalHeightWidth
-- Command line arguments
-- | The command line arguments that were used at program startup.
@ -175,6 +216,67 @@ hasOutputFile = outputFileOption `notElem` [Nothing, Just "-"]
-- ANSI colour
ifAnsi f = if useColorOnStdout then f else id
-- | Versions of some of text-ansi's string colors/styles which are more careful
-- to not print junk onscreen. These use our useColorOnStdout.
bold' :: String -> String
bold' = ifAnsi bold
faint' :: String -> String
faint' = ifAnsi faint
black' :: String -> String
black' = ifAnsi black
red' :: String -> String
red' = ifAnsi red
green' :: String -> String
green' = ifAnsi green
yellow' :: String -> String
yellow' = ifAnsi yellow
blue' :: String -> String
blue' = ifAnsi blue
magenta' :: String -> String
magenta' = ifAnsi magenta
cyan' :: String -> String
cyan' = ifAnsi cyan
white' :: String -> String
white' = ifAnsi white
brightBlack' :: String -> String
brightBlack' = ifAnsi brightBlack
brightRed' :: String -> String
brightRed' = ifAnsi brightRed
brightGreen' :: String -> String
brightGreen' = ifAnsi brightGreen
brightYellow' :: String -> String
brightYellow' = ifAnsi brightYellow
brightBlue' :: String -> String
brightBlue' = ifAnsi brightBlue
brightMagenta' :: String -> String
brightMagenta' = ifAnsi brightMagenta
brightCyan' :: String -> String
brightCyan' = ifAnsi brightCyan
brightWhite' :: String -> String
brightWhite' = ifAnsi brightWhite
rgb' :: Word8 -> Word8 -> Word8 -> String -> String
rgb' r g b = ifAnsi (rgb r g b)
-- | Read the value of the --color or --colour command line option provided at program startup
-- using unsafePerformIO. If this option was not provided, returns the empty string.
colorOption :: String
@ -227,6 +329,9 @@ useColorOnHandle h = unsafePerformIO $ do
|| (coloroption `notElem` ["never","no"] && not no_color && supports_color)
-- | Wrap a string in ANSI codes to set and reset foreground colour.
-- ColorIntensity is @Dull@ or @Vivid@ (ie normal and bold).
-- Color is one of @Black@, @Red@, @Green@, @Yellow@, @Blue@, @Magenta@, @Cyan@, @White@.
-- Eg: @color Dull Red "text"@.
color :: ColorIntensity -> Color -> String -> String
color int col s = setSGRCode [SetColor Foreground int col] ++ s ++ setSGRCode []

View File

@ -67,6 +67,7 @@ dependencies:
- tasty >=1.2.3
- tasty-hunit >=0.10.0.2
- template-haskell
- terminal-size >=0.3.3
- text >=1.2
- text-ansi >=0.2.1
- time >=1.5

View File

@ -163,9 +163,6 @@ accent
highlightAddon = id
-- More careful version of bold
bold' = if useColorOnStdout then bold else id
-- | The commands list, showing command names, standard aliases,
-- and short descriptions. This is modified at runtime, as follows:
--

View File

@ -16,6 +16,7 @@ extra-deps:
# for hledger-lib:
- doctest-0.20.0
- ansi-terminal-0.11.4
- terminal-size-0.3.4
- text-ansi-0.2.1
- text-builder-0.6.7
- text-builder-dev-0.3.3.2