mirror of
https://github.com/simonmichael/hledger.git
synced 2024-09-20 02:37:12 +03:00
help: add --info/--man/--pager/--cat flags, & choose best one by default (#579)
You can select a docs format/viewer with one of the `--info`, `--man`, `--pager`, `--cat` flags. Otherwise, it will use info if available, otherwise man if available, otherwise $PAGER if defined, otherwise less if available, otherwise it prints on stdout (and always prints on stdout when piped). Preferring info over man might not suit everyone.
This commit is contained in:
parent
daa9550929
commit
9eb1520b6f
@ -25,6 +25,8 @@ module Hledger.Cli.CliOptions (
|
||||
argsFlag,
|
||||
showModeUsage,
|
||||
withAliases,
|
||||
likelyExecutablesInPath,
|
||||
hledgerExecutablesInPath,
|
||||
|
||||
-- * CLI options
|
||||
CliOpts(..),
|
||||
@ -633,23 +635,27 @@ dropRedundantSourceVersion fs = fs
|
||||
compiledExts = ["",".com",".exe"]
|
||||
|
||||
|
||||
-- | Get the sorted unique filenames of all hledger-* executables in
|
||||
-- the current user's PATH. Currently these are: files in any of the
|
||||
-- PATH directories, named hledger-*, with either no extension (and no
|
||||
-- periods in the name) or one of the addonExtensions. Limitations:
|
||||
-- we do not currently check that the file is really a file (not eg a
|
||||
-- directory) or whether it has execute permission.
|
||||
hledgerExecutablesInPath :: IO [String]
|
||||
hledgerExecutablesInPath = do
|
||||
-- | Get all sorted unique filenames in the current user's PATH.
|
||||
-- We do not currently filter out non-file objects or files without execute permission.
|
||||
likelyExecutablesInPath :: IO [String]
|
||||
likelyExecutablesInPath = do
|
||||
pathdirs <- splitOneOf "[:;]" `fmap` getEnvSafe "PATH"
|
||||
pathfiles <- concat `fmap` mapM getDirectoryContentsSafe pathdirs
|
||||
return $ nub $ sort $ filter isHledgerExeName pathfiles
|
||||
-- XXX should exclude directories and files without execute permission.
|
||||
return $ nub $ sort pathfiles
|
||||
-- exclude directories and files without execute permission.
|
||||
-- These will do a stat for each hledger-*, probably ok.
|
||||
-- But they need paths, not just filenames
|
||||
-- hledgerexes <- filterM doesFileExist hledgernamed
|
||||
-- hledgerexes' <- filterM isExecutable hledgerexes
|
||||
-- return hledgerexes
|
||||
-- exes' <- filterM doesFileExist exe'
|
||||
-- exes'' <- filterM isExecutable exes'
|
||||
-- return exes''
|
||||
|
||||
-- | Get the sorted unique filenames of all hledger-* executables in
|
||||
-- the current user's PATH. These are files in any of the PATH directories,
|
||||
-- named hledger-*, with either no extension (and no periods in the name)
|
||||
-- or one of the addonExtensions.
|
||||
-- We do not currently filter out non-file objects or files without execute permission.
|
||||
hledgerExecutablesInPath :: IO [String]
|
||||
hledgerExecutablesInPath = filter isHledgerExeName <$> likelyExecutablesInPath
|
||||
|
||||
-- isExecutable f = getPermissions f >>= (return . executable)
|
||||
|
||||
|
@ -16,6 +16,7 @@ module Hledger.Cli.DocFiles (
|
||||
,printHelpForTopic
|
||||
,runManForTopic
|
||||
,runInfoForTopic
|
||||
,runPagerForTopic
|
||||
|
||||
) where
|
||||
|
||||
@ -94,6 +95,15 @@ printHelpForTopic :: Topic -> IO ()
|
||||
printHelpForTopic t =
|
||||
putStrLn $ lookupDocTxt t
|
||||
|
||||
runPagerForTopic :: FilePath -> Topic -> IO ()
|
||||
runPagerForTopic exe t = do
|
||||
(Just inp, _, _, ph) <- createProcess (proc exe []){
|
||||
std_in=CreatePipe
|
||||
}
|
||||
hPutStrLn inp (lookupDocTxt t)
|
||||
_ <- waitForProcess ph
|
||||
return ()
|
||||
|
||||
runManForTopic :: Topic -> IO ()
|
||||
runManForTopic t =
|
||||
withSystemTempFile ("hledger-"++t++".nroff") $ \f h -> do
|
||||
|
@ -3,6 +3,8 @@
|
||||
The help command.
|
||||
|
||||
|-}
|
||||
--TODO rename manuals
|
||||
--TODO substring matching
|
||||
|
||||
module Hledger.Cli.Help (
|
||||
|
||||
@ -14,29 +16,57 @@ module Hledger.Cli.Help (
|
||||
import Prelude ()
|
||||
import Prelude.Compat
|
||||
import Data.List
|
||||
import Data.Maybe
|
||||
import System.Console.CmdArgs.Explicit
|
||||
import System.Environment
|
||||
import System.IO
|
||||
|
||||
import Hledger.Data.RawOptions
|
||||
import Hledger.Cli.CliOptions
|
||||
import Hledger.Cli.DocFiles
|
||||
--import Hledger.Utils.Debug
|
||||
|
||||
helpmode = (defCommandMode $ ["help"] ++ aliases) {
|
||||
modeHelp = "show any of the hledger manuals" `withAliases` aliases
|
||||
modeHelp = "show any of the hledger manuals, as plain text. With no argument, list the manuals." `withAliases` aliases
|
||||
,modeGroupFlags = Group {
|
||||
groupUnnamed = []
|
||||
groupUnnamed = [
|
||||
flagNone ["info"] (setboolopt "info") "show the manual with info"
|
||||
,flagNone ["man"] (setboolopt "man") "show the manual with man"
|
||||
,flagNone ["pager"] (setboolopt "pager") "show the manual with $PAGER or less"
|
||||
,flagNone ["cat"] (setboolopt "cat") "show the manual on stdout"
|
||||
,flagNone ["help","h"] (setboolopt "help") "show this help"
|
||||
]
|
||||
,groupHidden = []
|
||||
,groupNamed = []
|
||||
}
|
||||
}
|
||||
,modeArgs = ([], Just $ argsFlag "[MANUAL]")
|
||||
}
|
||||
where aliases = []
|
||||
|
||||
-- | Print detailed help on various topics.
|
||||
-- | List or display one of the hledger manuals in various formats.
|
||||
-- You can select a docs viewer with one of the `--info`, `--man`, `--pager`, `--cat` flags.
|
||||
-- Otherwise it will use the first available of: info, man, $PAGER, less, stdout
|
||||
-- (and always stdout if output is non-interactive).
|
||||
help' :: CliOpts -> IO ()
|
||||
help' opts = do
|
||||
let args = listofstringopt "args" $ rawopts_ opts
|
||||
exes <- likelyExecutablesInPath
|
||||
pagerprog <- fromMaybe "less" <$> lookupEnv "PAGER"
|
||||
interactive <- hIsTerminalDevice stdout
|
||||
let
|
||||
args = take 1 $ listofstringopt "args" $ rawopts_ opts
|
||||
[info, man, pager, cat] =
|
||||
[runInfoForTopic, runManForTopic, runPagerForTopic pagerprog, printHelpForTopic]
|
||||
viewer
|
||||
| boolopt "info" $ rawopts_ opts = info
|
||||
| boolopt "man" $ rawopts_ opts = man
|
||||
| boolopt "pager" $ rawopts_ opts = pager
|
||||
| boolopt "cat" $ rawopts_ opts = cat
|
||||
| not interactive = cat
|
||||
| "info" `elem` exes = info
|
||||
| "man" `elem` exes = man
|
||||
| pagerprog `elem` exes = pager
|
||||
| otherwise = cat
|
||||
case args of
|
||||
[] -> putStrLn $
|
||||
"Choose a topic, eg: hledger help cli\n" ++
|
||||
intercalate ", " docTopics
|
||||
topic:_ -> printHelpForTopic topic
|
||||
[t] -> viewer t
|
||||
_ -> putStrLn $ "Please choose a manual:\nhledger help " ++ intercalate "|" docTopics
|
||||
|
||||
|
@ -128,10 +128,7 @@ PROGNAME CMD [--] [OPTS] [ARGS] run a command (use -- with addon commands)
|
||||
PROGNAME-CMD [OPTS] [ARGS] or run addon commands directly
|
||||
PROGNAME -h show general usage
|
||||
PROGNAME CMD -h show command usage
|
||||
PROGNAME help list available manuals
|
||||
PROGNAME help MANUAL show a manual as plain text
|
||||
PROGNAME man MANUAL show a manual as man page
|
||||
PROGNAME info MANUAL show a manual as info manual
|
||||
PROGNAME help [MANUAL] show any of the hledger manuals in various formats
|
||||
|]
|
||||
}
|
||||
|
||||
@ -263,7 +260,7 @@ OTHERCMDS
|
||||
Help:
|
||||
hledger -h show general usage
|
||||
hledger CMD -h show command usage
|
||||
help|man|info show any of the hledger manuals in plain text/man/info format
|
||||
help show any of the hledger manuals in various formats
|
||||
|]
|
||||
|
||||
knownCommands :: [String]
|
||||
|
@ -304,18 +304,18 @@ you can alter the report mode with `--change`/`--cumulative`/`--historical`.
|
||||
## help
|
||||
Show any of the hledger manuals.
|
||||
|
||||
The `help` command displays any of the main [hledger man pages](/docs.html).
|
||||
(Unlike `hledger --help`, which displays only the hledger man page.)
|
||||
Run it with no arguments to list available topics (their names are shortened for easier typing),
|
||||
and run `hledger help TOPIC` to select one.
|
||||
The output is similar to a man page, but fixed width.
|
||||
It may be long, so you may wish to pipe it into a pager.
|
||||
See also [info](#info) and [man](#man).
|
||||
The `help` command displays any of the main [hledger manuals](/docs.html), in one of several ways.
|
||||
Run it with no argument to list the manuals (their names are shortened for easier typing),
|
||||
and run `hledger help MANUAL` to select one.
|
||||
|
||||
hledger help will choose one of these docs viewers, in order of preference:
|
||||
info, man, $PAGER, less, stdout (and it always prints on stdout when piped).
|
||||
Or you can force a particular viewer with the `--info`, `--man`, `--pager`, `--cat` flags.
|
||||
|
||||
_shell_({{
|
||||
$ hledger help
|
||||
Choose a topic, eg: hledger help cli
|
||||
cli, ui, web, api, journal, csv, timeclock, timedot
|
||||
Please choose a manual:
|
||||
hledger help cli|ui|web|api|journal|csv|timeclock|timedot
|
||||
}})
|
||||
|
||||
_shell_({{
|
||||
@ -329,9 +329,7 @@ NAME
|
||||
hledger - a command-line accounting tool
|
||||
|
||||
SYNOPSIS
|
||||
hledger [-f FILE] COMMAND [OPTIONS] [CMDARGS]
|
||||
hledger [-f FILE] ADDONCMD -- [OPTIONS] [CMDARGS]
|
||||
:
|
||||
hledger [-f FILE] COMMAND [OPTIONS] [ARGS]
|
||||
}})
|
||||
|
||||
## incomestatement
|
||||
@ -404,6 +402,7 @@ Normally incomestatement shows revenues/expenses per period, though
|
||||
as with [multicolumn balance reports](#multicolumn-balance-reports)
|
||||
you can alter the report mode with `--change`/`--cumulative`/`--historical`.
|
||||
|
||||
...
|
||||
## info
|
||||
Show any of the hledger manuals using info.
|
||||
|
||||
@ -423,6 +422,7 @@ This will fit the text to your terminal width, and probably invoke a pager autom
|
||||
It requires the "man" program to be available in your PATH.
|
||||
|
||||
As with [help](#help), run it with no arguments to list available topics (manuals).
|
||||
```
|
||||
|
||||
## print
|
||||
Show transactions from the journal.
|
||||
|
Loading…
Reference in New Issue
Block a user