feat: use a pager for all large terminal output, not just for help

This commit is contained in:
Simon Michael 2024-10-17 19:32:58 -10:00
parent a758eb0b5a
commit 3b7420b97c
3 changed files with 23 additions and 24 deletions

View File

@ -171,12 +171,12 @@ pprint' = pPrintOpt NoCheckColorTty prettyoptsNoColor
-- "Avoid using pshow, pprint, dbg* in the code below to prevent infinite loops." (?)
-- | 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"
-- (except on Windows, where a pager will not be used).
-- than the current terminal and stdout is interactive and TERM is not "dumb";
-- except on Windows, where currently we don't attempt to use a pager.
-- 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.
-- We call "setupPager" at hledger startup to make that less likely.
pager :: String -> IO ()
#ifdef mingw32_HOST_OS
pager = putStrLn

View File

@ -123,13 +123,14 @@ writeOutput opts s = do
f <- outputFileFromOpts opts
(maybe putStr writeFile f) s
-- | Write some output to stdout or to a file selected by --output-file.
-- If the file exists it will be overwritten. This function operates on Lazy
-- Text values.
-- | Write some output, to a file specified by --output-file if any,
-- otherwise to stdout.
-- If writing to a file and the file exists, it will be overwritten.
-- If writing to stdout, a pager is used when appropriate and possible.
writeOutputLazyText :: CliOpts -> TL.Text -> IO ()
writeOutputLazyText opts s = do
f <- outputFileFromOpts opts
(maybe TL.putStr TL.writeFile f) s
maybe (pager.TL.unpack) TL.writeFile f s
-- -- | Get a journal from the given string and options, or throw an error.
-- readJournal :: CliOpts -> String -> IO Journal

View File

@ -721,6 +721,21 @@ The `-O` option can be combined with `-o` to override the file extension if need
$ hledger balancesheet -o foo.txt -O csv # write CSV to foo.txt
```
## Paging
On unix-like systems, when displaying large output in the terminal,
hledger tries to use a pager when appropriate:
the one specified by the `PAGER` environment variable,
otherwise `less` if available, otherwise `more` if available.
The pager shows one page of text at a time, and lets you scroll around to see more.
While it is active, usually `SPACE` shows the next page, `q` quits, and `?` shows more features.
The pager is expected to display ANSI color and text styling if possible.
hledger adds `R` to the `LESS` and `MORE` environment variables to enable this
in `less` (and in its `more` compatibility mode).
If you use a different pager, you might need to configure it similarly, to avoid seeing junk on screen.
Or you can set the `NO_COLOR` environment variable described below.
Here are some notes about the various output formats.
### Text output
@ -906,23 +921,6 @@ the [commodity directive](#commodity-directive).
In some cases hledger will adjust number formatting to improve their parseability
(such as adding [trailing decimal marks](#trailing-decimal-marks) when needed).
## Paging
When showing long output in the terminal, hledger will try to use
the pager specified by the `PAGER` environment variable, or `less`, or `more`.
(A pager is a helper program that shows one page at a time rather than scrolling everything off screen).
Currently it does this only for help output, not for reports; specifically,
- when listing commands, with `hledger`
- when showing help with `hledger [CMD] --help`,
- when viewing manuals with `hledger help` or `hledger --man`.
Note the pager is expected to handle ANSI codes, which hledger uses eg for bold emphasis.
For the common pager `less` (and its `more` compatibility mode),
we add `R` to the `LESS` and `MORE` environment variables to make this work.
If you use a different pager, you might need to configure it similarly, to avoid seeing junk on screen (let us know).
Otherwise, you can set the `NO_COLOR` environment variable to 1 to disable all ANSI output (see [Colour](#colour)).
## Debug output
We intend hledger to be relatively easy to troubleshoot, introspect and develop.