    {-|

    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 System.Console.CmdArgs.Explicit
    import System.Environment
    import System.IO

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

    helpmode :: Mode RawOpts
    helpmode = CommandDoc
    -> [Flag RawOpts]
    -> [(CommandDoc, [Flag RawOpts])]
    -> [Flag RawOpts]
    -> ([Arg RawOpts], Maybe (Arg RawOpts))
    -> Mode RawOpts
    hledgerCommandMode
      $(embedFileRelative "Hledger/Cli/Commands/Help.txt")
      [[CommandDoc] -> (RawOpts -> RawOpts) -> CommandDoc -> Flag RawOpts
    forall a. [CommandDoc] -> (a -> a) -> CommandDoc -> Flag a
    flagNone [CommandDoc
    "i"]  (CommandDoc -> RawOpts -> RawOpts
    setboolopt CommandDoc
    "info")  CommandDoc
    "show the manual with info"
      ,[CommandDoc] -> (RawOpts -> RawOpts) -> CommandDoc -> Flag RawOpts
    forall a. [CommandDoc] -> (a -> a) -> CommandDoc -> Flag a
    flagNone [CommandDoc
    "m"]   (CommandDoc -> RawOpts -> RawOpts
    setboolopt CommandDoc
    "man")   CommandDoc
    "show the manual with man"
      ,[CommandDoc] -> (RawOpts -> RawOpts) -> CommandDoc -> Flag RawOpts
    forall a. [CommandDoc] -> (a -> a) -> CommandDoc -> Flag a
    flagNone [CommandDoc
    "p"] (CommandDoc -> RawOpts -> RawOpts
    setboolopt CommandDoc
    "pager") CommandDoc
    "show the manual with $PAGER or less"
      ,[CommandDoc] -> (RawOpts -> RawOpts) -> CommandDoc -> Flag RawOpts
    forall a. [CommandDoc] -> (a -> a) -> CommandDoc -> Flag a
    flagNone [CommandDoc
    "help",CommandDoc
    "h"]  (CommandDoc -> RawOpts -> RawOpts
    setboolopt CommandDoc
    "help")  CommandDoc
    "show this help"
      ]
      []
      []
      ([], 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
    $ CommandDoc -> Arg RawOpts
    argsFlag CommandDoc
    "[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
      [CommandDoc]
    exes <- IO [CommandDoc]
    likelyExecutablesInPath
      CommandDoc
    pagerprog <- CommandDoc -> Maybe CommandDoc -> CommandDoc
    forall a. a -> Maybe a -> a
    fromMaybe CommandDoc
    "less" (Maybe CommandDoc -> CommandDoc)
    -> IO (Maybe CommandDoc) -> IO CommandDoc
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    <$> CommandDoc -> IO (Maybe CommandDoc)
    lookupEnv CommandDoc
    "PAGER"
      Bool
    interactive <- Handle -> IO Bool
    hIsTerminalDevice Handle
    stdout
      let
        args :: [CommandDoc]
    args = Int -> [CommandDoc] -> [CommandDoc]
    forall a. Int -> [a] -> [a]
    take Int
    1 ([CommandDoc] -> [CommandDoc]) -> [CommandDoc] -> [CommandDoc]
    forall a b. (a -> b) -> a -> b
    $ CommandDoc -> RawOpts -> [CommandDoc]
    listofstringopt CommandDoc
    "args" (RawOpts -> [CommandDoc]) -> RawOpts -> [CommandDoc]
    forall a b. (a -> b) -> a -> b
    $ CliOpts -> RawOpts
    rawopts_ CliOpts
    opts
        mtopic :: Maybe CommandDoc
    mtopic = [CommandDoc] -> Maybe CommandDoc
    forall a. [a] -> Maybe a
    headMay [CommandDoc]
    args
        [CommandDoc -> Maybe CommandDoc -> IO ()
    info, CommandDoc -> Maybe CommandDoc -> IO ()
    man, CommandDoc -> Maybe CommandDoc -> IO ()
    pager, CommandDoc -> Maybe CommandDoc -> IO ()
    cat] =
          [CommandDoc -> Maybe CommandDoc -> IO ()
    runInfoForTopic, CommandDoc -> Maybe CommandDoc -> IO ()
    runManForTopic, CommandDoc -> Maybe CommandDoc -> IO ()
    runPagerForTopic, CommandDoc -> Maybe CommandDoc -> IO ()
    printHelpForTopic]
        viewer :: CommandDoc -> Maybe CommandDoc -> IO ()
    viewer
          | CommandDoc -> RawOpts -> Bool
    boolopt CommandDoc
    "info"  (RawOpts -> Bool) -> RawOpts -> Bool
    forall a b. (a -> b) -> a -> b
    $ CliOpts -> RawOpts
    rawopts_ CliOpts
    opts = CommandDoc -> Maybe CommandDoc -> IO ()
    info
          | CommandDoc -> RawOpts -> Bool
    boolopt CommandDoc
    "man"   (RawOpts -> Bool) -> RawOpts -> Bool
    forall a b. (a -> b) -> a -> b
    $ CliOpts -> RawOpts
    rawopts_ CliOpts
    opts = CommandDoc -> Maybe CommandDoc -> IO ()
    man
          | CommandDoc -> RawOpts -> Bool
    boolopt CommandDoc
    "pager" (RawOpts -> Bool) -> RawOpts -> Bool
    forall a b. (a -> b) -> a -> b
    $ CliOpts -> RawOpts
    rawopts_ CliOpts
    opts = CommandDoc -> Maybe CommandDoc -> IO ()
    pager
          | Bool -> Bool
    not Bool
    interactive                 = CommandDoc -> Maybe CommandDoc -> IO ()
    cat
          | CommandDoc
    "info"    CommandDoc -> [CommandDoc] -> Bool
    forall a. Eq a => a -> [a] -> Bool
    forall (t :: * -> *) a. (Foldable t, Eq a) => a -> t a -> Bool
    `elem` [CommandDoc]
    exes           = CommandDoc -> Maybe CommandDoc -> IO ()
    info
          | CommandDoc
    "man"     CommandDoc -> [CommandDoc] -> Bool
    forall a. Eq a => a -> [a] -> Bool
    forall (t :: * -> *) a. (Foldable t, Eq a) => a -> t a -> Bool
    `elem` [CommandDoc]
    exes           = CommandDoc -> Maybe CommandDoc -> IO ()
    man
          | CommandDoc
    pagerprog CommandDoc -> [CommandDoc] -> Bool
    forall a. Eq a => a -> [a] -> Bool
    forall (t :: * -> *) a. (Foldable t, Eq a) => a -> t a -> Bool
    `elem` [CommandDoc]
    exes           = CommandDoc -> Maybe CommandDoc -> IO ()
    pager
          | CommandDoc
    "less"    CommandDoc -> [CommandDoc] -> Bool
    forall a. Eq a => a -> [a] -> Bool
    forall (t :: * -> *) a. (Foldable t, Eq a) => a -> t a -> Bool
    `elem` [CommandDoc]
    exes           = CommandDoc -> Maybe CommandDoc -> IO ()
    pager
          | Bool
    otherwise                       = CommandDoc -> Maybe CommandDoc -> IO ()
    cat

      CommandDoc -> Maybe CommandDoc -> IO ()
    viewer CommandDoc
    "hledger" Maybe CommandDoc
    mtopic