diff --git a/CHANGELOG.md b/CHANGELOG.md
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,3 +1,17 @@
+## Version 0.17.1.0 (21 May 2023)
+
+- Widen bounds for `ansi-wl-pprint`. This supports the use of `prettyprinter`
+  in a non-breaking way, as the `ansi-wl-pprint > 1.0` support the newer
+  library.
+
+- Export `helpIndent` from `Options.Applicative`.
+
+- Export completion script generators from `Options.Applicative.BashCompletion`.
+
+- Add `simpleVersioner` utility for adding a '--version' option to a parser.
+
+- Improve documentation.
+
 ## Version 0.17.0.0 (1 Feb 2022)
 
 - Make tabulation width configurable in usage texts.
diff --git a/README.md b/README.md
--- a/README.md
+++ b/README.md
@@ -1,7 +1,6 @@
 # optparse-applicative
 
 [![Continuous Integration status][status-png]][status]
-[![Hackage matrix][hackage-matrix-png]][hackage-matrix]
 [![Hackage page (downloads and API reference)][hackage-png]][hackage]
 [![Hackage-Deps][hackage-deps-png]][hackage-deps]
 
@@ -75,7 +74,6 @@
 
 ```haskell
 import Options.Applicative
-import Data.Semigroup ((<>))
 
 data Sample = Sample
   { hello      :: String
@@ -303,8 +301,15 @@
 parsers are also able to be composed with standard combinators. For
 example: `optional :: Alternative f => f a -> f (Maybe a)` will
 mean the user is not required to provide input for the affected
-`Parser`.
+`Parser`. For example, the following parser will return `Nothing`
+instead of failing if the user doesn't supply an `output` option:
 
+```haskell
+optional $ strOption
+  ( long "output"
+ <> metavar "DIRECTORY" )
+```
+
 ### Running parsers
 
 Before we can run a `Parser`, we need to wrap it into a `ParserInfo`
@@ -1018,8 +1023,6 @@
  [blog]: http://paolocapriotti.com/blog/2012/04/27/applicative-option-parser/
  [hackage]: http://hackage.haskell.org/package/optparse-applicative
  [hackage-png]: http://img.shields.io/hackage/v/optparse-applicative.svg
- [hackage-matrix]: https://matrix.hackage.haskell.org/package/optparse-applicative
- [hackage-matrix-png]: https://matrix.hackage.haskell.org/api/v2/packages/optparse-applicative/badge
  [hackage-deps]: http://packdeps.haskellers.com/reverse/optparse-applicative
  [hackage-deps-png]: https://img.shields.io/hackage-deps/v/optparse-applicative.svg
  [monoid]: http://hackage.haskell.org/package/base/docs/Data-Monoid.html
diff --git a/optparse-applicative.cabal b/optparse-applicative.cabal
--- a/optparse-applicative.cabal
+++ b/optparse-applicative.cabal
@@ -1,5 +1,5 @@
 name:                optparse-applicative
-version:             0.17.0.0
+version:             0.17.1.0
 synopsis:            Utilities and combinators for parsing command line options
 description:
     optparse-applicative is a haskell library for parsing options
@@ -45,19 +45,22 @@
 homepage:            https://github.com/pcapriotti/optparse-applicative
 bug-reports:         https://github.com/pcapriotti/optparse-applicative/issues
 tested-with:
-  GHC==7.0.4,
-  GHC==7.2.2,
-  GHC==7.4.2,
-  GHC==7.6.3,
-  GHC==7.8.4,
-  GHC==7.10.3,
-  GHC==8.0.2,
-  GHC==8.2.2,
-  GHC==8.4.4,
-  GHC==8.6.5,
-  GHC==8.8.4,
-  GHC==8.10.4,
-  GHC==9.0.1
+  GHC==9.6.1
+  GHC==9.4.4
+  GHC==9.2.7
+  GHC==9.0.2
+  GHC==8.10.7
+  GHC==8.8.4
+  GHC==8.6.5
+  GHC==8.4.4
+  GHC==8.2.2
+  GHC==8.0.2
+  GHC==7.10.3
+  GHC==7.8.4
+  GHC==7.6.3
+  GHC==7.4.2
+  GHC==7.2.2
+  GHC==7.0.4
 
 source-repository head
   type:     git
@@ -100,7 +103,7 @@
   build-depends:       base                            == 4.*
                      , transformers                    >= 0.2 && < 0.7
                      , transformers-compat             >= 0.3 && < 0.8
-                     , ansi-wl-pprint                  >= 0.6.8 && < 0.7
+                     , ansi-wl-pprint                  >= 0.6.8 && < 1.1
 
   if flag(process)
     build-depends:     process                         >= 1.0 && < 1.7
diff --git a/src/Options/Applicative.hs b/src/Options/Applicative.hs
--- a/src/Options/Applicative.hs
+++ b/src/Options/Applicative.hs
@@ -74,6 +74,7 @@
   abortOption,
   infoOption,
   helper,
+  simpleVersioner,
 
   -- ** Modifiers
   --
@@ -197,6 +198,7 @@
   columns,
   helpLongEquals,
   helpShowGlobals,
+  helpIndent,
   defaultPrefs,
 
   -- * Completions
diff --git a/src/Options/Applicative/BashCompletion.hs b/src/Options/Applicative/BashCompletion.hs
--- a/src/Options/Applicative/BashCompletion.hs
+++ b/src/Options/Applicative/BashCompletion.hs
@@ -1,10 +1,15 @@
+{-# OPTIONS_GHC -fno-warn-warnings-deprecations #-}
 -- | 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
+  ( bashCompletionParser,
+
+    bashCompletionScript,
+    fishCompletionScript,
+    zshCompletionScript,
   ) where
 
 import Control.Applicative
@@ -34,11 +39,15 @@
 bashCompletionParser :: ParserInfo a -> ParserPrefs -> Parser CompletionResult
 bashCompletionParser pinfo pprefs = complParser
   where
-    failure opts = CompletionResult
-      { execCompletion = \progn -> unlines <$> opts progn }
+    returnCompletions opts =
+      CompletionResult $
+        \progn -> unlines <$> opts progn
 
+    scriptRequest =
+      CompletionResult . fmap pure
+
     complParser = asum
-      [ failure <$>
+      [ returnCompletions <$>
         (  bashCompletionQuery pinfo pprefs
         -- To get rich completions, one just needs the first
         -- command. To customise the lengths, use either of
@@ -53,15 +62,13 @@
         <*> (many . strOption) (long "bash-completion-word"
                                   `mappend` internal)
         <*> option auto (long "bash-completion-index" `mappend` internal) )
-      , failure <$>
-          (bashCompletionScript <$>
-            strOption (long "bash-completion-script" `mappend` internal))
-      , failure <$>
-          (fishCompletionScript <$>
-            strOption (long "fish-completion-script" `mappend` internal))
-      , failure <$>
-          (zshCompletionScript <$>
-            strOption (long "zsh-completion-script" `mappend` internal))
+
+      , scriptRequest . bashCompletionScript <$>
+            strOption (long "bash-completion-script" `mappend` internal)
+      , scriptRequest . fishCompletionScript <$>
+            strOption (long "fish-completion-script" `mappend` internal)
+      , scriptRequest . zshCompletionScript <$>
+            strOption (long "zsh-completion-script" `mappend` internal)
       ]
 
 bashCompletionQuery :: ParserInfo a -> ParserPrefs -> Richness -> [String] -> Int -> String -> IO [String]
@@ -161,8 +168,9 @@
         w:_ -> isPrefixOf w
         _ -> const True
 
-bashCompletionScript :: String -> String -> IO [String]
-bashCompletionScript prog progn = return
+-- | Generated bash shell completion script
+bashCompletionScript :: String -> String -> String
+bashCompletionScript prog progn = unlines
   [ "_" ++ progn ++ "()"
   , "{"
   , "    local CMDLINE"
@@ -196,8 +204,10 @@
 
 Tab characters separate items from descriptions.
 -}
-fishCompletionScript :: String -> String -> IO [String]
-fishCompletionScript prog progn = return
+
+-- | Generated fish shell completion script 
+fishCompletionScript :: String -> String -> String
+fishCompletionScript prog progn = unlines
   [ " function _" ++ progn
   , "    set -l cl (commandline --tokenize --current-process)"
   , "    # Hack around fish issue #3934"
@@ -219,8 +229,9 @@
   , "complete --no-files --command " ++ progn ++ " --arguments '(_"  ++ progn ++  ")'"
   ]
 
-zshCompletionScript :: String -> String -> IO [String]
-zshCompletionScript prog progn = return
+-- | Generated zsh shell completion script
+zshCompletionScript :: String -> String -> String
+zshCompletionScript prog progn = unlines
   [ "#compdef " ++ progn
   , ""
   , "local request"
diff --git a/src/Options/Applicative/Builder/Completer.hs b/src/Options/Applicative/Builder/Completer.hs
--- a/src/Options/Applicative/Builder/Completer.hs
+++ b/src/Options/Applicative/Builder/Completer.hs
@@ -6,6 +6,8 @@
   , listIOCompleter
   , listCompleter
   , bashCompleter
+
+  , requote
   ) where
 
 import Control.Applicative
diff --git a/src/Options/Applicative/Extra.hs b/src/Options/Applicative/Extra.hs
--- a/src/Options/Applicative/Extra.hs
+++ b/src/Options/Applicative/Extra.hs
@@ -6,6 +6,7 @@
   helper,
   helperWith,
   hsubparser,
+  simpleVersioner,
   execParser,
   customExecParser,
   execParserPure,
@@ -93,6 +94,19 @@
     add_helper pinfo = pinfo
       { infoParser = infoParser pinfo <**> helper }
 
+-- | A hidden \"--version\" option that displays the version.
+--
+-- > opts :: ParserInfo Sample
+-- > opts = info (sample <**> simpleVersioner "v1.2.3") mempty
+simpleVersioner :: String -- ^ Version string to be shown
+                -> Parser (a -> a)
+simpleVersioner version = infoOption version $
+  mconcat
+    [ long "version"
+    , help "Show version information"
+    , hidden
+    ]
+
 -- | Run a program description.
 --
 -- Parse command line arguments. Display help text and exit if any parse error
@@ -153,7 +167,7 @@
 --
 -- This function can be used, for example, to show the help text for a parser:
 --
--- @handleParseResult . Failure $ parserFailure pprefs pinfo ShowHelpText mempty@
+-- @handleParseResult . Failure $ parserFailure pprefs pinfo (ShowHelpText Nothing) mempty@
 parserFailure :: ParserPrefs -> ParserInfo a
               -> ParseError -> [Context]
               -> ParserFailure ParserHelp
diff --git a/src/Options/Applicative/Help/Chunk.hs b/src/Options/Applicative/Help/Chunk.hs
--- a/src/Options/Applicative/Help/Chunk.hs
+++ b/src/Options/Applicative/Help/Chunk.hs
@@ -1,3 +1,4 @@
+{-# OPTIONS_GHC -fno-warn-warnings-deprecations #-}
 module Options.Applicative.Help.Chunk
   ( Chunk(..)
   , chunked
diff --git a/src/Options/Applicative/Help/Core.hs b/src/Options/Applicative/Help/Core.hs
--- a/src/Options/Applicative/Help/Core.hs
+++ b/src/Options/Applicative/Help/Core.hs
@@ -1,4 +1,5 @@
 {-# LANGUAGE CPP #-}
+{-# OPTIONS_GHC -fno-warn-warnings-deprecations #-}
 module Options.Applicative.Help.Core (
   cmdDesc,
   briefDesc,
@@ -24,7 +25,7 @@
 import Data.Function (on)
 import Data.List (sort, intersperse, groupBy)
 import Data.Foldable (any, foldl')
-import Data.Maybe (maybeToList, catMaybes, fromMaybe)
+import Data.Maybe (catMaybes, fromMaybe, maybeToList)
 #if !MIN_VERSION_base(4,8,0)
 import Data.Monoid (mempty)
 #endif
diff --git a/src/Options/Applicative/Help/Pretty.hs b/src/Options/Applicative/Help/Pretty.hs
--- a/src/Options/Applicative/Help/Pretty.hs
+++ b/src/Options/Applicative/Help/Pretty.hs
@@ -1,23 +1,37 @@
 {-# LANGUAGE CPP #-}
+{-# OPTIONS_GHC -fno-warn-warnings-deprecations #-}
 module Options.Applicative.Help.Pretty
   ( module Text.PrettyPrint.ANSI.Leijen
+  , Doc
+  , indent
+  , renderPretty
+  , displayS
   , (.$.)
   , groupOrNestLine
   , altSep
   , hangAtIfOver
   ) where
 
-import           Control.Applicative
 #if !MIN_VERSION_base(4,11,0)
 import           Data.Semigroup ((<>))
 #endif
 
-import           Text.PrettyPrint.ANSI.Leijen hiding ((<$>), (<>), columns)
-import           Text.PrettyPrint.ANSI.Leijen.Internal (Doc (..), flatten)
+import           Text.PrettyPrint.ANSI.Leijen hiding (Doc, (<$>), (<>), columns, indent, renderPretty, displayS)
 import qualified Text.PrettyPrint.ANSI.Leijen as PP
 
 import           Prelude
 
+type Doc = PP.Doc
+
+indent :: Int -> PP.Doc -> PP.Doc
+indent = PP.indent
+
+renderPretty :: Float -> Int -> PP.Doc -> SimpleDoc
+renderPretty = PP.renderPretty
+
+displayS :: SimpleDoc -> ShowS
+displayS = PP.displayS
+
 (.$.) :: Doc -> Doc -> Doc
 (.$.) = (PP.<$>)
 
@@ -38,8 +52,8 @@
 --   start of our nesting level.
 ifElseAtRoot :: (Doc -> Doc) -> (Doc -> Doc) -> Doc -> Doc
 ifElseAtRoot f g doc =
-  Nesting $ \i ->
-    Column $ \j ->
+  nesting $ \i ->
+    column $ \j ->
       if i == j
         then f doc
         else g doc
@@ -52,9 +66,7 @@
 --   group.
 groupOrNestLine :: Doc -> Doc
 groupOrNestLine =
-  Union
-    <$> flatten
-    <*> ifNotAtRoot (line <>) . nest 2
+  group . ifNotAtRoot (linebreak <>) . nest 2
 
 
 -- | Separate items in an alternative with a pipe.
@@ -85,7 +97,7 @@
 --   the starting column, and it won't be indented more.
 hangAtIfOver :: Int -> Int -> Doc -> Doc
 hangAtIfOver i j d =
-  Column $ \k ->
+  column $ \k ->
     if k <= j then
       align d
     else
diff --git a/tests/Examples/Cabal.hs b/tests/Examples/Cabal.hs
--- a/tests/Examples/Cabal.hs
+++ b/tests/Examples/Cabal.hs
@@ -39,10 +39,6 @@
   { buildDir :: FilePath }
   deriving Show
 
-version :: Parser (a -> a)
-version = infoOption "0.0.0"
-  (  long "version"
-  <> help "Print version information" )
 
 parser :: Parser Args
 parser = runA $ proc () -> do
@@ -60,7 +56,7 @@
            <> command "build"
               (info buildParser
                     (progDesc "Make this package ready for installation")) ) -< ()
-  A version >>> A helper -< Args opts cmds
+  A (simpleVersioner "0.0.0") >>> A helper -< Args opts cmds
 
 commonOpts :: Parser CommonOpts
 commonOpts = CommonOpts
diff --git a/tests/cabal.err.txt b/tests/cabal.err.txt
--- a/tests/cabal.err.txt
+++ b/tests/cabal.err.txt
@@ -9,4 +9,4 @@
 
 Global options:
   -v,--verbose LEVEL       Set verbosity to LEVEL
-  --version                Print version information
+  --version                Show version information
diff --git a/tests/test.hs b/tests/test.hs
--- a/tests/test.hs
+++ b/tests/test.hs
@@ -907,12 +907,11 @@
 ---
 
 deriving instance Arbitrary a => Arbitrary (Chunk a)
-deriving instance Eq SimpleDoc
-deriving instance Show SimpleDoc
 
+
 equalDocs :: Float -> Int -> Doc -> Doc -> Property
-equalDocs f w d1 d2 = Doc.renderPretty f w d1
-                  === Doc.renderPretty f w d2
+equalDocs f w d1 d2 = Doc.displayS (Doc.renderPretty f w d1) ""
+                  === Doc.displayS (Doc.renderPretty f w d2) ""
 
 prop_listToChunk_1 :: [String] -> Property
 prop_listToChunk_1 xs = isEmpty (listToChunk xs) === null xs
