diff --git a/CHANGELOG.md b/CHANGELOG.md
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,3 +1,16 @@
+## Version 0.17.0.0 (1 Feb 2022)
+
+- Make tabulation width configurable in usage texts.
+
+- Separate program name and description in ParserHelp type.
+
+- Add `helperWith` function, which can be easily used to
+  localize the help flag.
+
+- Improve usage texts when command names are long.
+
+- Improve Documentation.
+
 ## Version 0.16.1.0 (21 Nov 2020)
 
 - Guard `process` dependency behind an on by default flag.
diff --git a/README.md b/README.md
--- a/README.md
+++ b/README.md
@@ -527,22 +527,6 @@
 global options that apply to all of them. Typical examples are
 version control systems like `git`, or build tools like `cabal`.
 
-A command can be created using the `subparser` builder (or `hsubparser`,
-which is identical but for an additional `--help` option on each
-command), and commands can be added with the `command` modifier.
-For example
-
-```haskell
-subparser
-  ( command "add" (info addOptions ( progDesc "Add a file to the repository" ))
- <> command "commit" (info commitOptions ( progDesc "Record changes to the repository" ))
-  )
-```
-
-Each command takes a full `ParserInfo` structure, which will be
-used to extract a description for this command when generating a
-help text.
-
 Note that all the parsers appearing in a command need to have the
 same type.  For this reason, it is often best to use a sum type
 which has the same structure as the command itself. For example,
@@ -559,6 +543,22 @@
   ...
 ```
 
+A command can then be created using the `subparser` builder (or
+`hsubparser`, which is identical but for an additional `--help` option
+on each command), and commands can be added with the `command`
+modifier. For example,
+
+```haskell
+subparser
+  ( command "add" (info addCommand ( progDesc "Add a file to the repository" ))
+ <> command "commit" (info commitCommand ( progDesc "Record changes to the repository" ))
+  )
+```
+
+Each command takes a full `ParserInfo` structure, which will be
+used to extract a description for this command when generating a
+help text.
+
 Alternatively, you can directly return an `IO` action from a parser,
 and execute it using `join` from `Control.Monad`.
 
@@ -702,6 +702,11 @@
 
 ```
 
+**Note**. If an option name is a prefix of another option, then it
+will never be matched when disambiguation is on. See
+[#419](https://github.com/pcapriotti/optparse-applicative/issues/419)
+for more details.
+
 ### Customising the help screen
 
 optparse-applicative has a number of combinators to help customise
@@ -1020,6 +1025,6 @@
  [monoid]: http://hackage.haskell.org/package/base/docs/Data-Monoid.html
  [semigroup]: http://hackage.haskell.org/package/base/docs/Data-Semigroup.html
  [parsec]: http://hackage.haskell.org/package/parsec
- [status]: http://travis-ci.org/pcapriotti/optparse-applicative?branch=master
- [status-png]: https://api.travis-ci.org/pcapriotti/optparse-applicative.svg?branch=master
+ [status]: https://github.com/pcapriotti/optparse-applicative/actions/workflows/haskell-ci.yml
+ [status-png]: https://github.com/pcapriotti/optparse-applicative/workflows/Haskell-CI/badge.svg
  [ansi-wl-pprint]: http://hackage.haskell.org/package/ansi-wl-pprint
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.16.1.0
+version:             0.17.0.0
 synopsis:            Utilities and combinators for parsing command line options
 description:
     optparse-applicative is a haskell library for parsing options
@@ -36,6 +36,7 @@
                      tests/helponemptysub.err.txt
                      tests/long_equals.err.txt
                      tests/formatting.err.txt
+                     tests/formatting-long-subcommand.err.txt
                      tests/nested.err.txt
                      tests/optional.err.txt
                      tests/nested_optional.err.txt
@@ -54,7 +55,9 @@
   GHC==8.2.2,
   GHC==8.4.4,
   GHC==8.6.5,
-  GHC==8.8.1
+  GHC==8.8.4,
+  GHC==8.10.4,
+  GHC==9.0.1
 
 source-repository head
   type:     git
@@ -95,15 +98,15 @@
                      , Options.Applicative.Internal
 
   build-depends:       base                            == 4.*
-                     , transformers                    >= 0.2 && < 0.6
-                     , transformers-compat             >= 0.3 && < 0.7
+                     , transformers                    >= 0.2 && < 0.7
+                     , transformers-compat             >= 0.3 && < 0.8
                      , ansi-wl-pprint                  >= 0.6.8 && < 0.7
 
   if flag(process)
     build-depends:     process                         >= 1.0 && < 1.7
 
   if !impl(ghc >= 8)
-    build-depends:     semigroups                      >= 0.10 && < 0.20
+    build-depends:     semigroups                      >= 0.10 && < 0.21
                      , fail                            == 4.9.*
 
 test-suite tests
@@ -122,6 +125,7 @@
                      , Examples.Commands
                      , Examples.Formatting
                      , Examples.Hello
+                     , Examples.LongSub
 
   build-depends:       base
                      , optparse-applicative
diff --git a/src/Options/Applicative/Builder.hs b/src/Options/Applicative/Builder.hs
--- a/src/Options/Applicative/Builder.hs
+++ b/src/Options/Applicative/Builder.hs
@@ -1,5 +1,4 @@
 {-# LANGUAGE CPP #-}
-
 module Options.Applicative.Builder (
   -- * Parser builders
   --
@@ -89,6 +88,7 @@
   columns,
   helpLongEquals,
   helpShowGlobals,
+  helpIndent,
   prefs,
   defaultPrefs,
 
@@ -219,7 +219,7 @@
 --
 -- /NOTE/: This builder is more flexible than its name and example
 -- allude. One of the motivating examples for its addition was to
--- used `const` to completely replace the usage text of an option.
+-- use `const` to completely replace the usage text of an option.
 style :: ( Doc -> Doc ) -> Mod f a
 style x = optionMod $ \p ->
   p { propDescMod = Just x }
@@ -273,6 +273,11 @@
 
 -- | Builder for a command parser. The 'command' modifier can be used to
 -- specify individual commands.
+--
+-- By default, sub-parsers allow backtracking to their parent's options when
+-- they are completed. To allow full mixing of parent and sub-parser options,
+-- turn on 'subparserInline'; otherwise, to disable backtracking completely,
+-- use 'noBacktrack'.
 subparser :: Mod CommandFields a -> Parser a
 subparser m = mkParser d g rdr
   where
@@ -385,7 +390,7 @@
 instance Semigroup (InfoMod a) where
   m1 <> m2 = InfoMod $ applyInfoMod m2 . applyInfoMod m1
 
--- | Show a full description in the help text of this parser.
+-- | Show a full description in the help text of this parser (default).
 fullDesc :: InfoMod a
 fullDesc = InfoMod $ \i -> i { infoFullDesc = True }
 
@@ -517,11 +522,16 @@
 helpLongEquals :: PrefsMod
 helpLongEquals = PrefsMod $ \p -> p { prefHelpLongEquals = True }
 
--- | Show global help information in subparser usage
+-- | Show global help information in subparser usage.
 helpShowGlobals :: PrefsMod
-helpShowGlobals = PrefsMod $ \p -> p { prefHelpShowGlobal = True}
+helpShowGlobals = PrefsMod $ \p -> p { prefHelpShowGlobal = True }
 
+-- | Set fill width in help text presentation.
+helpIndent :: Int -> PrefsMod
+helpIndent w = PrefsMod $ \p -> p { prefTabulateFill = w }
 
+
+
 -- | Create a `ParserPrefs` given a modifier
 prefs :: PrefsMod -> ParserPrefs
 prefs m = applyPrefsMod m base
@@ -534,7 +544,8 @@
       , prefBacktrack = Backtrack
       , prefColumns = 80
       , prefHelpLongEquals = False
-      , prefHelpShowGlobal = False }
+      , prefHelpShowGlobal = False
+      , prefTabulateFill = 24 }
 
 -- Convenience shortcuts
 
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
@@ -4,6 +4,7 @@
   --
   -- | This module contains high-level functions to run parsers.
   helper,
+  helperWith,
   hsubparser,
   execParser,
   customExecParser,
@@ -47,16 +48,32 @@
 
 helper :: Parser (a -> a)
 helper =
+  helperWith (mconcat [
+    long "help",
+    short 'h',
+    help "Show this help text"
+  ])
+
+-- | Like helper, but with a minimal set of modifiers that can be extended
+-- as desired.
+--
+-- > opts :: ParserInfo Sample
+-- > opts = info (sample <**> helperWith (mconcat [
+-- >          long "help",
+-- >          short 'h',
+-- >          help "Show this help text",
+-- >          hidden
+-- >        ])) mempty
+helperWith :: Mod OptionFields (a -> a) -> Parser (a -> a)
+helperWith modifiers =
   option helpReader $
     mconcat
-      [ long "help",
-        short 'h',
-        help "Show this help text",
-        value id,
+      [ value id,
         metavar "",
         noGlobal,
         noArgError (ShowHelpText Nothing),
-        hidden
+        hidden,
+        modifiers
       ]
   where
     helpReader = do
@@ -197,9 +214,10 @@
       InfoMsg _
         -> mempty
       _
-        -> usageHelp $ vcatChunks
-          [ pure . parserUsage pprefs (infoParser i) . unwords $ progn : names
-          , fmap (indent 2) . infoProgDesc $ i ]
+        -> mconcat [
+            usageHelp (pure . parserUsage pprefs (infoParser i) . unwords $ progn : names)
+          , descriptionHelp (infoProgDesc i)
+          ]
 
     error_help = errorHelp $ case msg of
       ShowHelpText {}
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
@@ -128,12 +128,9 @@
 paragraph = foldr (chunked (</>) . stringChunk) mempty
           . words
 
-tabulate' :: Int -> [(Doc, Doc)] -> Chunk Doc
-tabulate' _ [] = mempty
-tabulate' size table = pure $ vcat
+-- | Display pairs of strings in a table.
+tabulate :: Int -> [(Doc, Doc)] -> Chunk Doc
+tabulate _ [] = mempty
+tabulate size table = pure $ vcat
   [ indent 2 (fillBreak size key <+> value)
   | (key, value) <- table ]
-
--- | Display pairs of strings in a table.
-tabulate :: [(Doc, Doc)] -> Chunk Doc
-tabulate = tabulate' 24
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,3 +1,4 @@
+{-# LANGUAGE CPP #-}
 module Options.Applicative.Help.Core (
   cmdDesc,
   briefDesc,
@@ -9,6 +10,7 @@
   headerHelp,
   suggestionsHelp,
   usageHelp,
+  descriptionHelp,
   bodyHelp,
   footerHelp,
   globalsHelp,
@@ -23,8 +25,12 @@
 import Data.List (sort, intersperse, groupBy)
 import Data.Foldable (any, foldl')
 import Data.Maybe (maybeToList, catMaybes, fromMaybe)
+#if !MIN_VERSION_base(4,8,0)
 import Data.Monoid (mempty)
+#endif
+#if !MIN_VERSION_base(4,11,0)
 import Data.Semigroup (Semigroup (..))
+#endif
 import Prelude hiding (any)
 
 import Options.Applicative.Common
@@ -83,14 +89,14 @@
    in (modified, wrapping)
 
 -- | Generate descriptions for commands.
-cmdDesc :: Parser a -> [(Maybe String, Chunk Doc)]
-cmdDesc = mapParser desc
+cmdDesc :: ParserPrefs -> Parser a -> [(Maybe String, Chunk Doc)]
+cmdDesc pprefs = mapParser desc
   where
     desc _ opt =
       case optMain opt of
         CmdReader gn cmds p ->
           (,) gn $
-            tabulate
+            tabulate (prefTabulateFill pprefs)
               [ (string cmd, align (extractChunk d))
                 | cmd <- reverse cmds,
                   d <- maybeToList . fmap infoProgDesc $ p cmd
@@ -188,7 +194,7 @@
 
 -- | Common generator for full descriptions and globals
 optionsDesc :: Bool -> ParserPrefs -> Parser a -> Chunk Doc
-optionsDesc global pprefs = tabulate . catMaybes . mapParser doc
+optionsDesc global pprefs = tabulate (prefTabulateFill pprefs) . catMaybes . mapParser doc
   where
     doc info opt = do
       guard . not . isEmpty $ n
@@ -220,6 +226,9 @@
 usageHelp :: Chunk Doc -> ParserHelp
 usageHelp chunk = mempty { helpUsage = chunk }
 
+descriptionHelp :: Chunk Doc -> ParserHelp
+descriptionHelp chunk = mempty { helpDescription = chunk }
+
 bodyHelp :: Chunk Doc -> ParserHelp
 bodyHelp chunk = mempty { helpBody = chunk }
 
@@ -234,7 +243,7 @@
       : (group_title <$> cs)
   where
     def = "Available commands:"
-    cs = groupBy ((==) `on` fst) $ cmdDesc p
+    cs = groupBy ((==) `on` fst) $ cmdDesc pprefs p
 
     group_title a@((n, _) : _) =
       with_title (fromMaybe def n) $
@@ -256,11 +265,12 @@
 -- | Generate option summary.
 parserUsage :: ParserPrefs -> Parser a -> String -> Doc
 parserUsage pprefs p progn =
-  hsep
-    [ string "Usage:",
-      string progn,
-      align (extractChunk (briefDesc pprefs p))
-    ]
+  group $
+    hsep
+      [ string "Usage:",
+        string progn,
+        hangAtIfOver 9 35 (extractChunk (briefDesc pprefs p))
+      ]
 
 -- | Peek at the structure of the rendered tree within.
 --
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,12 +1,16 @@
+{-# LANGUAGE CPP #-}
 module Options.Applicative.Help.Pretty
   ( module Text.PrettyPrint.ANSI.Leijen
   , (.$.)
   , 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)
@@ -21,12 +25,24 @@
 -- | Apply the function if we're not at the
 --   start of our nesting level.
 ifNotAtRoot :: (Doc -> Doc) -> Doc -> Doc
-ifNotAtRoot f doc =
+ifNotAtRoot =
+  ifElseAtRoot id
+
+-- | Apply the function if we're not at the
+--   start of our nesting level.
+ifAtRoot :: (Doc -> Doc) -> Doc -> Doc
+ifAtRoot =
+  flip ifElseAtRoot id
+
+-- | Apply the function if we're not at the
+--   start of our nesting level.
+ifElseAtRoot :: (Doc -> Doc) -> (Doc -> Doc) -> Doc -> Doc
+ifElseAtRoot f g doc =
   Nesting $ \i ->
     Column $ \j ->
       if i == j
-        then doc
-        else f doc
+        then f doc
+        else g doc
 
 
 -- | Render flattened text on this line, or start
@@ -54,3 +70,23 @@
 altSep :: Doc -> Doc -> Doc
 altSep x y =
   group (x <+> char '|' <> line) <//> y
+
+
+-- | Printer hacks to get nice indentation for long commands
+--   and subcommands.
+--
+--   If we're starting this section over the desired width
+--   (usually 1/3 of the ribbon), then we will make a line
+--   break, indent all of the usage, and go.
+--
+--   The ifAtRoot is an interesting clause. If this whole
+--   operation is put under a `group` then the linebreak
+--   will disappear; then item d will therefore not be at
+--   the starting column, and it won't be indented more.
+hangAtIfOver :: Int -> Int -> Doc -> Doc
+hangAtIfOver i j d =
+  Column $ \k ->
+    if k <= j then
+      align d
+    else
+      linebreak <> ifAtRoot (indent i) d
diff --git a/src/Options/Applicative/Help/Types.hs b/src/Options/Applicative/Help/Types.hs
--- a/src/Options/Applicative/Help/Types.hs
+++ b/src/Options/Applicative/Help/Types.hs
@@ -14,26 +14,30 @@
   , helpSuggestions :: Chunk Doc
   , helpHeader :: Chunk Doc
   , helpUsage :: Chunk Doc
+  , helpDescription :: Chunk Doc
   , helpBody :: Chunk Doc
   , helpGlobals :: Chunk Doc
-  , helpFooter :: Chunk Doc }
+  , helpFooter :: Chunk Doc
+  }
 
 instance Show ParserHelp where
   showsPrec _ h = showString (renderHelp 80 h)
 
 instance Monoid ParserHelp where
-  mempty = ParserHelp mempty mempty mempty mempty mempty mempty mempty
+  mempty = ParserHelp mempty mempty mempty mempty mempty mempty mempty mempty
   mappend = (<>)
 
 instance Semigroup ParserHelp where
-  (ParserHelp e1 s1 h1 u1 b1 g1 f1) <> (ParserHelp e2 s2 h2 u2 b2 g2 f2)
+  (ParserHelp e1 s1 h1 u1 d1 b1 g1 f1) <> (ParserHelp e2 s2 h2 u2 d2 b2 g2 f2)
     = ParserHelp (mappend e1 e2) (mappend s1 s2)
                  (mappend h1 h2) (mappend u1 u2)
-                 (mappend b1 b2) (mappend g1 g2)
-                 (mappend f1 f2)
+                 (mappend d1 d2) (mappend b1 b2)
+                 (mappend g1 g2) (mappend f1 f2)
 
 helpText :: ParserHelp -> Doc
-helpText (ParserHelp e s h u b g f) = extractChunk . vsepChunks $ [e, s, h, u, b, g, f]
+helpText (ParserHelp e s h u d b g f) =
+  extractChunk $
+    vsepChunks [e, s, h, u, fmap (indent 2) d, b, g, f]
 
 -- | Convert a help text to 'String'.
 renderHelp :: Int -> ParserHelp -> String
diff --git a/src/Options/Applicative/NonEmpty.hs b/src/Options/Applicative/NonEmpty.hs
--- a/src/Options/Applicative/NonEmpty.hs
+++ b/src/Options/Applicative/NonEmpty.hs
@@ -1,4 +1,3 @@
-{-# LANGUAGE CPP, Rank2Types, ExistentialQuantification #-}
 module Options.Applicative.NonEmpty (
   some1
 ) where
diff --git a/src/Options/Applicative/Types.hs b/src/Options/Applicative/Types.hs
--- a/src/Options/Applicative/Types.hs
+++ b/src/Options/Applicative/Types.hs
@@ -125,7 +125,8 @@
                                   -- single space (default: False)
   , prefHelpShowGlobal :: Bool    -- ^ when displaying subparsers' usage help,
                                   -- show parent options under a "global options"
-                                  -- section (default: True)
+                                  -- section (default: False)
+  , prefTabulateFill ::Int       -- ^ Indentation width for tables
   } deriving (Eq, Show)
 
 data OptName = OptShort !Char
diff --git a/tests/Examples/LongSub.hs b/tests/Examples/LongSub.hs
new file mode 100644
--- /dev/null
+++ b/tests/Examples/LongSub.hs
@@ -0,0 +1,34 @@
+{-# LANGUAGE CPP #-}
+module Examples.LongSub where
+
+import Data.Monoid
+import Options.Applicative
+
+#if __GLASGOW_HASKELL__ <= 702
+(<>) :: Monoid a => a -> a -> a
+(<>) = mappend
+#endif
+
+data Sample
+  = Hello [String]
+  | Goodbye
+  deriving (Eq, Show)
+
+hello :: Parser Sample
+hello =
+  Hello
+    <$> many (argument str (metavar "TARGET..."))
+    <*  switch (long "first-flag")
+    <*  switch (long "second-flag")
+    <*  switch (long "third-flag")
+    <*  switch (long "fourth-flag")
+
+sample :: Parser Sample
+sample = hsubparser
+       ( command "hello-very-long-sub"
+         (info hello
+               (progDesc "Print greeting"))
+       )
+
+opts :: ParserInfo Sample
+opts = info (sample <**> helper) idm
diff --git a/tests/cabal.err.txt b/tests/cabal.err.txt
--- a/tests/cabal.err.txt
+++ b/tests/cabal.err.txt
@@ -1,4 +1,5 @@
 Usage: cabal configure [--enable-tests] [-f|--flags FLAGS]
+
   Prepare to build the package
 
 Available options:
diff --git a/tests/formatting-long-subcommand.err.txt b/tests/formatting-long-subcommand.err.txt
new file mode 100644
--- /dev/null
+++ b/tests/formatting-long-subcommand.err.txt
@@ -0,0 +1,9 @@
+Usage: formatting-long-subcommand hello-very-long-sub 
+         [TARGET...] [--first-flag] 
+         [--second-flag] [--third-flag] 
+         [--fourth-flag]
+
+  Print greeting
+
+Available options:
+  -h,--help                Show this help text
diff --git a/tests/formatting.err.txt b/tests/formatting.err.txt
--- a/tests/formatting.err.txt
+++ b/tests/formatting.err.txt
@@ -1,4 +1,5 @@
 Usage: formatting [-t|--test FOO_BAR_BAZ_LONG_METAVARIABLE]
+
   This is a very long program description. This
   text should be automatically wrapped to fit the
   size of the terminal
diff --git a/tests/hello.err.txt b/tests/hello.err.txt
--- a/tests/hello.err.txt
+++ b/tests/hello.err.txt
@@ -1,6 +1,7 @@
 hello - a test for optparse-applicative
 
 Usage: hello --hello TARGET [-q|--quiet] [--repeat INT]
+
   Print a greeting for TARGET
 
 Available options:
diff --git a/tests/test.hs b/tests/test.hs
--- a/tests/test.hs
+++ b/tests/test.hs
@@ -9,6 +9,7 @@
 import qualified Examples.Cabal as Cabal
 import qualified Examples.Alternatives as Alternatives
 import qualified Examples.Formatting as Formatting
+import qualified Examples.LongSub as LongSub
 
 import           Control.Applicative
 import           Control.Monad
@@ -890,6 +891,18 @@
     pre = run i ["--help"]
     post = run i ["--help", "not-a-command"]
   in grabHelpMessage pre === grabHelpMessage post
+
+
+prop_long_command_line_flow :: Property
+prop_long_command_line_flow = once $
+  let p = LongSub.sample <**> helper
+      i = info p
+        ( progDesc (concat
+            [ "This is a very long program description. "
+            , "This text should be automatically wrapped "
+            , "to fit the size of the terminal" ]) )
+  in checkHelpTextWith ExitSuccess (prefs (columns 50)) "formatting-long-subcommand" i ["hello-very-long-sub", "--help"]
+
 
 ---
 
