Repository: pallets/click

Issue:
Make option format replace newlines with spaces.
#834 
Remade to point 7.x


Discussion:
Turns out the underlying `wrap_text` function already takes a `preserve_paragraphs` option, but it's not enabled for option help text right now. This enables the behavior in the command help text where `\n\n` is preserved and each paragraph is wrapped separately.

I'll submit a new PR that rolls this change back and uses `preserve_paragraphs` instead.

Resolving patch:
diff --git a/click/core.py b/click/core.py
--- a/click/core.py
+++ b/click/core.py
@@ -945,8 +945,7 @@ def format_options(self, ctx, formatter):
         for param in self.get_params(ctx):
             rv = param.get_help_record(ctx)
             if rv is not None:
-                part_a, part_b = rv
-                opts.append((part_a, part_b.replace('\n', ' ')))
+                opts.append(rv)
 
         if opts:
             with formatter.section('Options'):
diff --git a/click/formatting.py b/click/formatting.py
--- a/click/formatting.py
+++ b/click/formatting.py
@@ -198,12 +198,14 @@ def write_dl(self, rows, col_max=30, col_spacing=2):
                 self.write(' ' * (first_col + self.current_indent))
 
             text_width = max(self.width - first_col - 2, 10)
-            lines = iter(wrap_text(second, text_width).splitlines())
+            wrapped_text = wrap_text(second, text_width, preserve_paragraphs=True)
+            lines = wrapped_text.splitlines()
+
             if lines:
-                self.write(next(lines) + '\n')
-                for line in lines:
-                    self.write('%*s%s\n' % (
-                        first_col + self.current_indent, '', line))
+                self.write(lines[0] + '\n')
+
+                for line in lines[1:]:
+                    self.write('%*s%s\n' % (first_col + self.current_indent, '', line))
             else:
                 self.write('\n')
 


Test patch:
diff --git a/tests/test_options.py b/tests/test_options.py
--- a/tests/test_options.py
+++ b/tests/test_options.py
@@ -408,22 +408,30 @@ def cmd(foo):
     assert result.output == 'Apple\n'
 
 
-def test_multiline_help(runner):
-    @click.command()
-    @click.option('--foo', help="""
-        hello
-
-        i am
-
-        multiline
-    """)
-    def cmd(foo):
-        click.echo(foo)
+def test_option_help_preserve_paragraphs(runner):
+    @click.command()
+    @click.option(
+        "-C",
+        "--config",
+        type=click.Path(),
+        help="""Configuration file to use.
+        
+        If not given, the environment variable CONFIG_FILE is consulted
+        and used if set. If neither are given, a default configuration
+        file is loaded.""",
+    )
+    def cmd(config):
+        pass
 
-    result = runner.invoke(cmd, ['--help'])
+    result = runner.invoke(cmd, ['--help'], )
     assert result.exit_code == 0
-    out = result.output.splitlines()
-    assert '  --foo TEXT  hello  i am  multiline' in out
+    assert (
+        "  -C, --config PATH  Configuration file to use.\n"
+        "{i}\n"
+        "{i}If not given, the environment variable CONFIG_FILE is\n"
+        "{i}consulted and used if set. If neither are given, a default\n"
+        "{i}configuration file is loaded.".format(i=" " * 21)
+    ) in result.output
 
 def test_argument_custom_class(runner):
     class CustomArgument(click.Argument):