Repository: certbot/certbot

Issue:
Disable line wrapping in --text mode
When I run with `--text`, I get these lines as output:

```
Congratulations! You have successfully enabled https://02e645.le-test.hoffman-
andrews.com

You should test your configuration at:
https://www.ssllabs.com/ssltest/analyze.html?d=02e645.le-test.hoffman-
andrews.com
```

These lines are artificially wrapped at 80 characters, even though my terminal is much wider than that. This breaks the links and makes them (a) unclickable and (b) hard to paste into a browser.

I think with `--text`, we shouldn't wrap lines, but leave it to the user's terminal.



Discussion:
This is a good first ticket for a volunteer.  The line wrapping happens in [FileDisplay](https://github.com/letsencrypt/letsencrypt/blob/master/letsencrypt/display/util.py#L202) and [NonineractiveDisplay](https://github.com/letsencrypt/letsencrypt/blob/master/letsencrypt/display/util.py#L449) and should be easy to remove; it'll mostly be a matter of checking that everything looks sane afterwards.

Copied from my comment [here](https://github.com/certbot/certbot/pull/2795#issuecomment-221403893):

So after talking to jsha out of band, we decided that the output above does look pretty bad and we have another solution. Sorry for changing our position on this, but since you've identified all places we use text wrapping in order to write this PR, implemented the new solution should be pretty easy if you're still interested.

The main problem identified in #2754 is we break things like URLs that would normally be clickable in a terminal. `textwrap` has options [break_long_words](https://docs.python.org/2/library/textwrap.html#textwrap.TextWrapper.break_long_words) and [break_on_hyphens](https://docs.python.org/2/library/textwrap.html#textwrap.TextWrapper.break_on_hyphens) which solve this problem. Using the examples, provided [here](https://github.com/certbot/certbot/issues/2754#issue-145527636), output becomes:

```
Congratulations! You have successfully enabled
https://02e645.le-test.hoffman-andrews.com

You should test your configuration at:
https://www.ssllabs.com/ssltest/analyze.html?d=02e645.le-test.hoffman-andrews.com
```

which solves the problem and still allows for text wrap to make the output look a little better.


Resolving patch:
diff --git a/certbot/display/util.py b/certbot/display/util.py
--- a/certbot/display/util.py
+++ b/certbot/display/util.py
@@ -41,10 +41,15 @@ def _wrap_lines(msg):
     """
     lines = msg.splitlines()
     fixed_l = []
+
     for line in lines:
-        fixed_l.append(textwrap.fill(line, 80))
-    return os.linesep.join(fixed_l)
+        fixed_l.append(textwrap.fill(
+            line,
+            80,
+            break_long_words=False,
+            break_on_hyphens=False))
 
+    return os.linesep.join(fixed_l)
 
 @zope.interface.implementer(interfaces.IDisplay)
 class NcursesDisplay(object):
@@ -265,7 +270,11 @@ def input(self, message, **unused_kwargs):
 
         """
         ans = raw_input(
-            textwrap.fill("%s (Enter 'c' to cancel): " % message, 80))
+            textwrap.fill(
+                "%s (Enter 'c' to cancel): " % message,
+                80,
+                break_long_words=False,
+                break_on_hyphens=False))
 
         if ans == "c" or ans == "C":
             return CANCEL, "-1"
@@ -402,7 +411,11 @@ def _print_menu(self, message, choices):
         # Write out the menu choices
         for i, desc in enumerate(choices, 1):
             self.outfile.write(
-                textwrap.fill("{num}: {desc}".format(num=i, desc=desc), 80))
+                textwrap.fill(
+                    "{num}: {desc}".format(num=i, desc=desc),
+                    80,
+                    break_long_words=False,
+                    break_on_hyphens=False))
 
             # Keep this outside of the textwrap
             self.outfile.write(os.linesep)
diff --git a/certbot/reporter.py b/certbot/reporter.py
--- a/certbot/reporter.py
+++ b/certbot/reporter.py
@@ -82,10 +82,15 @@ def print_messages(self):
                     print(le_util.ANSI_SGR_BOLD)
                 print('IMPORTANT NOTES:')
             first_wrapper = textwrap.TextWrapper(
-                initial_indent=' - ', subsequent_indent=(' ' * 3))
+                initial_indent=' - ',
+                subsequent_indent=(' ' * 3),
+                break_long_words=False,
+                break_on_hyphens=False)
             next_wrapper = textwrap.TextWrapper(
                 initial_indent=first_wrapper.subsequent_indent,
-                subsequent_indent=first_wrapper.subsequent_indent)
+                subsequent_indent=first_wrapper.subsequent_indent,
+                break_long_words=False,
+                break_on_hyphens=False)
         while not self.messages.empty():
             msg = self.messages.get()
             if self.config.quiet:


Test patch: