    {-|

    The help command.

    |-}
    --TODO rename manuals
    --TODO substring matching

    {-# LANGUAGE PackageImports #-}
    {-# LANGUAGE QuasiQuotes #-}
    {-# LANGUAGE TemplateHaskell #-}

    module Hledger.Cli.Commands.Help (

       helpmode
      ,help'

      ) where

    import Data.Maybe
    import Safe (headMay)
    import System.Console.CmdArgs.Explicit
    import System.Environment
    import System.IO

    import Hledger.Cli.CliOptions
    import Hledger.Cli.DocFiles
    import Hledger.Data.RawOptions
    import Hledger.Data.Types
    import Hledger.Utils (embedFileRelative)
    --import Hledger.Utils.Debug

    helpmode :: Mode RawOpts
    helpmode = CommandHelpStr
    -> [Flag RawOpts]
    -> [(CommandHelpStr, [Flag RawOpts])]
    -> [Flag RawOpts]
    -> ([Arg RawOpts], Maybe (Arg RawOpts))
    -> Mode RawOpts
    hledgerCommandMode
      $(embedFileRelative "Hledger/Cli/Commands/Help.txt")
      -- The help-* names avoid a clash with the --info and --man flags handled in Cli.hs.
      [[CommandHelpStr]
    -> (RawOpts -> RawOpts) -> CommandHelpStr -> Flag RawOpts
    forall a. [CommandHelpStr] -> (a -> a) -> CommandHelpStr -> Flag a
    flagNone [CommandHelpStr
    "i"] (CommandHelpStr -> RawOpts -> RawOpts
    setboolopt CommandHelpStr
    "help-i")  CommandHelpStr
    "show the manual with info"
      ,[CommandHelpStr]
    -> (RawOpts -> RawOpts) -> CommandHelpStr -> Flag RawOpts
    forall a. [CommandHelpStr] -> (a -> a) -> CommandHelpStr -> Flag a
    flagNone [CommandHelpStr
    "m"] (CommandHelpStr -> RawOpts -> RawOpts
    setboolopt CommandHelpStr
    "help-m")   CommandHelpStr
    "show the manual with man"
      ,[CommandHelpStr]
    -> (RawOpts -> RawOpts) -> CommandHelpStr -> Flag RawOpts
    forall a. [CommandHelpStr] -> (a -> a) -> CommandHelpStr -> Flag a
    flagNone [CommandHelpStr
    "p"] (CommandHelpStr -> RawOpts -> RawOpts
    setboolopt CommandHelpStr
    "help-p") CommandHelpStr
    "show the manual with $PAGER or less\n(less is always used if TOPIC is specified)"
      ]
      [(CommandHelpStr
    helpflagstitle, [Flag RawOpts]
    helpflags)]
      []
      ([], Arg RawOpts -> Maybe (Arg RawOpts)
    forall a. a -> Maybe a
    Just (Arg RawOpts -> Maybe (Arg RawOpts))
    -> Arg RawOpts -> Maybe (Arg RawOpts)
    forall a b. (a -> b) -> a -> b
    $ CommandHelpStr -> Arg RawOpts
    argsFlag CommandHelpStr
    "[TOPIC]")

    -- | Display the hledger manual in various formats.
    -- You can select a docs viewer with one of the `--info`, `--man`, `--pager` flags.
    -- Otherwise it will use the first available of: info, man, $PAGER, less, stdout
    -- (and always stdout if output is non-interactive).
    help' :: CliOpts -> Journal -> IO ()
    help' :: CliOpts -> Journal -> IO ()
    help' CliOpts
    opts Journal
    _ = do
      exes <- IO [CommandHelpStr]
    likelyExecutablesInPath
      pagerprog <- fromMaybe "less" <$> lookupEnv "PAGER"
      interactive <- hIsTerminalDevice stdout
      let
        args = Int -> [CommandHelpStr] -> [CommandHelpStr]
    forall a. Int -> [a] -> [a]
    take Int
    1 ([CommandHelpStr] -> [CommandHelpStr])
    -> [CommandHelpStr] -> [CommandHelpStr]
    forall a b. (a -> b) -> a -> b
    $ CommandHelpStr -> RawOpts -> [CommandHelpStr]
    listofstringopt CommandHelpStr
    "args" (RawOpts -> [CommandHelpStr]) -> RawOpts -> [CommandHelpStr]
    forall a b. (a -> b) -> a -> b
    $ CliOpts -> RawOpts
    rawopts_ CliOpts
    opts
        mtopic = [CommandHelpStr] -> Maybe CommandHelpStr
    forall a. [a] -> Maybe a
    headMay [CommandHelpStr]
    args
        [info, man, pager, cat] =
          [runInfoForTopic, runManForTopic, runPagerForTopic, printHelpForTopic]
        viewer
          | CommandHelpStr -> RawOpts -> Bool
    boolopt CommandHelpStr
    "help-i" (RawOpts -> Bool) -> RawOpts -> Bool
    forall a b. (a -> b) -> a -> b
    $ CliOpts -> RawOpts
    rawopts_ CliOpts
    opts = CommandHelpStr -> Maybe CommandHelpStr -> IO ()
    info
          | CommandHelpStr -> RawOpts -> Bool
    boolopt CommandHelpStr
    "help-m" (RawOpts -> Bool) -> RawOpts -> Bool
    forall a b. (a -> b) -> a -> b
    $ CliOpts -> RawOpts
    rawopts_ CliOpts
    opts = CommandHelpStr -> Maybe CommandHelpStr -> IO ()
    man
          | CommandHelpStr -> RawOpts -> Bool
    boolopt CommandHelpStr
    "help-p" (RawOpts -> Bool) -> RawOpts -> Bool
    forall a b. (a -> b) -> a -> b
    $ CliOpts -> RawOpts
    rawopts_ CliOpts
    opts = CommandHelpStr -> Maybe CommandHelpStr -> IO ()
    pager
          | Bool -> Bool
    not Bool
    interactive                  = CommandHelpStr -> Maybe CommandHelpStr -> IO ()
    cat
          | CommandHelpStr
    "info"    CommandHelpStr -> [CommandHelpStr] -> Bool
    forall a. Eq a => a -> [a] -> Bool
    forall (t :: * -> *) a. (Foldable t, Eq a) => a -> t a -> Bool
    `elem` [CommandHelpStr]
    exes            = CommandHelpStr -> Maybe CommandHelpStr -> IO ()
    info
          | CommandHelpStr
    "man"     CommandHelpStr -> [CommandHelpStr] -> Bool
    forall a. Eq a => a -> [a] -> Bool
    forall (t :: * -> *) a. (Foldable t, Eq a) => a -> t a -> Bool
    `elem` [CommandHelpStr]
    exes            = CommandHelpStr -> Maybe CommandHelpStr -> IO ()
    man
          | CommandHelpStr
    pagerprog CommandHelpStr -> [CommandHelpStr] -> Bool
    forall a. Eq a => a -> [a] -> Bool
    forall (t :: * -> *) a. (Foldable t, Eq a) => a -> t a -> Bool
    `elem` [CommandHelpStr]
    exes            = CommandHelpStr -> Maybe CommandHelpStr -> IO ()
    pager
          | CommandHelpStr
    "less"    CommandHelpStr -> [CommandHelpStr] -> Bool
    forall a. Eq a => a -> [a] -> Bool
    forall (t :: * -> *) a. (Foldable t, Eq a) => a -> t a -> Bool
    `elem` [CommandHelpStr]
    exes            = CommandHelpStr -> Maybe CommandHelpStr -> IO ()
    pager
          | Bool
    otherwise                        = CommandHelpStr -> Maybe CommandHelpStr -> IO ()
    cat

      viewer "hledger" mtopic