    {-|

    The @descriptions@ command lists all unique descriptions seen in transactions, sorted alphabetically.

    -}

    {-# LANGUAGE MultiWayIf #-}
    {-# LANGUAGE OverloadedStrings #-}
    {-# LANGUAGE ScopedTypeVariables #-}
    {-# LANGUAGE TemplateHaskell #-}

    module Hledger.Cli.Commands.Descriptions (
      descriptionsmode
     ,descriptions
    ) where

    import Data.List.Extra (nubSort)
    import qualified Data.Text.IO as T

    import Hledger
    import Hledger.Cli.CliOptions

    -- | Command line options for this command.
    descriptionsmode :: Mode RawOpts
    descriptionsmode = CommandDoc
    -> [Flag RawOpts]
    -> [(CommandDoc, [Flag RawOpts])]
    -> [Flag RawOpts]
    -> ([Arg RawOpts], Maybe (Arg RawOpts))
    -> Mode RawOpts
    hledgerCommandMode
      $(embedFileRelative "Hledger/Cli/Commands/Descriptions.txt")
      []
      [(CommandDoc, [Flag RawOpts])
    generalflagsgroup1]
      [Flag RawOpts]
    hiddenflags
      ([], 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 "[QUERY]")

    -- | The descriptions command.
    descriptions :: CliOpts -> Journal -> IO ()
    descriptions :: CliOpts -> Journal -> IO ()
    descriptions CliOpts{reportopts_ :: CliOpts -> ReportOpts
    reportopts_=ReportOpts
    ropts} j :: Journal
    j = do
      Day
    d <- IO Day
    getCurrentDay
      let q :: Query
    q  = Day -> ReportOpts -> Query
    queryFromOpts Day
    d ReportOpts
    ropts
          ts :: EntriesReport
    ts = ReportOpts -> Query -> Journal -> EntriesReport
    entriesReport ReportOpts
    ropts Query
    q Journal
    j
          descriptions :: [Text]
    descriptions = [Text] -> [Text]
    forall a. Ord a => [a] -> [a]
    nubSort ([Text] -> [Text]) -> [Text] -> [Text]
    forall a b. (a -> b) -> a -> b
    $ (Transaction -> Text) -> EntriesReport -> [Text]
    forall a b. (a -> b) -> [a] -> [b]
    map Transaction -> Text
    tdescription EntriesReport
    ts

      (Text -> IO ()) -> [Text] -> IO ()
    forall (t :: * -> *) (m :: * -> *) a b.
    (Foldable t, Monad m) =>
    (a -> m b) -> t a -> m ()
    mapM_ Text -> IO ()
    T.putStrLn [Text]
    descriptions