{-|

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")
  [forall a. [CommandDoc] -> (a -> a) -> CommandDoc -> Flag a
flagNone [CommandDoc
"i"]  (CommandDoc -> RawOpts -> RawOpts
setboolopt CommandDoc
"info")  CommandDoc
"show the manual with info"
  ,forall a. [CommandDoc] -> (a -> a) -> CommandDoc -> Flag a
flagNone [CommandDoc
"m"]   (CommandDoc -> RawOpts -> RawOpts
setboolopt CommandDoc
"man")   CommandDoc
"show the manual with man"
  ,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"
  ,forall a. [CommandDoc] -> (a -> a) -> CommandDoc -> Flag a
flagNone [CommandDoc
"help",CommandDoc
"h"]  (CommandDoc -> RawOpts -> RawOpts
setboolopt CommandDoc
"help")  CommandDoc
"show this help"
  ]
  []
  []
  ([], forall a. a -> Maybe a
Just 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 <- forall a. a -> Maybe a -> a
fromMaybe CommandDoc
"less" 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 = forall a. Int -> [a] -> [a]
take Int
1 forall a b. (a -> b) -> a -> b
$ CommandDoc -> RawOpts -> [CommandDoc]
listofstringopt CommandDoc
"args" forall a b. (a -> b) -> a -> b
$ CliOpts -> RawOpts
rawopts_ CliOpts
opts
    mtopic :: Maybe CommandDoc
mtopic = 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"  forall a b. (a -> b) -> a -> b
$ CliOpts -> RawOpts
rawopts_ CliOpts
opts = CommandDoc -> Maybe CommandDoc -> IO ()
info
      | CommandDoc -> RawOpts -> Bool
boolopt CommandDoc
"man"   forall a b. (a -> b) -> a -> b
$ CliOpts -> RawOpts
rawopts_ CliOpts
opts = CommandDoc -> Maybe CommandDoc -> IO ()
man
      | CommandDoc -> RawOpts -> Bool
boolopt CommandDoc
"pager" 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"    forall (t :: * -> *) a. (Foldable t, Eq a) => a -> t a -> Bool
`elem` [CommandDoc]
exes           = CommandDoc -> Maybe CommandDoc -> IO ()
info
      | CommandDoc
"man"     forall (t :: * -> *) a. (Foldable t, Eq a) => a -> t a -> Bool
`elem` [CommandDoc]
exes           = CommandDoc -> Maybe CommandDoc -> IO ()
man
      | CommandDoc
pagerprog forall (t :: * -> *) a. (Foldable t, Eq a) => a -> t a -> Bool
`elem` [CommandDoc]
exes           = CommandDoc -> Maybe CommandDoc -> IO ()
pager
      | CommandDoc
"less"    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