HORIZON HASKELLDocslts/ghc-10.0.x8c2f8e82026-10-19Search names, modules, packages, or :: a typeCtrl K

GHC 10.0.0.20260917 · lts/ghc-10.0.x · 8c2f8e8 · 2026-10-19

Modulehledger-lib-1.52.4GHC2021

Hledger.Utils.IO

General and hledger-specific input/output-related helpers for pretty-printing haskell values, error reporting, time, files, command line parsing, terminals, pager output, ANSI colour/styles, etc.

  • 1 type
  • 74 values

Pretty showing/printing

4 declarations
valuepshow :: Show a => a -> String
#

Pretty show. An easier alias for pretty-simple's pShow. This will probably show in colour if useColorOnStderrUnsafe is true.

valuepshow' :: Show a => a -> String
#

Monochrome version of pshow. This will never show in colour.

valuepprint :: Show a => a -> IO ()
#

Pretty print a showable value. An easier alias for pretty-simple's pPrint. This will print in colour if useColorOnStderrUnsafe is true.

valuepprint' :: Show a => a -> IO ()
#

Monochrome version of pprint. This will never print in colour.

Errors

9 declarations
valueerror' :: String -> a
#

Call errorWithoutStackTrace, prepending a "Error:" label.

valuewarn :: String -> a -> a
#

Show a warning message on stderr before returning the given value. Like trace, but prepends a "Warning:" label, and does some ANSI styling of the first line when allowed (using unsafe IO). Currently we use this very sparingly in hledger; we prefer to either quietly work, or loudly raise an error. Varying output can make scripting harder. But on stderr, it shouldn't cause much hassle.

valuewarnIO :: MonadIO m => String -> m ()
#

Like warn, but take extra care to sequence properly in IO.

valueprintError :: String -> IO ()
#

Print an error message to stderr, with a consistent "programname: " prefix, and applying ANSI styling (bold bright red) to the first line if that is supported and allowed.

valuehandleExit :: IO () -> IO ()
#

This wraps a program's main routine so as to display more consistent, useful, and GHC-version-independent error output when the program exits because of certain common exceptions. It

  1. disables SIGPIPE errors, which are usually harmless, caused when our output is truncated in a piped command.

  2. catches these common exceptions:

  • UnicodeException, caused eg by text decoding errors in pure code

  • IOException, caused by IO errors, including text decoding errors during IO

  • ErrorCall - error / errorWithoutStackTrace calls

  1. compensates for GHC output bugs:

  • removes the trailing newlines added by some GHC 9.10.* versions

  • removes "uncaught exception" output added by some GHC 9.12.* versions

  • ensures a consistent "PROGNAME: " prefix

  1. applies bold bright red ANSI styling to the first line of error output, if that is supported and allowed

  2. for unicode exceptions and I/O exceptions which look like they were unicode-related, it adds a message (in english) explaining the problem and what to do.

Some exceptions this does not catch are ExitCode (exitSuccessexitFailureexitWith) and UserInterrupt (control-C).

Time

2 declarations

Files

14 declarations
valuegetHomeSafe :: IO (Maybe FilePath)
#

Like getHomeDirectory, but in case of IO error (home directory not found, not understood, etc.), returns "".

Expand a single tilde (representing home directory) at the start of a file path. ~username is not supported. This can raise an IO error.

Given a current directory, convert a possibly relative, possibly tilde-prefixed file path to an absolute one. ~username is not supported. If the file path is "-", it is left as-is. This can an raise an IO error.

valueexpandGlob :: FilePath -> FilePath -> IO [FilePath]
#

Like expandPath, but treats the expanded path as a glob, and returns zero or more matched absolute file paths, alphabetically sorted. Can raise an error. For a more elaborate glob expander, see findMatchedFiles (used by the include directive).

Like expandPath, but if the path contains glob metacharacters (* ? [ {), treats it as a glob pattern and expands it, returning the first match. Raises an error if the glob pattern matches no files. If the path contains no glob metacharacters, just expands ~ and returns the path, even if the file doesn't exist yet. This is useful for options like -f and LEDGER_FILE that should: - accept non-existent files (for commands like add/import that create them) - expand glob patterns and error if they don't match anything

Open a file for reading, using the standard System.IO.openFile. This opens the handle in text mode, using the initial system locale's text encoding.

Read text from a file, converting any rn line endings to n,, using the system locale's text encoding, ignoring any utf8 BOM prefix (as seen in paypal's 2018 CSV, eg) if that encoding is utf8.

Read text from a handle, perhaps using a specified encoding from the encoding package. Or if no encoding is specified, using the handle's current encoding, changing it to UTF-8BOM if it was UTF-8, to ignore any Byte Order Mark at the start. Also it converts Windows line endings to newlines. If decoding fails, this throws an IOException (or possibly a UnicodeException or something else from the encoding package).

valuetextToHandle :: Text -> IO Handle
#

Create a handle from which the given text can be read. Its encoding will be UTF-8.

Command line parsing

6 declarations
valueprogArgs :: [String]
#

The program's command line arguments. Uses unsafePerformIO; tends to stick in GHCI until reloaded, and may or may not detect args provided by a hledger config file.

valuegetFlag :: [String] -> IO Bool
#

Given one or more long or short flag names, report whether this flag is present in the command line. Concatenated short flags (-a -b written as -ab) are not supported.

valuegetOpt :: [String] -> IO (Maybe String)
#

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. Concatenated short flags (-a -b written as -ab) are not supported.

datadata YNA
#
Instances2Eq, Show
  • Eq YNADefined in hledger-lib-1.52.4 · Hledger.Utils.IO
  • Show YNADefined in hledger-lib-1.52.4 · Hledger.Utils.IO

Terminal size

3 declarations

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.

Pager output

4 declarations
valuefindPager :: IO (Maybe String)
#

Try to find a pager executable robustly, safely handling various error conditions like an unset PATH var or the specified pager not being found as an executable. The pager can be specified by a path or program name in the PAGER environment variable. If that is unset or has a problem, "less" is tried, then "more". If successful, the pager's path or program name is returned.

valuerunPager :: String -> IO ()
#

Display the given text on the terminal, trying to use a pager ($PAGER, less, or more) when appropriate (see maybePagerFor), otherwise printing to standard output. Also, if the pager is less, we modify the LESS environment variable (see lessVarValue) and check for problems which could cause confusing output (see lessIsWorking).

Compute the LESS environment variable value that hledger will use for the less pager. This used in runPager when invoking less, and also in the setup command for display. It takes the current HLEDGER_LESS and LESS env var values, and whether we are showing colour on stdout, and returns the adjusted LESS value that should be used. Specifically:

  • If HLEDGER_LESS is defined, we use it in place of the LESS environment variable.

  • Otherwise, if LESS is defined, append some preferred options (lessOptions and maybe lessColourOptions) to it.

  • Otherwise, we set LESS to just use those preferred options.

valuelessIsWorking :: Maybe [(String, String)] -> IO Bool
#

Test less, by running less --version and looking for a nonzero exit, timeout, or stderr output. Uses the provided environment, containing a LESS variable, if any. We do this because various LESS settings can cause some less versions to fail or cause confusing output without failing.

ANSI colour/styles

0 declarations

hledger-specific

valuecolorOption :: IO YNA
#

Get the value of the rightmost --color or --colour option from the program's command line arguments. Throws an error if the option's value could not be parsed.

Should ANSI color and styles be used for standard output ? Considers useColorOnHandle stdout and hasOutputFile.

Should ANSI color and styles be used for standard error output ? Considers useColorOnHandle stderr; is not affected by an --output-file option.

Like useColorOnStdout, but using unsafePerformIO. Useful eg for low-level debug code. Sticky in GHCI until reloaded, may not always be affected by --color in a hledger config file, etc.

valuebold' :: String -> String
#

Set various ANSI styles/colours in a string, only if useColorOnStdoutUnsafe says we should.

Generic

valuecolor :: ColorIntensity -> Color -> String -> String
#

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".

Detect whether the terminal currently has a light background colour, if possible, using unsafePerformIO. If the terminal is transparent, its apparent light/darkness may be different.

Detect the terminal's current background lightness (0..1), if possible, using unsafePerformIO. If the terminal is transparent, its apparent lightness may be different.