    -- | You don't need to import this module to enable bash completion.
    --
    -- See
    -- <http://github.com/pcapriotti/optparse-applicative/wiki/Bash-Completion the wiki>
    -- for more information on bash completion.
    module Options.Applicative.BashCompletion
      ( bashCompletionParser,

        bashCompletionScript,
        fishCompletionScript,
        zshCompletionScript,
      ) where

    import Control.Applicative
    import Prelude
    import Data.Foldable ( asum )
    import Data.List ( isPrefixOf )
    import Data.Maybe ( fromMaybe, listToMaybe )

    import Options.Applicative.Builder
    import Options.Applicative.Common
    import Options.Applicative.Internal
    import Options.Applicative.Types
    import Options.Applicative.Help.Pretty
    import Options.Applicative.Help.Chunk

    -- | Provide basic or rich command completions
    data Richness
      = Standard
      -- ^ Add no help descriptions to the completions
      | Enriched Int Int
      -- ^ Include tab separated description for options
      --   and commands when available.
      --   Takes option description length and command
      --   description length.
      deriving (Richness -> Richness -> Bool
    (Richness -> Richness -> Bool)
    -> (Richness -> Richness -> Bool) -> Eq Richness
    forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
    $c== :: Richness -> Richness -> Bool
    == :: Richness -> Richness -> Bool
    $c/= :: Richness -> Richness -> Bool
    /= :: Richness -> Richness -> Bool
    Eq, Eq Richness
    Eq Richness =>
    (Richness -> Richness -> Ordering)
    -> (Richness -> Richness -> Bool)
    -> (Richness -> Richness -> Bool)
    -> (Richness -> Richness -> Bool)
    -> (Richness -> Richness -> Bool)
    -> (Richness -> Richness -> Richness)
    -> (Richness -> Richness -> Richness)
    -> Ord Richness
    Richness -> Richness -> Bool
    Richness -> Richness -> Ordering
    Richness -> Richness -> Richness
    forall a.
    Eq a =>
    (a -> a -> Ordering)
    -> (a -> a -> Bool)
    -> (a -> a -> Bool)
    -> (a -> a -> Bool)
    -> (a -> a -> Bool)
    -> (a -> a -> a)
    -> (a -> a -> a)
    -> Ord a
    $ccompare :: Richness -> Richness -> Ordering
    compare :: Richness -> Richness -> Ordering
    $c< :: Richness -> Richness -> Bool
    < :: Richness -> Richness -> Bool
    $c<= :: Richness -> Richness -> Bool
    <= :: Richness -> Richness -> Bool
    $c> :: Richness -> Richness -> Bool
    > :: Richness -> Richness -> Bool
    $c>= :: Richness -> Richness -> Bool
    >= :: Richness -> Richness -> Bool
    $cmax :: Richness -> Richness -> Richness
    max :: Richness -> Richness -> Richness
    $cmin :: Richness -> Richness -> Richness
    min :: Richness -> Richness -> Richness
    Ord, Int -> Richness -> ShowS
    [Richness] -> ShowS
    Richness -> String
    (Int -> Richness -> ShowS)
    -> (Richness -> String) -> ([Richness] -> ShowS) -> Show Richness
    forall a.
    (Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
    $cshowsPrec :: Int -> Richness -> ShowS
    showsPrec :: Int -> Richness -> ShowS
    $cshow :: Richness -> String
    show :: Richness -> String
    $cshowList :: [Richness] -> ShowS
    showList :: [Richness] -> ShowS
    Show)

    bashCompletionParser :: ParserInfo a -> ParserPrefs -> Parser CompletionResult
    bashCompletionParser :: forall a. ParserInfo a -> ParserPrefs -> Parser CompletionResult
    bashCompletionParser ParserInfo a
    pinfo ParserPrefs
    pprefs = Parser CompletionResult
    complParser
      where
        returnCompletions :: (String -> IO [String]) -> CompletionResult
    returnCompletions String -> IO [String]
    opts =
          (String -> IO String) -> CompletionResult
    CompletionResult ((String -> IO String) -> CompletionResult)
    -> (String -> IO String) -> CompletionResult
    forall a b. (a -> b) -> a -> b
    $
            \String
    progn -> [String] -> String
    unlines ([String] -> String) -> IO [String] -> IO String
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    <$> String -> IO [String]
    opts String
    progn

        scriptRequest :: ShowS -> CompletionResult
    scriptRequest =
          (String -> IO String) -> CompletionResult
    CompletionResult ((String -> IO String) -> CompletionResult)
    -> (ShowS -> String -> IO String) -> ShowS -> CompletionResult
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . (String -> IO String) -> ShowS -> String -> IO String
    forall a b. (a -> b) -> (String -> a) -> String -> b
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    fmap String -> IO String
    forall a. a -> IO a
    forall (f :: * -> *) a. Applicative f => a -> f a
    pure

        complParser :: Parser CompletionResult
    complParser = [Parser CompletionResult] -> Parser CompletionResult
    forall (t :: * -> *) (f :: * -> *) a.
    (Foldable t, Alternative f) =>
    t (f a) -> f a
    asum
          [ (String -> IO [String]) -> CompletionResult
    returnCompletions ((String -> IO [String]) -> CompletionResult)
    -> Parser (String -> IO [String]) -> Parser CompletionResult
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    <$>
            (  ParserInfo a
    -> ParserPrefs
    -> Richness
    -> [String]
    -> Int
    -> String
    -> IO [String]
    forall a.
    ParserInfo a
    -> ParserPrefs
    -> Richness
    -> [String]
    -> Int
    -> String
    -> IO [String]
    bashCompletionQuery ParserInfo a
    pinfo ParserPrefs
    pprefs
            -- To get rich completions, one just needs the first
            -- command. To customise the lengths, use either of
            -- the `desc-length` options.
            -- zsh commands can go on a single line, so they might
            -- want to be longer.
            (Richness -> [String] -> Int -> String -> IO [String])
    -> Parser Richness
    -> Parser ([String] -> Int -> String -> IO [String])
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    <$> ( (Int -> Int -> Richness)
    -> Mod FlagFields (Int -> Int -> Richness)
    -> Parser (Int -> Int -> Richness)
    forall a. a -> Mod FlagFields a -> Parser a
    flag' Int -> Int -> Richness
    Enriched (String -> Mod FlagFields (Int -> Int -> Richness)
    forall (f :: * -> *) a. HasName f => String -> Mod f a
    long String
    "bash-completion-enriched" Mod FlagFields (Int -> Int -> Richness)
    -> Mod FlagFields (Int -> Int -> Richness)
    -> Mod FlagFields (Int -> Int -> Richness)
    forall a. Monoid a => a -> a -> a
    `mappend` Mod FlagFields (Int -> Int -> Richness)
    forall (f :: * -> *) a. Mod f a
    internal)
                    Parser (Int -> Int -> Richness)
    -> Parser Int -> Parser (Int -> Richness)
    forall a b. Parser (a -> b) -> Parser a -> Parser b
    forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
    <*> ReadM Int -> Mod OptionFields Int -> Parser Int
    forall a. ReadM a -> Mod OptionFields a -> Parser a
    option ReadM Int
    forall a. Read a => ReadM a
    auto (String -> Mod OptionFields Int
    forall (f :: * -> *) a. HasName f => String -> Mod f a
    long String
    "bash-completion-option-desc-length" Mod OptionFields Int
    -> Mod OptionFields Int -> Mod OptionFields Int
    forall a. Monoid a => a -> a -> a
    `mappend` Mod OptionFields Int
    forall (f :: * -> *) a. Mod f a
    internal Mod OptionFields Int
    -> Mod OptionFields Int -> Mod OptionFields Int
    forall a. Monoid a => a -> a -> a
    `mappend` Int -> Mod OptionFields Int
    forall (f :: * -> *) a. HasValue f => a -> Mod f a
    value Int
    40)
                    Parser (Int -> Richness) -> Parser Int -> Parser Richness
    forall a b. Parser (a -> b) -> Parser a -> Parser b
    forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
    <*> ReadM Int -> Mod OptionFields Int -> Parser Int
    forall a. ReadM a -> Mod OptionFields a -> Parser a
    option ReadM Int
    forall a. Read a => ReadM a
    auto (String -> Mod OptionFields Int
    forall (f :: * -> *) a. HasName f => String -> Mod f a
    long String
    "bash-completion-command-desc-length" Mod OptionFields Int
    -> Mod OptionFields Int -> Mod OptionFields Int
    forall a. Monoid a => a -> a -> a
    `mappend` Mod OptionFields Int
    forall (f :: * -> *) a. Mod f a
    internal Mod OptionFields Int
    -> Mod OptionFields Int -> Mod OptionFields Int
    forall a. Monoid a => a -> a -> a
    `mappend` Int -> Mod OptionFields Int
    forall (f :: * -> *) a. HasValue f => a -> Mod f a
    value Int
    40)
              Parser Richness -> Parser Richness -> Parser Richness
    forall a. Parser a -> Parser a -> Parser a
    forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
    <|> Richness -> Parser Richness
    forall a. a -> Parser a
    forall (f :: * -> *) a. Applicative f => a -> f a
    pure Richness
    Standard
              )
            Parser ([String] -> Int -> String -> IO [String])
    -> Parser [String] -> Parser (Int -> String -> IO [String])
    forall a b. Parser (a -> b) -> Parser a -> Parser b
    forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
    <*> (Parser String -> Parser [String]
    forall a. Parser a -> Parser [a]
    forall (f :: * -> *) a. Alternative f => f a -> f [a]
    many (Parser String -> Parser [String])
    -> (Mod OptionFields String -> Parser String)
    -> Mod OptionFields String
    -> Parser [String]
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . Mod OptionFields String -> Parser String
    forall s. IsString s => Mod OptionFields s -> Parser s
    strOption) (String -> Mod OptionFields String
    forall (f :: * -> *) a. HasName f => String -> Mod f a
    long String
    "bash-completion-word"
                                      Mod OptionFields String
    -> Mod OptionFields String -> Mod OptionFields String
    forall a. Monoid a => a -> a -> a
    `mappend` Mod OptionFields String
    forall (f :: * -> *) a. Mod f a
    internal)
            Parser (Int -> String -> IO [String])
    -> Parser Int -> Parser (String -> IO [String])
    forall a b. Parser (a -> b) -> Parser a -> Parser b
    forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
    <*> ReadM Int -> Mod OptionFields Int -> Parser Int
    forall a. ReadM a -> Mod OptionFields a -> Parser a
    option ReadM Int
    forall a. Read a => ReadM a
    auto (String -> Mod OptionFields Int
    forall (f :: * -> *) a. HasName f => String -> Mod f a
    long String
    "bash-completion-index" Mod OptionFields Int
    -> Mod OptionFields Int -> Mod OptionFields Int
    forall a. Monoid a => a -> a -> a
    `mappend` Mod OptionFields Int
    forall (f :: * -> *) a. Mod f a
    internal) )

          , ShowS -> CompletionResult
    scriptRequest (ShowS -> CompletionResult)
    -> (String -> ShowS) -> String -> CompletionResult
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . String -> ShowS
    bashCompletionScript (String -> CompletionResult)
    -> Parser String -> Parser CompletionResult
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    <$>
                Mod OptionFields String -> Parser String
    forall s. IsString s => Mod OptionFields s -> Parser s
    strOption (String -> Mod OptionFields String
    forall (f :: * -> *) a. HasName f => String -> Mod f a
    long String
    "bash-completion-script" Mod OptionFields String
    -> Mod OptionFields String -> Mod OptionFields String
    forall a. Monoid a => a -> a -> a
    `mappend` Mod OptionFields String
    forall (f :: * -> *) a. Mod f a
    internal)
          , ShowS -> CompletionResult
    scriptRequest (ShowS -> CompletionResult)
    -> (String -> ShowS) -> String -> CompletionResult
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . String -> ShowS
    fishCompletionScript (String -> CompletionResult)
    -> Parser String -> Parser CompletionResult
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    <$>
                Mod OptionFields String -> Parser String
    forall s. IsString s => Mod OptionFields s -> Parser s
    strOption (String -> Mod OptionFields String
    forall (f :: * -> *) a. HasName f => String -> Mod f a
    long String
    "fish-completion-script" Mod OptionFields String
    -> Mod OptionFields String -> Mod OptionFields String
    forall a. Monoid a => a -> a -> a
    `mappend` Mod OptionFields String
    forall (f :: * -> *) a. Mod f a
    internal)
          , ShowS -> CompletionResult
    scriptRequest (ShowS -> CompletionResult)
    -> (String -> ShowS) -> String -> CompletionResult
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . String -> ShowS
    zshCompletionScript (String -> CompletionResult)
    -> Parser String -> Parser CompletionResult
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    <$>
                Mod OptionFields String -> Parser String
    forall s. IsString s => Mod OptionFields s -> Parser s
    strOption (String -> Mod OptionFields String
    forall (f :: * -> *) a. HasName f => String -> Mod f a
    long String
    "zsh-completion-script" Mod OptionFields String
    -> Mod OptionFields String -> Mod OptionFields String
    forall a. Monoid a => a -> a -> a
    `mappend` Mod OptionFields String
    forall (f :: * -> *) a. Mod f a
    internal)
          ]

    bashCompletionQuery :: ParserInfo a -> ParserPrefs -> Richness -> [String] -> Int -> String -> IO [String]
    bashCompletionQuery :: forall a.
    ParserInfo a
    -> ParserPrefs
    -> Richness
    -> [String]
    -> Int
    -> String
    -> IO [String]
    bashCompletionQuery ParserInfo a
    pinfo ParserPrefs
    pprefs Richness
    richness [String]
    ws Int
    i String
    _ = case Completion a
    -> ParserPrefs -> Maybe (Either (SomeParser, ArgPolicy) Completer)
    forall r.
    Completion r
    -> ParserPrefs -> Maybe (Either (SomeParser, ArgPolicy) Completer)
    runCompletion Completion a
    compl ParserPrefs
    pprefs of
      Just (Left (SomeParser Parser a
    p, ArgPolicy
    a))
        -> ArgPolicy -> Parser a -> IO [String]
    forall {a}. ArgPolicy -> Parser a -> IO [String]
    list_options ArgPolicy
    a Parser a
    p
      Just (Right Completer
    c)
        -> Completer -> IO [String]
    run_completer Completer
    c
      Maybe (Either (SomeParser, ArgPolicy) Completer)
    Nothing
        -> [String] -> IO [String]
    forall a. a -> IO a
    forall (m :: * -> *) a. Monad m => a -> m a
    return []
      where
        compl :: Completion a
    compl = ParserInfo a -> [String] -> Completion a
    forall (m :: * -> *) a. MonadP m => ParserInfo a -> [String] -> m a
    runParserInfo ParserInfo a
    pinfo (Int -> [String] -> [String]
    forall a. Int -> [a] -> [a]
    drop Int
    1 [String]
    ws')

        list_options :: ArgPolicy -> Parser a -> IO [String]
    list_options ArgPolicy
    a
          = ([[String]] -> [String]) -> IO [[String]] -> IO [String]
    forall a b. (a -> b) -> IO a -> IO b
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    fmap [[String]] -> [String]
    forall (t :: * -> *) a. Foldable t => t [a] -> [a]
    concat
          (IO [[String]] -> IO [String])
    -> (Parser a -> IO [[String]]) -> Parser a -> IO [String]
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . [IO [String]] -> IO [[String]]
    forall (t :: * -> *) (m :: * -> *) a.
    (Traversable t, Monad m) =>
    t (m a) -> m (t a)
    forall (m :: * -> *) a. Monad m => [m a] -> m [a]
    sequence
          ([IO [String]] -> IO [[String]])
    -> (Parser a -> [IO [String]]) -> Parser a -> IO [[String]]
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . (forall x. ArgumentReachability -> Option x -> IO [String])
    -> Parser a -> [IO [String]]
    forall b a.
    (forall x. ArgumentReachability -> Option x -> b)
    -> Parser a -> [b]
    mapParser (ArgPolicy -> ArgumentReachability -> Option x -> IO [String]
    forall {a}.
    ArgPolicy -> ArgumentReachability -> Option a -> IO [String]
    opt_completions ArgPolicy
    a)

        --
        -- Prior to 0.14 there was a subtle bug which would
        -- mean that completions from positional arguments
        -- further into the parse would be shown.
        --
        -- We therefore now check to see that
        -- hinfoUnreachableArgs is off before running the
        -- completion for position arguments.
        --
        -- For options and flags, ensure that the user
        -- hasn't disabled them with `--`.
        opt_completions :: ArgPolicy -> ArgumentReachability -> Option a -> IO [String]
    opt_completions ArgPolicy
    argPolicy ArgumentReachability
    reachability Option a
    opt = case Option a -> OptReader a
    forall a. Option a -> OptReader a
    optMain Option a
    opt of
          OptReader [OptName]
    ns CReader a
    _ String -> ParseError
    _
             | ArgPolicy
    argPolicy ArgPolicy -> ArgPolicy -> Bool
    forall a. Eq a => a -> a -> Bool
    /= ArgPolicy
    AllPositionals
            -> [String] -> IO [String]
    forall a. a -> IO a
    forall (m :: * -> *) a. Monad m => a -> m a
    return ([String] -> IO [String])
    -> ([String] -> [String]) -> [String] -> IO [String]
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . Option a -> [String] -> [String]
    forall (f :: * -> *) a.
    Functor f =>
    Option a -> f String -> f String
    add_opt_help Option a
    opt ([String] -> IO [String]) -> [String] -> IO [String]
    forall a b. (a -> b) -> a -> b
    $ [OptName] -> [String]
    show_names [OptName]
    ns
             | Bool
    otherwise
            -> [String] -> IO [String]
    forall a. a -> IO a
    forall (m :: * -> *) a. Monad m => a -> m a
    return []
          FlagReader [OptName]
    ns a
    _
             | ArgPolicy
    argPolicy ArgPolicy -> ArgPolicy -> Bool
    forall a. Eq a => a -> a -> Bool
    /= ArgPolicy
    AllPositionals
            -> [String] -> IO [String]
    forall a. a -> IO a
    forall (m :: * -> *) a. Monad m => a -> m a
    return ([String] -> IO [String])
    -> ([String] -> [String]) -> [String] -> IO [String]
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . Option a -> [String] -> [String]
    forall (f :: * -> *) a.
    Functor f =>
    Option a -> f String -> f String
    add_opt_help Option a
    opt ([String] -> IO [String]) -> [String] -> IO [String]
    forall a b. (a -> b) -> a -> b
    $ [OptName] -> [String]
    show_names [OptName]
    ns
             | Bool
    otherwise
            -> [String] -> IO [String]
    forall a. a -> IO a
    forall (m :: * -> *) a. Monad m => a -> m a
    return []
          ArgReader CReader a
    rdr
             | ArgumentReachability -> Bool
    argumentIsUnreachable ArgumentReachability
    reachability
            -> [String] -> IO [String]
    forall a. a -> IO a
    forall (m :: * -> *) a. Monad m => a -> m a
    return []
             | Bool
    otherwise
            -> Completer -> IO [String]
    run_completer (CReader a -> Completer
    forall a. CReader a -> Completer
    crCompleter CReader a
    rdr)
          CmdReader Maybe String
    _ [(String, ParserInfo a)]
    ns
             | ArgumentReachability -> Bool
    argumentIsUnreachable ArgumentReachability
    reachability
            -> [String] -> IO [String]
    forall a. a -> IO a
    forall (m :: * -> *) a. Monad m => a -> m a
    return []
             | Bool
    otherwise
            -> [String] -> IO [String]
    forall a. a -> IO a
    forall (m :: * -> *) a. Monad m => a -> m a
    return ([String] -> IO [String])
    -> ([(String, ParserInfo a)] -> [String])
    -> [(String, ParserInfo a)]
    -> IO [String]
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . [(String, ParserInfo a)] -> [String]
    forall (f :: * -> *) a.
    Functor f =>
    f (String, ParserInfo a) -> f String
    with_cmd_help ([(String, ParserInfo a)] -> IO [String])
    -> [(String, ParserInfo a)] -> IO [String]
    forall a b. (a -> b) -> a -> b
    $ ((String, ParserInfo a) -> Bool)
    -> [(String, ParserInfo a)] -> [(String, ParserInfo a)]
    forall a. (a -> Bool) -> [a] -> [a]
    filter (String -> Bool
    is_completion (String -> Bool)
    -> ((String, ParserInfo a) -> String)
    -> (String, ParserInfo a)
    -> Bool
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . (String, ParserInfo a) -> String
    forall a b. (a, b) -> a
    fst) [(String, ParserInfo a)]
    ns

        -- When doing enriched completions, add any help specified
        -- to the completion variables (tab separated).
        add_opt_help :: Functor f => Option a -> f String -> f String
        add_opt_help :: forall (f :: * -> *) a.
    Functor f =>
    Option a -> f String -> f String
    add_opt_help Option a
    opt = case Richness
    richness of
          Richness
    Standard ->
            f String -> f String
    forall a. a -> a
    id
          Enriched Int
    len Int
    _ ->
            ShowS -> f String -> f String
    forall a b. (a -> b) -> f a -> f b
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    fmap (ShowS -> f String -> f String) -> ShowS -> f String -> f String
    forall a b. (a -> b) -> a -> b
    $ \String
    o ->
              let h :: Maybe Doc
    h = Chunk Doc -> Maybe Doc
    forall a. Chunk a -> Maybe a
    unChunk (Chunk Doc -> Maybe Doc) -> Chunk Doc -> Maybe Doc
    forall a b. (a -> b) -> a -> b
    $ Option a -> Chunk Doc
    forall a. Option a -> Chunk Doc
    optHelp Option a
    opt
              in  String -> (Doc -> String) -> Maybe Doc -> String
    forall b a. b -> (a -> b) -> Maybe a -> b
    maybe String
    o (\Doc
    h' -> String
    o String -> ShowS
    forall a. [a] -> [a] -> [a]
    ++ String
    "\t" String -> ShowS
    forall a. [a] -> [a] -> [a]
    ++ Int -> Doc -> String
    render_line Int
    len Doc
    h') Maybe Doc
    h

        -- When doing enriched completions, add the command description
        -- to the completion variables (tab separated).
        with_cmd_help :: Functor f => f (String, ParserInfo a) -> f String
        with_cmd_help :: forall (f :: * -> *) a.
    Functor f =>
    f (String, ParserInfo a) -> f String
    with_cmd_help =
          case Richness
    richness of
            Richness
    Standard ->
              ((String, ParserInfo a) -> String)
    -> f (String, ParserInfo a) -> f String
    forall a b. (a -> b) -> f a -> f b
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    fmap (String, ParserInfo a) -> String
    forall a b. (a, b) -> a
    fst
            Enriched Int
    _ Int
    len ->
              ((String, ParserInfo a) -> String)
    -> f (String, ParserInfo a) -> f String
    forall a b. (a -> b) -> f a -> f b
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    fmap (((String, ParserInfo a) -> String)
     -> f (String, ParserInfo a) -> f String)
    -> ((String, ParserInfo a) -> String)
    -> f (String, ParserInfo a)
    -> f String
    forall a b. (a -> b) -> a -> b
    $ \(String
    cmd, ParserInfo a
    cmdInfo) ->
                let h :: Maybe Doc
    h = Chunk Doc -> Maybe Doc
    forall a. Chunk a -> Maybe a
    unChunk (ParserInfo a -> Chunk Doc
    forall a. ParserInfo a -> Chunk Doc
    infoProgDesc ParserInfo a
    cmdInfo)
                in  String -> (Doc -> String) -> Maybe Doc -> String
    forall b a. b -> (a -> b) -> Maybe a -> b
    maybe String
    cmd (\Doc
    h' -> String
    cmd String -> ShowS
    forall a. [a] -> [a] -> [a]
    ++ String
    "\t" String -> ShowS
    forall a. [a] -> [a] -> [a]
    ++ Int -> Doc -> String
    render_line Int
    len Doc
    h') Maybe Doc
    h

        show_names :: [OptName] -> [String]
        show_names :: [OptName] -> [String]
    show_names = (String -> Bool) -> [String] -> [String]
    forall a. (a -> Bool) -> [a] -> [a]
    filter String -> Bool
    is_completion ([String] -> [String])
    -> ([OptName] -> [String]) -> [OptName] -> [String]
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . (OptName -> String) -> [OptName] -> [String]
    forall a b. (a -> b) -> [a] -> [b]
    map OptName -> String
    showOption

        -- We only want to show a single line in the completion results description.
        -- If there was a line break, it would come across as a different completion
        -- possibility.
        render_line :: Int -> Doc -> String
        render_line :: Int -> Doc -> String
    render_line Int
    len Doc
    doc = case String -> [String]
    lines (Double -> Int -> Doc -> String
    prettyString Double
    1 Int
    len Doc
    doc) of
          [] -> String
    ""
          [String
    x] -> String
    x
          String
    x : [String]
    _ -> String
    x String -> ShowS
    forall a. [a] -> [a] -> [a]
    ++ String
    "..."

        run_completer :: Completer -> IO [String]
        run_completer :: Completer -> IO [String]
    run_completer Completer
    c = Completer -> String -> IO [String]
    runCompleter Completer
    c (String -> Maybe String -> String
    forall a. a -> Maybe a -> a
    fromMaybe String
    "" ([String] -> Maybe String
    forall a. [a] -> Maybe a
    listToMaybe [String]
    ws''))

        ([String]
    ws', [String]
    ws'') = Int -> [String] -> ([String], [String])
    forall a. Int -> [a] -> ([a], [a])
    splitAt Int
    i [String]
    ws

        is_completion :: String -> Bool
        is_completion :: String -> Bool
    is_completion =
          case [String]
    ws'' of
            String
    w:[String]
    _ -> String -> String -> Bool
    forall a. Eq a => [a] -> [a] -> Bool
    isPrefixOf String
    w
            [String]
    _ -> Bool -> String -> Bool
    forall a b. a -> b -> a
    const Bool
    True

    -- | Generated bash shell completion script
    bashCompletionScript :: String -> String -> String
    bashCompletionScript :: String -> ShowS
    bashCompletionScript String
    prog String
    progn = [String] -> String
    unlines
      [ String
    "_" String -> ShowS
    forall a. [a] -> [a] -> [a]
    ++ String
    progn String -> ShowS
    forall a. [a] -> [a] -> [a]
    ++ String
    "()"
      , String
    "{"
      , String
    "    local CMDLINE"
      , String
    "    local IFS=$'\\n'"
      , String
    "    CMDLINE=(--bash-completion-index $COMP_CWORD)"
      , String
    ""
      , String
    "    for arg in ${COMP_WORDS[@]}; do"
      , String
    "        CMDLINE=(${CMDLINE[@]} --bash-completion-word $arg)"
      , String
    "    done"
      , String
    ""
      , String
    "    COMPREPLY=( $(" String -> ShowS
    forall a. [a] -> [a] -> [a]
    ++ String
    prog String -> ShowS
    forall a. [a] -> [a] -> [a]
    ++ String
    " \"${CMDLINE[@]}\") )"
      , String
    "}"
      , String
    ""
      , String
    "complete -o filenames -F _" String -> ShowS
    forall a. [a] -> [a] -> [a]
    ++ String
    progn String -> ShowS
    forall a. [a] -> [a] -> [a]
    ++ String
    " " String -> ShowS
    forall a. [a] -> [a] -> [a]
    ++ String
    progn ]

    {-
    /Note/: Fish Shell

    Derived from Drezil's post in #169.

    @
    commandline
    -c or --cut-at-cursor only print selection up until the current cursor position
    -o or --tokenize tokenize the selection and print one string-type token per line
    @

    We tokenize so that the call to count (and hence --bash-completion-index)
    gets the right number use cut-at-curstor to not bother sending anything
    after the cursor position, which allows for completion of the middle of
    words.

    Tab characters separate items from descriptions.
    -}

    -- | Generated fish shell completion script
    fishCompletionScript :: String -> String -> String
    fishCompletionScript :: String -> ShowS
    fishCompletionScript String
    prog String
    progn = [String] -> String
    unlines
      [ String
    " function _" String -> ShowS
    forall a. [a] -> [a] -> [a]
    ++ String
    progn
      , String
    "    set -l cl (commandline --tokenize --current-process)"
      , String
    "    # Hack around fish issue #3934"
      , String
    "    set -l cn (commandline --tokenize --cut-at-cursor --current-process)"
      , String
    "    set -l cn (count $cn)"
      , String
    "    set -l tmpline --bash-completion-enriched --bash-completion-index $cn"
      , String
    "    for arg in $cl"
      , String
    "      set tmpline $tmpline --bash-completion-word $arg"
      , String
    "    end"
      , String
    "    for opt in (" String -> ShowS
    forall a. [a] -> [a] -> [a]
    ++ String
    prog String -> ShowS
    forall a. [a] -> [a] -> [a]
    ++ String
    " $tmpline)"
      , String
    "      if test -d $opt"
      , String
    "        echo -E \"$opt/\""
      , String
    "      else"
      , String
    "        echo -E \"$opt\""
      , String
    "      end"
      , String
    "    end"
      , String
    "end"
      , String
    ""
      , String
    "complete --no-files --command " String -> ShowS
    forall a. [a] -> [a] -> [a]
    ++ String
    progn String -> ShowS
    forall a. [a] -> [a] -> [a]
    ++ String
    " --arguments '(_"  String -> ShowS
    forall a. [a] -> [a] -> [a]
    ++ String
    progn String -> ShowS
    forall a. [a] -> [a] -> [a]
    ++  String
    ")'"
      ]

    -- | Generated zsh shell completion script
    zshCompletionScript :: String -> String -> String
    zshCompletionScript :: String -> ShowS
    zshCompletionScript String
    prog String
    progn = [String] -> String
    unlines
      [ String
    "#compdef " String -> ShowS
    forall a. [a] -> [a] -> [a]
    ++ String
    progn
      , String
    ""
      , String
    "local request"
      , String
    "local completions"
      , String
    "local word"
      , String
    "local index=$((CURRENT - 1))"
      , String
    ""
      , String
    "request=(--bash-completion-enriched --bash-completion-index $index)"
      , String
    "for arg in ${words[@]}; do"
      , String
    "  request=(${request[@]} --bash-completion-word $arg)"
      , String
    "done"
      , String
    ""
      , String
    "IFS=$'\\n' completions=($( " String -> ShowS
    forall a. [a] -> [a] -> [a]
    ++ String
    prog String -> ShowS
    forall a. [a] -> [a] -> [a]
    ++ String
    " \"${request[@]}\" ))"
      , String
    ""
      , String
    "for word in $completions; do"
      , String
    "  local -a parts"
      , String
    ""
      , String
    "  # Split the line at a tab if there is one."
      , String
    "  IFS=$'\\t' parts=($( echo $word ))"
      , String
    ""
      , String
    "  if [[ -n $parts[2] ]]; then"
      , String
    "     if [[ $word[1] == \"-\" ]]; then"
      , String
    "       local desc=(\"$parts[1] ($parts[2])\")"
      , String
    "       compadd -d desc -- $parts[1]"
      , String
    "     else"
      , String
    "       local desc=($(print -f  \"%-019s -- %s\" $parts[1] $parts[2]))"
      , String
    "       compadd -l -d desc -- $parts[1]"
      , String
    "     fi"
      , String
    "  else"
      , String
    "    compadd -f -- $word"
      , String
    "  fi"
      , String
    "done"
      ]