cli, ui, web, api: --info, --man, info & man cmds

This commit is contained in:
Simon Michael 2016-04-19 14:40:58 -07:00
parent 1fc34d76f8
commit 42c12fe631
25 changed files with 661 additions and 341 deletions

View File

@ -74,12 +74,22 @@ show usage
.RE .RE
.TP .TP
.B \f[C]\-\-help\f[] .B \f[C]\-\-help\f[]
show detailed help show manual
.RS
.RE
.TP
.B \f[C]\-\-man\f[]
show manual with man
.RS
.RE
.TP
.B \f[C]\-\-info\f[]
show manual with info
.RS .RS
.RE .RE
.TP .TP
.B \f[C]\-\-version\f[] .B \f[C]\-\-version\f[]
show version information show version
.RS .RS
.RE .RE
.SH ENVIRONMENT .SH ENVIRONMENT

View File

@ -66,10 +66,16 @@ Note: if invoking hledger-api as a hledger subcommand, write `--` before options
: show usage : show usage
`--help` `--help`
: show detailed help : show manual
`--man`
: show manual with man
`--info`
: show manual with info
`--version` `--version`
: show version information : show version
_man_({{ _man_({{

View File

@ -52,10 +52,14 @@ OOPPTTIIOONNSS
--hh show usage --hh show usage
----hheellpp show detailed help ----hheellpp show manual
----mmaann show manual with man
----iinnffoo show manual with info
----vveerrssiioonn ----vveerrssiioonn
show version information show version
EENNVVIIRROONNMMEENNTT EENNVVIIRROONNMMEENNTT
LLEEDDGGEERR__FFIILLEE sets the default journal file path. If not set, it is LLEEDDGGEERR__FFIILLEE sets the default journal file path. If not set, it is

View File

@ -48,7 +48,7 @@ Usage:
hledger-api --swagger hledger-api --swagger
print API docs in Swagger 2.0 format print API docs in Swagger 2.0 format
hledger-api --version hledger-api --version
hledger-api --help hledger-api -h|--help|--info
Options: Options:
-f --file FILE use a different input file -f --file FILE use a different input file
@ -58,7 +58,9 @@ Options:
-p --port PORT use a different TCP port (default: 8001) -p --port PORT use a different TCP port (default: 8001)
--version show version --version show version
-h show usage -h show usage
--help show detailed help --help show manual
--man show manual with man
--info show manual with info
|] |]
swaggerSpec :: Swagger swaggerSpec :: Swagger
@ -72,7 +74,9 @@ main :: IO ()
main = do main = do
args <- getArgs >>= parseArgsOrExit doc args <- getArgs >>= parseArgsOrExit doc
when (isPresent args (shortOption 'h')) $ exitWithUsage doc when (isPresent args (shortOption 'h')) $ exitWithUsage doc
when (isPresent args (longOption "help")) $ putStr (lookupDocTxt "api") >> exitSuccess when (isPresent args (longOption "help")) $ printHelpForTopic "api" >> exitSuccess
when (isPresent args (longOption "man")) $ runManForTopic "api" >> exitSuccess
when (isPresent args (longOption "info")) $ runInfoForTopic "api" >> exitSuccess
when (isPresent args (longOption "version")) $ putStrLn hledgerApiVersion >> exitSuccess when (isPresent args (longOption "version")) $ putStrLn hledgerApiVersion >> exitSuccess
when (isPresent args (longOption "swagger")) $ BL8.putStrLn (encode swaggerSpec) >> exitSuccess when (isPresent args (longOption "swagger")) $ BL8.putStrLn (encode swaggerSpec) >> exitSuccess
let defp = "8001" let defp = "8001"

View File

@ -42,9 +42,10 @@ main = do
run opts run opts
where where
run opts run opts
| "shorthelp" `inRawOpts` (rawopts_ $ cliopts_ opts) = putStr (showModeUsage uimode) >> exitSuccess | "h" `inRawOpts` (rawopts_ $ cliopts_ opts) = putStr (showModeUsage uimode) >> exitSuccess
| "longhelp" `inRawOpts` (rawopts_ $ cliopts_ opts) = putStr (showModeHelp uimode) >> exitSuccess | "help" `inRawOpts` (rawopts_ $ cliopts_ opts) = printHelpForTopic (topicForMode uimode) >> exitSuccess
| "version" `inRawOpts` (rawopts_ $ cliopts_ opts) = putStrLn prognameandversion >> exitSuccess | "info" `inRawOpts` (rawopts_ $ cliopts_ opts) = runInfoForTopic (topicForMode uimode) >> exitSuccess
| "version" `inRawOpts` (rawopts_ $ cliopts_ opts) = putStrLn prognameandversion >> exitSuccess
| "binary-filename" `inRawOpts` (rawopts_ $ cliopts_ opts) = putStrLn (binaryfilename progname) | "binary-filename" `inRawOpts` (rawopts_ $ cliopts_ opts) = putStrLn (binaryfilename progname)
| otherwise = withJournalDoUICommand opts runBrickUi | otherwise = withJournalDoUICommand opts runBrickUi

View File

@ -75,12 +75,22 @@ show usage
.RE .RE
.TP .TP
.B \f[C]\-\-help\f[] .B \f[C]\-\-help\f[]
show detailed help show manual
.RS
.RE
.TP
.B \f[C]\-\-man\f[]
show manual with man
.RS
.RE
.TP
.B \f[C]\-\-info\f[]
show manual with info
.RS .RS
.RE .RE
.TP .TP
.B \f[C]\-\-version\f[] .B \f[C]\-\-version\f[]
show version information show version
.RS .RS
.RE .RE
.SS hledger options .SS hledger options

View File

@ -78,10 +78,16 @@ Any QUERYARGS are interpreted as a hledger search query which filters the data.
: show usage : show usage
`--help` `--help`
: show detailed help : show manual
`--man`
: show manual with man
`--info`
: show manual with info
`--version` `--version`
: show version information : show version
## hledger options ## hledger options

View File

@ -56,10 +56,14 @@ OOPPTTIIOONNSS
--hh show usage --hh show usage
----hheellpp show detailed help ----hheellpp show manual
----mmaann show manual with man
----iinnffoo show manual with info
----vveerrssiioonn ----vveerrssiioonn
show version information show version
hhlleeddggeerr ooppttiioonnss hhlleeddggeerr ooppttiioonnss
The following common hledger options should also work: The following common hledger options should also work:

View File

@ -43,9 +43,11 @@ hledgerWebMain = do
runWith :: WebOpts -> IO () runWith :: WebOpts -> IO ()
runWith opts runWith opts
| "shorthelp" `inRawOpts` (rawopts_ $ cliopts_ opts) = putStr (showModeUsage webmode) >> exitSuccess | "h" `inRawOpts` (rawopts_ $ cliopts_ opts) = putStr (showModeUsage webmode) >> exitSuccess
| "longhelp" `inRawOpts` (rawopts_ $ cliopts_ opts) = putStr (showModeHelp webmode) >> exitSuccess | "help" `inRawOpts` (rawopts_ $ cliopts_ opts) = printHelpForTopic (topicForMode webmode) >> exitSuccess
| "version" `inRawOpts` (rawopts_ $ cliopts_ opts) = putStrLn prognameandversion >> exitSuccess | "man" `inRawOpts` (rawopts_ $ cliopts_ opts) = runManForTopic (topicForMode webmode) >> exitSuccess
| "info" `inRawOpts` (rawopts_ $ cliopts_ opts) = runInfoForTopic (topicForMode webmode) >> exitSuccess
| "version" `inRawOpts` (rawopts_ $ cliopts_ opts) = putStrLn prognameandversion >> exitSuccess
| "binary-filename" `inRawOpts` (rawopts_ $ cliopts_ opts) = putStrLn (binaryfilename progname) | "binary-filename" `inRawOpts` (rawopts_ $ cliopts_ opts) = putStrLn (binaryfilename progname)
| otherwise = do | otherwise = do
requireJournalFileExists =<< (head `fmap` journalFilePathFromOpts (cliopts_ opts)) -- XXX head should be safe for now requireJournalFileExists =<< (head `fmap` journalFilePathFromOpts (cliopts_ opts)) -- XXX head should be safe for now

View File

@ -114,12 +114,22 @@ show usage
.RE .RE
.TP .TP
.B \f[C]\-\-help\f[] .B \f[C]\-\-help\f[]
show detailed help show manual
.RS
.RE
.TP
.B \f[C]\-\-man\f[]
show manual with man
.RS
.RE
.TP
.B \f[C]\-\-info\f[]
show manual with info
.RS .RS
.RE .RE
.TP .TP
.B \f[C]\-\-version\f[] .B \f[C]\-\-version\f[]
show version information show version
.RS .RS
.RE .RE
.SS hledger options .SS hledger options

View File

@ -121,10 +121,16 @@ serve them from another server for efficiency, you would set the url with this.
: show usage : show usage
`--help` `--help`
: show detailed help : show manual
`--man`
: show manual with man
`--info`
: show manual with info
`--version` `--version`
: show version information : show version
## hledger options ## hledger options

View File

@ -90,10 +90,14 @@ OOPPTTIIOONNSS
--hh show usage --hh show usage
----hheellpp show detailed help ----hheellpp show manual
----mmaann show manual with man
----iinnffoo show manual with info
----vveerrssiioonn ----vveerrssiioonn
show version information show version
hhlleeddggeerr ooppttiioonnss hhlleeddggeerr ooppttiioonnss
The following common hledger options should also work: The following common hledger options should also work:

View File

@ -16,6 +16,8 @@ module Hledger.Cli (
module Hledger.Cli.Help, module Hledger.Cli.Help,
module Hledger.Cli.Histogram, module Hledger.Cli.Histogram,
module Hledger.Cli.Incomestatement, module Hledger.Cli.Incomestatement,
module Hledger.Cli.Info,
module Hledger.Cli.Man,
module Hledger.Cli.Print, module Hledger.Cli.Print,
module Hledger.Cli.Register, module Hledger.Cli.Register,
module Hledger.Cli.Stats, module Hledger.Cli.Stats,
@ -41,6 +43,8 @@ import Hledger.Cli.Cashflow
import Hledger.Cli.Histogram import Hledger.Cli.Histogram
import Hledger.Cli.Help import Hledger.Cli.Help
import Hledger.Cli.Incomestatement import Hledger.Cli.Incomestatement
import Hledger.Cli.Info
import Hledger.Cli.Man
import Hledger.Cli.Print import Hledger.Cli.Print
import Hledger.Cli.Register import Hledger.Cli.Register
import Hledger.Cli.Stats import Hledger.Cli.Stats

View File

@ -22,7 +22,6 @@ module Hledger.Cli.CliOptions (
defAddonCommandMode, defAddonCommandMode,
argsFlag, argsFlag,
showModeUsage, showModeUsage,
showModeHelp,
withAliases, withAliases,
-- * CLI options -- * CLI options
@ -54,6 +53,7 @@ module Hledger.Cli.CliOptions (
-- * Other utils -- * Other utils
hledgerAddons, hledgerAddons,
topicForMode,
-- * Tests -- * Tests
tests_Hledger_Cli_CliOptions tests_Hledger_Cli_CliOptions
@ -95,8 +95,10 @@ import Hledger.Cli.Version
-- | Common help flags: --help, --debug, --version... -- | Common help flags: --help, --debug, --version...
helpflags :: [Flag RawOpts] helpflags :: [Flag RawOpts]
helpflags = [ helpflags = [
flagNone ["h"] (setboolopt "shorthelp") "show general usage or (after command) command usage" flagNone ["h"] (setboolopt "h") "show general usage or (after command) command usage"
,flagNone ["help"] (setboolopt "longhelp") "show detailed help" ,flagNone ["help"] (setboolopt "help") "show manual"
,flagNone ["man"] (setboolopt "man") "show manual with man"
,flagNone ["info"] (setboolopt "info") "show manual with info"
-- ,flagNone ["browse-args"] (setboolopt "browse-args") "use a web UI to select options and build up a command line" -- ,flagNone ["browse-args"] (setboolopt "browse-args") "use a web UI to select options and build up a command line"
,flagReq ["debug"] (\s opts -> Right $ setopt "debug" s opts) "N" "show increasing amounts of debug output if N is 1-9. With no argument, show level 1" ,flagReq ["debug"] (\s opts -> Right $ setopt "debug" s opts) "N" "show increasing amounts of debug output if N is 1-9. With no argument, show level 1"
,flagNone ["version"] (setboolopt "version") "show version information" ,flagNone ["version"] (setboolopt "version") "show version information"
@ -169,7 +171,7 @@ defMode = Mode {
,modeGroupFlags = Group { ,modeGroupFlags = Group {
groupNamed = [] groupNamed = []
,groupUnnamed = [ ,groupUnnamed = [
flagNone ["h"] (setboolopt "shorthelp") "Show command help." flagNone ["h"] (setboolopt "h") "Show command usage."
] ]
,groupHidden = [] ,groupHidden = []
} }
@ -230,15 +232,15 @@ showModeUsage :: Mode a -> String
showModeUsage = (showText defaultWrap :: [Text] -> String) . showModeUsage = (showText defaultWrap :: [Text] -> String) .
(helpText [] HelpFormatDefault :: Mode a -> [Text]) (helpText [] HelpFormatDefault :: Mode a -> [Text])
-- | Get a mode's long help, ready for console output. Currently that -- | Get the most appropriate documentation topic for a mode.
-- will be the hledger, hledger-ui, hledger-web or hledger-api man page, -- Currently, that is either the hledger, hledger-ui, hledger-web or
-- formatted for 80 columns. -- hledger-api manual.
showModeHelp :: Mode a -> String topicForMode :: Mode a -> Topic
showModeHelp m topicForMode m
| n == "hledger-ui" = lookupDocTxt "ui" | n == "hledger-ui" = "ui"
| n == "hledger-web" = lookupDocTxt "web" | n == "hledger-web" = "web"
-- | n == "hledger-api" = lookupDocTxt "api" -- hledger-api uses docopt -- | n == "hledger-api" = lookupDocTxt "api" -- hledger-api uses docopt
| otherwise = lookupDocTxt "cli" | otherwise = "cli"
where n = headDef "" $ modeNames m where n = headDef "" $ modeNames m
-- | Add command aliases to the command's help string. -- | Add command aliases to the command's help string.
@ -362,8 +364,8 @@ getCliOpts mode' = do
opts <- rawOptsToCliOpts rawopts opts <- rawOptsToCliOpts rawopts
debugArgs args' opts debugArgs args' opts
-- if any (`elem` args) ["--help","-h","-?"] -- if any (`elem` args) ["--help","-h","-?"]
when ("shorthelp" `inRawOpts` rawopts_ opts) $ putStr (showModeUsage mode') >> exitSuccess when ("h" `inRawOpts` rawopts_ opts) $ putStr (showModeUsage mode') >> exitSuccess
when ("longhelp" `inRawOpts` rawopts_ opts) $ putStr (showModeHelp mode') >> exitSuccess when ("help" `inRawOpts` rawopts_ opts) $ printHelpForTopic (topicForMode mode') >> exitSuccess
return opts return opts
where where
-- | Print debug info about arguments and options if --debug is present. -- | Print debug info about arguments and options if --debug is present.

View File

@ -1,16 +1,21 @@
{-# LANGUAGE TemplateHaskell, OverloadedStrings #-} {-# LANGUAGE TemplateHaskell, OverloadedStrings #-}
{-| {-|
Embedded help files (man pages). Embedded documentation files in various formats, and helpers for viewing them.
|-} |-}
module Hledger.Cli.DocFiles ( module Hledger.Cli.DocFiles (
docFiles Topic
,docFiles
,docTopics ,docTopics
,lookupDocNroff ,lookupDocNroff
,lookupDocTxt ,lookupDocTxt
,lookupDocInfo
,printHelpForTopic
,runManForTopic
,runInfoForTopic
) where ) where
@ -18,46 +23,90 @@ import Prelude ()
import Prelude.Compat import Prelude.Compat
import Data.FileEmbed import Data.FileEmbed
import Data.String import Data.String
import System.IO
import System.IO.Temp
import System.Process
import Hledger.Utils (first3, second3, third3)
type Topic = String type Topic = String
-- XXX assumes cwd is the hledger package directory, for now ghci must be run from there -- XXX assumes cwd is the hledger package directory, for now ghci must be run from there
docFiles :: IsString a => [(Topic, (a, a))] docFiles :: IsString a => [(Topic, (a, a, a))]
docFiles = [ docFiles = [
("cli", ("cli",
($(embedStringFile $ "../hledger/doc/hledger.1"), ($(embedStringFile $ "../hledger/doc/hledger.1")
$(embedStringFile $ "../hledger/doc/hledger.1.txt"))) ,$(embedStringFile $ "../hledger/doc/hledger.1.txt")
,$(embedStringFile $ "../hledger/doc/hledger.1.info")
))
,("ui", ,("ui",
($(embedStringFile $ "../hledger-ui/doc/hledger-ui.1"), ($(embedStringFile $ "../hledger-ui/doc/hledger-ui.1")
$(embedStringFile $ "../hledger-ui/doc/hledger-ui.1.txt"))) ,$(embedStringFile $ "../hledger-ui/doc/hledger-ui.1.txt")
,$(embedStringFile $ "../hledger-ui/doc/hledger-ui.1.info")
))
,("web", ,("web",
($(embedStringFile $ "../hledger-web/doc/hledger-web.1"), ($(embedStringFile $ "../hledger-web/doc/hledger-web.1")
$(embedStringFile $ "../hledger-web/doc/hledger-web.1.txt"))) ,$(embedStringFile $ "../hledger-web/doc/hledger-web.1.txt")
,$(embedStringFile $ "../hledger-web/doc/hledger-web.1.info")
))
,("api", ,("api",
($(embedStringFile $ "../hledger-api/doc/hledger-api.1"), ($(embedStringFile $ "../hledger-api/doc/hledger-api.1")
$(embedStringFile $ "../hledger-api/doc/hledger-api.1.txt"))) ,$(embedStringFile $ "../hledger-api/doc/hledger-api.1.txt")
,$(embedStringFile $ "../hledger-api/doc/hledger-api.1.info")
))
,("journal", ,("journal",
($(embedStringFile $ "../hledger-lib/doc/hledger_journal.5"), ($(embedStringFile $ "../hledger-lib/doc/hledger_journal.5")
$(embedStringFile $ "../hledger-lib/doc/hledger_journal.5.txt"))) ,$(embedStringFile $ "../hledger-lib/doc/hledger_journal.5.txt")
,$(embedStringFile $ "../hledger-lib/doc/hledger_journal.5.info")
))
,("csv", ,("csv",
($(embedStringFile $ "../hledger-lib/doc/hledger_csv.5"), ($(embedStringFile $ "../hledger-lib/doc/hledger_csv.5")
$(embedStringFile $ "../hledger-lib/doc/hledger_csv.5.txt"))) ,$(embedStringFile $ "../hledger-lib/doc/hledger_csv.5.txt")
,$(embedStringFile $ "../hledger-lib/doc/hledger_csv.5.info")
))
,("timeclock", ,("timeclock",
($(embedStringFile $ "../hledger-lib/doc/hledger_timeclock.5"), ($(embedStringFile $ "../hledger-lib/doc/hledger_timeclock.5")
$(embedStringFile $ "../hledger-lib/doc/hledger_timeclock.5.txt"))) ,$(embedStringFile $ "../hledger-lib/doc/hledger_timeclock.5.txt")
,$(embedStringFile $ "../hledger-lib/doc/hledger_timeclock.5.info")
))
,("timedot", ,("timedot",
($(embedStringFile $ "../hledger-lib/doc/hledger_timedot.5"), ($(embedStringFile $ "../hledger-lib/doc/hledger_timedot.5")
$(embedStringFile $ "../hledger-lib/doc/hledger_timedot.5.txt"))) ,$(embedStringFile $ "../hledger-lib/doc/hledger_timedot.5.txt")
,$(embedStringFile $ "../hledger-lib/doc/hledger_timedot.5.info")
))
] ]
docTopics :: [Topic] docTopics :: [Topic]
docTopics = map fst docFiles docTopics = map fst docFiles
lookupDocNroff :: IsString a => Topic -> a
lookupDocNroff name =
maybe (fromString $ "No such help topic: "++name) fst $ lookup name docFiles
lookupDocTxt :: IsString a => Topic -> a lookupDocTxt :: IsString a => Topic -> a
lookupDocTxt name = lookupDocTxt name =
maybe (fromString $ "No such help topic: "++name) snd $ lookup name docFiles maybe (fromString $ "No text manual found for topic: "++name) second3 $ lookup name docFiles
lookupDocNroff :: IsString a => Topic -> a
lookupDocNroff name =
maybe (fromString $ "No man page found for topic: "++name) first3 $ lookup name docFiles
lookupDocInfo :: IsString a => Topic -> a
lookupDocInfo name =
maybe (fromString $ "No info manual found for topic: "++name) third3 $ lookup name docFiles
printHelpForTopic :: Topic -> IO ()
printHelpForTopic t =
putStrLn $ lookupDocTxt t
runManForTopic :: Topic -> IO ()
runManForTopic t =
withSystemTempFile ("hledger-"++t++".nroff") $ \f h -> do
hPutStrLn h $ lookupDocNroff t
hClose h
-- the temp file path will presumably have a slash in it, so man should read it
callCommand $ "man " ++ f
runInfoForTopic :: Topic -> IO ()
runInfoForTopic t =
withSystemTempFile ("hledger-"++t++".info") $ \f h -> do
hPutStrLn h $ lookupDocInfo t
hClose h
callCommand $ "info " ++ f

View File

@ -21,7 +21,7 @@ import Hledger.Cli.CliOptions
import Hledger.Cli.DocFiles import Hledger.Cli.DocFiles
helpmode = (defCommandMode $ ["help"] ++ aliases) { helpmode = (defCommandMode $ ["help"] ++ aliases) {
modeHelp = "show detailed help (the main hledger man pages)" `withAliases` aliases modeHelp = "show manual" `withAliases` aliases
,modeGroupFlags = Group { ,modeGroupFlags = Group {
groupUnnamed = [] groupUnnamed = []
,groupHidden = [] ,groupHidden = []
@ -36,7 +36,7 @@ help' opts = do
let args = listofstringopt "args" $ rawopts_ opts let args = listofstringopt "args" $ rawopts_ opts
case args of case args of
[] -> putStrLn $ [] -> putStrLn $
"Choose a topic, eg: hledger help ui\n" ++ "Choose a topic, eg: hledger help cli\n" ++
intercalate ", " docTopics intercalate ", " docTopics
topic:_ -> putStrLn $ lookupDocTxt topic topic:_ -> printHelpForTopic topic

View File

@ -0,0 +1,41 @@
{-|
The info command.
|-}
module Hledger.Cli.Info (
infomode
,info'
) where
import Prelude ()
import Prelude.Compat
import Data.List
import System.Console.CmdArgs.Explicit
import Hledger.Data.RawOptions
import Hledger.Cli.CliOptions
import Hledger.Cli.DocFiles
infomode = (defCommandMode $ ["info"] ++ aliases) {
modeHelp = "show manual with info" `withAliases` aliases
,modeGroupFlags = Group {
groupUnnamed = []
,groupHidden = []
,groupNamed = []
}
}
where aliases = []
-- | Try to use info to view the selected manual.
info' :: CliOpts -> IO ()
info' opts = do
let args = listofstringopt "args" $ rawopts_ opts
case args of
[] -> putStrLn $
"Choose a topic, eg: hledger info cli\n" ++
intercalate ", " docTopics
topic:_ -> runInfoForTopic topic

View File

@ -55,9 +55,12 @@ import Hledger.Cli.Accounts
import Hledger.Cli.Balance import Hledger.Cli.Balance
import Hledger.Cli.Balancesheet import Hledger.Cli.Balancesheet
import Hledger.Cli.Cashflow import Hledger.Cli.Cashflow
import Hledger.Cli.DocFiles
import Hledger.Cli.Help import Hledger.Cli.Help
import Hledger.Cli.Histogram import Hledger.Cli.Histogram
import Hledger.Cli.Incomestatement import Hledger.Cli.Incomestatement
import Hledger.Cli.Info
import Hledger.Cli.Man
import Hledger.Cli.Print import Hledger.Cli.Print
import Hledger.Cli.Register import Hledger.Cli.Register
import Hledger.Cli.Stats import Hledger.Cli.Stats
@ -100,6 +103,8 @@ mainmode addons = defMode {
-- modes in the unnamed group, shown first without a heading: -- modes in the unnamed group, shown first without a heading:
,groupUnnamed = [ ,groupUnnamed = [
helpmode helpmode
,manmode
,infomode
] ]
-- modes handled but not shown -- modes handled but not shown
,groupHidden = [ ,groupHidden = [
@ -247,13 +252,19 @@ main = do
hasVersion = ("--version" `elem`) hasVersion = ("--version" `elem`)
hasDetailedVersion = ("--version+" `elem`) hasDetailedVersion = ("--version+" `elem`)
printUsage = putStr $ showModeUsage $ mainmode addonDisplayNames printUsage = putStr $ showModeUsage $ mainmode addonDisplayNames
printHelp = putStr $ showModeHelp $ mainmode addonDisplayNames
badCommandError = error' ("command "++rawcmd++" is not recognized, run with no command to see a list") >> exitFailure badCommandError = error' ("command "++rawcmd++" is not recognized, run with no command to see a list") >> exitFailure
hasShortHelp args = any (`elem` args) ["-h"] hasShortHelpFlag args = any (`elem` args) ["-h"]
hasLongHelp args = any (`elem` args) ["--help"] hasLongHelpFlag args = any (`elem` args) ["--help"]
hasHelp args = hasShortHelp args || hasLongHelp args hasManFlag args = any (`elem` args) ["--man"]
f `orShowUsage` mode = if hasShortHelp args then putStr (showModeUsage mode) else f hasInfoFlag args = any (`elem` args) ["--info"]
f `orShowHelp` mode = if hasLongHelp args then putStr (showModeHelp mode) else f hasSomeHelpFlag args = hasShortHelpFlag args || hasLongHelpFlag args || hasManFlag args || hasInfoFlag args
f `orShowHelp` mode
| hasShortHelpFlag args = putStr $ showModeUsage mode
| hasLongHelpFlag args = printHelpForTopic t
| hasManFlag args = runManForTopic t
| hasInfoFlag args = runInfoForTopic t
| otherwise = f
where t = topicForMode mode
dbgIO "processed opts" opts dbgIO "processed opts" opts
dbgIO "command matched" cmd dbgIO "command matched" cmd
dbgIO "isNullCommand" isNullCommand dbgIO "isNullCommand" isNullCommand
@ -266,31 +277,35 @@ main = do
dbgIO "query from opts & args" (queryFromOpts d $ reportopts_ opts) dbgIO "query from opts & args" (queryFromOpts d $ reportopts_ opts)
let let
runHledgerCommand runHledgerCommand
-- high priority flags and situations. --help should be highest priority. -- high priority flags and situations. -h, then --help, then --info are highest priority.
| hasShortHelp argsbeforecmd = dbgIO "" "-h before command, showing general usage" >> printUsage | hasShortHelpFlag argsbeforecmd = dbgIO "" "-h before command, showing general usage" >> printUsage
| hasLongHelp argsbeforecmd = dbgIO "" "--help before command, showing general help" >> printHelp | hasLongHelpFlag argsbeforecmd = dbgIO "" "--help before command, showing general manual" >> printHelpForTopic (topicForMode $ mainmode addonDisplayNames)
| not (hasHelp argsaftercmd) && (hasVersion argsbeforecmd || (hasVersion argsaftercmd && isInternalCommand)) | hasManFlag argsbeforecmd = dbgIO "" "--man before command, showing general manual with man" >> runManForTopic (topicForMode $ mainmode addonDisplayNames)
| hasInfoFlag argsbeforecmd = dbgIO "" "--info before command, showing general manual with info" >> runInfoForTopic (topicForMode $ mainmode addonDisplayNames)
| not (hasSomeHelpFlag argsaftercmd) && (hasVersion argsbeforecmd || (hasVersion argsaftercmd && isInternalCommand))
= putStrLn prognameandversion = putStrLn prognameandversion
| not (hasHelp argsaftercmd) && (hasDetailedVersion argsbeforecmd || (hasDetailedVersion argsaftercmd && isInternalCommand)) | not (hasSomeHelpFlag argsaftercmd) && (hasDetailedVersion argsbeforecmd || (hasDetailedVersion argsaftercmd && isInternalCommand))
= putStrLn prognameanddetailedversion = putStrLn prognameanddetailedversion
-- \| (null externalcmd) && "binary-filename" `inRawOpts` rawopts = putStrLn $ binaryfilename progname -- \| (null externalcmd) && "binary-filename" `inRawOpts` rawopts = putStrLn $ binaryfilename progname
-- \| "--browse-args" `elem` args = System.Console.CmdArgs.Helper.execute "cmdargs-browser" mainmode' args >>= (putStr . show) -- \| "--browse-args" `elem` args = System.Console.CmdArgs.Helper.execute "cmdargs-browser" mainmode' args >>= (putStr . show)
| isNullCommand = dbgIO "" "no command, showing general help" >> printUsage | isNullCommand = dbgIO "" "no command, showing general usage" >> printUsage
| isBadCommand = badCommandError | isBadCommand = badCommandError
-- internal commands -- internal commands
| cmd == "activity" = withJournalDo opts histogram `orShowUsage` activitymode `orShowHelp` activitymode | cmd == "activity" = withJournalDo opts histogram `orShowHelp` activitymode
| cmd == "add" = (journalFilePathFromOpts opts >>= (ensureJournalFileExists . head) >> withJournalDo opts add) `orShowUsage` addmode `orShowHelp` addmode | cmd == "add" = (journalFilePathFromOpts opts >>= (ensureJournalFileExists . head) >> withJournalDo opts add) `orShowHelp` addmode
| cmd == "accounts" = withJournalDo opts accounts `orShowUsage` accountsmode `orShowHelp` accountsmode | cmd == "accounts" = withJournalDo opts accounts `orShowHelp` accountsmode
| cmd == "balance" = withJournalDo opts balance `orShowUsage` balancemode `orShowHelp` balancemode | cmd == "balance" = withJournalDo opts balance `orShowHelp` balancemode
| cmd == "balancesheet" = withJournalDo opts balancesheet `orShowUsage` balancesheetmode `orShowHelp` balancesheetmode | cmd == "balancesheet" = withJournalDo opts balancesheet `orShowHelp` balancesheetmode
| cmd == "cashflow" = withJournalDo opts cashflow `orShowUsage` cashflowmode `orShowHelp` cashflowmode | cmd == "cashflow" = withJournalDo opts cashflow `orShowHelp` cashflowmode
| cmd == "incomestatement" = withJournalDo opts incomestatement `orShowUsage` incomestatementmode `orShowHelp` incomestatementmode | cmd == "incomestatement" = withJournalDo opts incomestatement `orShowHelp` incomestatementmode
| cmd == "print" = withJournalDo opts print' `orShowUsage` printmode `orShowHelp` printmode | cmd == "print" = withJournalDo opts print' `orShowHelp` printmode
| cmd == "register" = withJournalDo opts register `orShowUsage` registermode `orShowHelp` registermode | cmd == "register" = withJournalDo opts register `orShowHelp` registermode
| cmd == "stats" = withJournalDo opts stats `orShowUsage` statsmode `orShowHelp` statsmode | cmd == "stats" = withJournalDo opts stats `orShowHelp` statsmode
| cmd == "test" = test' opts `orShowUsage` testmode `orShowHelp` testmode | cmd == "test" = test' opts `orShowHelp` testmode
| cmd == "help" = help' opts `orShowUsage` helpmode `orShowHelp` helpmode | cmd == "help" = help' opts `orShowHelp` helpmode
| cmd == "man" = man opts `orShowHelp` manmode
| cmd == "info" = info' opts `orShowHelp` infomode
-- an external command -- an external command
| isExternalCommand = do | isExternalCommand = do

View File

@ -0,0 +1,41 @@
{-|
The man command.
|-}
module Hledger.Cli.Man (
manmode
,man
) where
import Prelude ()
import Prelude.Compat
import Data.List
import System.Console.CmdArgs.Explicit
import Hledger.Data.RawOptions
import Hledger.Cli.CliOptions
import Hledger.Cli.DocFiles
manmode = (defCommandMode $ ["man"] ++ aliases) {
modeHelp = "show manual with man" `withAliases` aliases
,modeGroupFlags = Group {
groupUnnamed = []
,groupHidden = []
,groupNamed = []
}
}
where aliases = []
-- | Try to use man to view the selected manual.
man :: CliOpts -> IO ()
man opts = do
let args = listofstringopt "args" $ rawopts_ opts
case args of
[] -> putStrLn $
"Choose a topic, eg: hledger man cli\n" ++
intercalate ", " docTopics
topic:_ -> runManForTopic topic

View File

@ -231,18 +231,20 @@ Total:
``` ```
## help ## help
Show detailed help. Show one of the hledger manuals.
The `help` command can display any of the main [hledger man pages](/docs.html), as fixed-width text. The `help` command displays any of the main [hledger man pages](/docs.html).
(Unlike `hledger --help`, which displays only the hledger man page.) (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), Run it with no arguments to list available topics (their names are shortened for easier typing),
and run `hledger help TOPIC` to select one. and run `hledger help TOPIC` to select one.
The output may be long, so you may wish to pipe it into a pager. 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).
_shell_({{ _shell_({{
$ hledger help $ hledger help
Please choose a topic, eg: hledger help ui Choose a topic, eg: hledger help cli
Topics: cli, ui, web, api, journal, csv, timeclock, timedot cli, ui, web, api, journal, csv, timeclock, timedot
}}) }})
_shell_({{ _shell_({{
@ -298,6 +300,26 @@ Total:
0 0
``` ```
## info
Show one of the hledger manuals using info.
The `info` command displays any of the [hledger reference manuals](/docs.html)
using the [info](https://en.wikipedia.org/wiki/Info_(Unix)) hypertextual documentation viewer.
This can be a very efficient way to browse large manuals.
It requires the "info" program to be available in your PATH.
As with [help](#help), run it with no arguments to list available topics (manuals).
## man
Show one of the hledger manuals using man.
The `man` command displays any of the [hledger reference manuals](/docs.html)
using [man](https://en.wikipedia.org/wiki/Man_page), the standard documentation viewer on unix systems.
This will fit the text to your terminal width, and probably invoke a pager automatically.
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 ## print
Show transactions from the journal. Show transactions from the journal.

View File

@ -177,12 +177,23 @@ show general usage (or if after COMMAND, the command\[aq]s usage)
.RE .RE
.TP .TP
.B \f[C]\-\-help\f[] .B \f[C]\-\-help\f[]
show detailed help (or if after COMMAND, the command\[aq]s help) show hledger manual (or if after an add\-on COMMAND, show the
add\-on\[aq]s manual)
.RS
.RE
.TP
.B \f[C]\-\-man\f[]
show manual with man
.RS
.RE
.TP
.B \f[C]\-\-info\f[]
show manual with info
.RS .RS
.RE .RE
.TP .TP
.B \f[C]\-\-version\f[] .B \f[C]\-\-version\f[]
show version information show version
.RS .RS
.RE .RE
.TP .TP
@ -1352,21 +1363,22 @@ Total:
.fi .fi
.SS help .SS help
.PP .PP
Show detailed help. Show one of the hledger manuals.
.PP .PP
The \f[C]help\f[] command can display any of the main hledger man pages, The \f[C]help\f[] command displays any of the main hledger man pages.
as fixed\-width text.
(Unlike \f[C]hledger\ \-\-help\f[], which displays only the hledger man (Unlike \f[C]hledger\ \-\-help\f[], which displays only the hledger man
page.) Run it with no arguments to list available topics (their names page.) Run it with no arguments to list available topics (their names
are shortened for easier typing), and run \f[C]hledger\ help\ TOPIC\f[] are shortened for easier typing), and run \f[C]hledger\ help\ TOPIC\f[]
to select one. to select one.
The output may be long, so you may wish to pipe it into a pager. 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 and man.
.IP .IP
.nf .nf
\f[C] \f[C]
$\ hledger\ help $\ hledger\ help
Please\ choose\ a\ topic,\ eg:\ hledger\ help\ ui Choose\ a\ topic,\ eg:\ hledger\ help\ cli
Topics:\ cli,\ ui,\ web,\ api,\ journal,\ csv,\ timeclock,\ timedot cli,\ ui,\ web,\ api,\ journal,\ csv,\ timeclock,\ timedot
\f[] \f[]
.fi .fi
.IP .IP
@ -1431,6 +1443,29 @@ Total:
\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ 0 \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ 0
\f[] \f[]
.fi .fi
.SS info
.PP
Show one of the hledger manuals using info.
.PP
The \f[C]info\f[] command displays any of the hledger reference manuals
using the info hypertextual documentation viewer.
This can be a very efficient way to browse large manuals.
It requires the "info" program to be available in your PATH.
.PP
As with help, run it with no arguments to list available topics
(manuals).
.SS man
.PP
Show one of the hledger manuals using man.
.PP
The \f[C]man\f[] command displays any of the hledger reference manuals
using man, the standard documentation viewer on unix systems.
This will fit the text to your terminal width, and probably invoke a
pager automatically.
It requires the "man" program to be available in your PATH.
.PP
As with help, run it with no arguments to list available topics
(manuals).
.SS print .SS print
.PP .PP
Show transactions from the journal. Show transactions from the journal.

File diff suppressed because it is too large Load Diff

View File

@ -26,10 +26,16 @@ General options are always available and can appear anywhere in the command line
: show general usage (or if after COMMAND, the command's usage) : show general usage (or if after COMMAND, the command's usage)
`--help` `--help`
: show detailed help (or if after COMMAND, the command's help) : show hledger manual (or if after an add-on COMMAND, show the add-on's manual)
`--man`
: show manual with man
`--info`
: show manual with info
`--version` `--version`
: show version information : show version
`-f FILE --file=FILE` `-f FILE --file=FILE`
: use a different input file. For stdin, use - : use a different input file. For stdin, use -

View File

@ -81,6 +81,7 @@ dependencies:
- regex-tdfa - regex-tdfa
- safe >= 0.2 - safe >= 0.2
- split >= 0.1 && < 0.3 - split >= 0.1 && < 0.3
- temporary
- text >= 0.11 - text >= 0.11
- tabular >= 0.2 && < 0.3 - tabular >= 0.2 && < 0.3
- utf8-string >= 0.3.5 && < 1.1 - utf8-string >= 0.3.5 && < 1.1
@ -124,6 +125,7 @@ library:
- Hledger.Cli - Hledger.Cli
- Hledger.Cli.Main - Hledger.Cli.Main
- Hledger.Cli.CliOptions - Hledger.Cli.CliOptions
- Hledger.Cli.DocFiles
- Hledger.Cli.Tests - Hledger.Cli.Tests
- Hledger.Cli.Utils - Hledger.Cli.Utils
- Hledger.Cli.Version - Hledger.Cli.Version
@ -132,8 +134,11 @@ library:
- Hledger.Cli.Balance - Hledger.Cli.Balance
- Hledger.Cli.Balancesheet - Hledger.Cli.Balancesheet
- Hledger.Cli.Cashflow - Hledger.Cli.Cashflow
- Hledger.Cli.Help
- Hledger.Cli.Histogram - Hledger.Cli.Histogram
- Hledger.Cli.Incomestatement - Hledger.Cli.Incomestatement
- Hledger.Cli.Info
- Hledger.Cli.Man
- Hledger.Cli.Print - Hledger.Cli.Print
- Hledger.Cli.Register - Hledger.Cli.Register
- Hledger.Cli.Stats - Hledger.Cli.Stats

View File

@ -80,6 +80,7 @@ library
, regex-tdfa , regex-tdfa
, safe >= 0.2 , safe >= 0.2
, split >= 0.1 && < 0.3 , split >= 0.1 && < 0.3
, temporary
, text >= 0.11 , text >= 0.11
, tabular >= 0.2 && < 0.3 , tabular >= 0.2 && < 0.3
, utf8-string >= 0.3.5 && < 1.1 , utf8-string >= 0.3.5 && < 1.1
@ -122,6 +123,8 @@ library
Hledger.Cli.Help Hledger.Cli.Help
Hledger.Cli.Histogram Hledger.Cli.Histogram
Hledger.Cli.Incomestatement Hledger.Cli.Incomestatement
Hledger.Cli.Info
Hledger.Cli.Man
Hledger.Cli.Print Hledger.Cli.Print
Hledger.Cli.Register Hledger.Cli.Register
Hledger.Cli.Stats Hledger.Cli.Stats
@ -158,6 +161,7 @@ executable hledger
, regex-tdfa , regex-tdfa
, safe >= 0.2 , safe >= 0.2
, split >= 0.1 && < 0.3 , split >= 0.1 && < 0.3
, temporary
, text >= 0.11 , text >= 0.11
, tabular >= 0.2 && < 0.3 , tabular >= 0.2 && < 0.3
, utf8-string >= 0.3.5 && < 1.1 , utf8-string >= 0.3.5 && < 1.1
@ -213,6 +217,7 @@ test-suite test
, regex-tdfa , regex-tdfa
, safe >= 0.2 , safe >= 0.2
, split >= 0.1 && < 0.3 , split >= 0.1 && < 0.3
, temporary
, text >= 0.11 , text >= 0.11
, tabular >= 0.2 && < 0.3 , tabular >= 0.2 && < 0.3
, utf8-string >= 0.3.5 && < 1.1 , utf8-string >= 0.3.5 && < 1.1
@ -256,6 +261,7 @@ benchmark bench
criterion, criterion,
html, html,
tabular >= 0.2 && < 0.3, tabular >= 0.2 && < 0.3,
temporary,
timeit, timeit,
process, process,
file-embed, file-embed,