We are currently solving the following issue within our repository. Here is the issue text:
--- BEGIN ISSUE ---
`HelpFormatter.write_text()` is not using all the available line width
`HelpFormatter.write_text()` uses the function `wrap_text(text, width, initial_indent, ...)` internally. This function expects `width` to be the line width **including** the eventual indentation. `HelpFormatter.write_text()` gets this wrong and passes `self.width - self.current_indent` instead of just `self.width`.



--- END ISSUE ---

Below are some code segments, each from a relevant file. One or more of these files may contain bugs.
--- BEGIN FILES ---
Path: `src/click/formatting.py`
Content:
```
1 import typing as t
2 from contextlib import contextmanager
3 from gettext import gettext as _
4 
5 from ._compat import term_len
6 from .parser import split_opt
7 
8 # Can force a width.  This is used by the test system
9 FORCED_WIDTH: t.Optional[int] = None
10 
11 
12 def measure_table(rows: t.Iterable[t.Tuple[str, str]]) -> t.Tuple[int, ...]:
13     widths: t.Dict[int, int] = {}
14 
15     for row in rows:
16         for idx, col in enumerate(row):
17             widths[idx] = max(widths.get(idx, 0), term_len(col))
18 
19     return tuple(y for x, y in sorted(widths.items()))
20 
21 
22 def iter_rows(
23     rows: t.Iterable[t.Tuple[str, str]], col_count: int
24 ) -> t.Iterator[t.Tuple[str, ...]]:
25     for row in rows:
26         yield row + ("",) * (col_count - len(row))
27 
28 
29 def wrap_text(
30     text: str,
31     width: int = 78,
32     initial_indent: str = "",
33     subsequent_indent: str = "",
34     preserve_paragraphs: bool = False,
35 ) -> str:
36     """A helper function that intelligently wraps text.  By default, it
37     assumes that it operates on a single paragraph of text but if the
38     `preserve_paragraphs` parameter is provided it will intelligently
39     handle paragraphs (defined by two empty lines).
40 
41     If paragraphs are handled, a paragraph can be prefixed with an empty
42     line containing the ``\\b`` character (``\\x08``) to indicate that
43     no rewrapping should happen in that block.
44 
45     :param text: the text that should be rewrapped.
46     :param width: the maximum width for the text.
47     :param initial_indent: the initial indent that should be placed on the
48                            first line as a string.
49     :param subsequent_indent: the indent string that should be placed on
50                               each consecutive line.
51     :param preserve_paragraphs: if this flag is set then the wrapping will
52                                 intelligently handle paragraphs.
53     """
54     from ._textwrap import TextWrapper
55 
56     text = text.expandtabs()
57     wrapper = TextWrapper(
58         width,
59         initial_indent=initial_indent,
60         subsequent_indent=subsequent_indent,
61         replace_whitespace=False,
62     )
63     if not preserve_paragraphs:
64         return wrapper.fill(text)
65 
66     p: t.List[t.Tuple[int, bool, str]] = []
67     buf: t.List[str] = []
68     indent = None
69 
70     def _flush_par() -> None:
71         if not buf:
72             return
73         if buf[0].strip() == "\b":
74             p.append((indent or 0, True, "\n".join(buf[1:])))
75         else:
76             p.append((indent or 0, False, " ".join(buf)))
77         del buf[:]
78 
79     for line in text.splitlines():
80         if not line:
81             _flush_par()
82             indent = None
83         else:
84             if indent is None:
85                 orig_len = term_len(line)
86                 line = line.lstrip()
87                 indent = orig_len - term_len(line)
88             buf.append(line)
89     _flush_par()
90 
91     rv = []
92     for indent, raw, text in p:
93         with wrapper.extra_indent(" " * indent):
94             if raw:
95                 rv.append(wrapper.indent_only(text))
96             else:
97                 rv.append(wrapper.fill(text))
98 
99     return "\n\n".join(rv)
100 
101 
102 class HelpFormatter:
103     """This class helps with formatting text-based help pages.  It's
104     usually just needed for very special internal cases, but it's also
105     exposed so that developers can write their own fancy outputs.
106 
107     At present, it always writes into memory.
108 
109     :param indent_increment: the additional increment for each level.
110     :param width: the width for the text.  This defaults to the terminal
111                   width clamped to a maximum of 78.
112     """
113 
114     def __init__(
115         self,
116         indent_increment: int = 2,
117         width: t.Optional[int] = None,
118         max_width: t.Optional[int] = None,
119     ) -> None:
120         import shutil
121 
122         self.indent_increment = indent_increment
123         if max_width is None:
124             max_width = 80
125         if width is None:
126             width = FORCED_WIDTH
127             if width is None:
128                 width = max(min(shutil.get_terminal_size().columns, max_width) - 2, 50)
129         self.width = width
130         self.current_indent = 0
131         self.buffer: t.List[str] = []
132 
133     def write(self, string: str) -> None:
134         """Writes a unicode string into the internal buffer."""
135         self.buffer.append(string)
136 
137     def indent(self) -> None:
138         """Increases the indentation."""
139         self.current_indent += self.indent_increment
140 
141     def dedent(self) -> None:
142         """Decreases the indentation."""
143         self.current_indent -= self.indent_increment
144 
145     def write_usage(
146         self, prog: str, args: str = "", prefix: t.Optional[str] = None
147     ) -> None:
148         """Writes a usage line into the buffer.
149 
150         :param prog: the program name.
151         :param args: whitespace separated list of arguments.
152         :param prefix: The prefix for the first line. Defaults to
153             ``"Usage: "``.
154         """
155         if prefix is None:
156             prefix = f"{_('Usage:')} "
157 
158         usage_prefix = f"{prefix:>{self.current_indent}}{prog} "
159         text_width = self.width - self.current_indent
160 
161         if text_width >= (term_len(usage_prefix) + 20):
162             # The arguments will fit to the right of the prefix.
163             indent = " " * term_len(usage_prefix)
164             self.write(
165                 wrap_text(
166                     args,
167                     text_width,
168                     initial_indent=usage_prefix,
169                     subsequent_indent=indent,
170                 )
171             )
172         else:
173             # The prefix is too long, put the arguments on the next line.
174             self.write(usage_prefix)
175             self.write("\n")
176             indent = " " * (max(self.current_indent, term_len(prefix)) + 4)
177             self.write(
178                 wrap_text(
179                     args, text_width, initial_indent=indent, subsequent_indent=indent
180                 )
181             )
182 
183         self.write("\n")
184 
185     def write_heading(self, heading: str) -> None:
186         """Writes a heading into the buffer."""
187         self.write(f"{'':>{self.current_indent}}{heading}:\n")
188 
189     def write_paragraph(self) -> None:
190         """Writes a paragraph into the buffer."""
191         if self.buffer:
192             self.write("\n")
193 
194     def write_text(self, text: str) -> None:
195         """Writes re-indented text into the buffer.  This rewraps and
196         preserves paragraphs.
197         """
198         text_width = max(self.width - self.current_indent, 11)
199         indent = " " * self.current_indent
200         self.write(
201             wrap_text(
202                 text,
203                 text_width,
204                 initial_indent=indent,
205                 subsequent_indent=indent,
206                 preserve_paragraphs=True,
207             )
208         )
209         self.write("\n")
210 
211     def write_dl(
212         self,
213         rows: t.Sequence[t.Tuple[str, str]],
214         col_max: int = 30,
215         col_spacing: int = 2,
216     ) -> None:
217         """Writes a definition list into the buffer.  This is how options
218         and commands are usually formatted.
219 
220         :param rows: a list of two item tuples for the terms and values.
221         :param col_max: the maximum width of the first column.
222         :param col_spacing: the number of spaces between the first and
223                             second column.
224         """
225         rows = list(rows)
226         widths = measure_table(rows)
227         if len(widths) != 2:
228             raise TypeError("Expected two columns for definition list")
229 
230         first_col = min(widths[0], col_max) + col_spacing
231 
232         for first, second in iter_rows(rows, len(widths)):
233             self.write(f"{'':>{self.current_indent}}{first}")
234             if not second:
235                 self.write("\n")
236                 continue
237             if term_len(first) <= first_col - col_spacing:
238                 self.write(" " * (first_col - term_len(first)))
239             else:
240                 self.write("\n")
241                 self.write(" " * (first_col + self.current_indent))
242 
243             text_width = max(self.width - first_col - 2, 10)
244             wrapped_text = wrap_text(second, text_width, preserve_paragraphs=True)
245             lines = wrapped_text.splitlines()
246 
247             if lines:
248                 self.write(f"{lines[0]}\n")
249 
250                 for line in lines[1:]:
251                     self.write(f"{'':>{first_col + self.current_indent}}{line}\n")
252             else:
253                 self.write("\n")
254 
255     @contextmanager
256     def section(self, name: str) -> t.Iterator[None]:
257         """Helpful context manager that writes a paragraph, a heading,
258         and the indents.
259 
260         :param name: the section name that is written as heading.
261         """
262         self.write_paragraph()
263         self.write_heading(name)
264         self.indent()
265         try:
266             yield
267         finally:
268             self.dedent()
269 
270     @contextmanager
271     def indentation(self) -> t.Iterator[None]:
272         """A context manager that increases the indentation."""
273         self.indent()
274         try:
275             yield
276         finally:
277             self.dedent()
278 
279     def getvalue(self) -> str:
280         """Returns the buffer contents."""
281         return "".join(self.buffer)
282 
283 
284 def join_options(options: t.Sequence[str]) -> t.Tuple[str, bool]:
285     """Given a list of option strings this joins them in the most appropriate
286     way and returns them in the form ``(formatted_string,
287     any_prefix_is_slash)`` where the second item in the tuple is a flag that
288     indicates if any of the option prefixes was a slash.
289     """
290     rv = []
291     any_prefix_is_slash = False
292 
293     for opt in options:
294         prefix = split_opt(opt)[0]
295 
296         if prefix == "/":
297             any_prefix_is_slash = True
298 
299         rv.append((len(prefix), opt))
300 
301     rv.sort(key=lambda x: x[0])
302     return ", ".join(x[1] for x in rv), any_prefix_is_slash
303
```
--- END FILES ---

Please first localize the bug based on the issue statement, and then generate a patch according to the `git diff` format fenced by three backticks.

Here is an example:

```diff
diff --git a/examples/server_async.py b/examples/server_async.py
--- a/examples/server_async.py
+++ b/examples/server_async.py
@@ -313,4 +313,4 @@
 
 
 if __name__ == "__main__":
-    asyncio.run(run_async_server("."), debug=True)
+    asyncio.run(run_async_server(), debug=True)
diff --git a/examples/server_sync.py b/examples/server_sync.py
--- a/examples/server_sync.py
+++ b/examples/server_sync.py
@@ -313,5 +313,5 @@
 
 
 if __name__ == "__main__":
-    server = run_sync_server(".")
+    server = run_sync_server()
     server.shutdown()

```

diff --git a/src/click/formatting.py b/src/click/formatting.py
--- a/src/click/formatting.py
+++ b/src/click/formatting.py
@@ -195,12 +195,11 @@
         """Writes re-indented text into the buffer.  This rewraps and
         preserves paragraphs.
         """
-        text_width = max(self.width - self.current_indent, 11)
         indent = " " * self.current_indent
         self.write(
             wrap_text(
                 text,
-                text_width,
+                self.width,
                 initial_indent=indent,
                 subsequent_indent=indent,
                 preserve_paragraphs=True,

{"golden_diff": "diff --git a/src/click/formatting.py b/src/click/formatting.py\n--- a/src/click/formatting.py\n+++ b/src/click/formatting.py\n@@ -195,12 +195,11 @@\n         \"\"\"Writes re-indented text into the buffer.  This rewraps and\n         preserves paragraphs.\n         \"\"\"\n-        text_width = max(self.width - self.current_indent, 11)\n         indent = \" \" * self.current_indent\n         self.write(\n             wrap_text(\n                 text,\n-                text_width,\n+                self.width,\n                 initial_indent=indent,\n                 subsequent_indent=indent,\n                 preserve_paragraphs=True,\n", "issue": "`HelpFormatter.write_text()` is not using all the available line width\n`HelpFormatter.write_text()` uses the function `wrap_text(text, width, initial_indent, ...)` internally. This function expects `width` to be the line width **including** the eventual indentation. `HelpFormatter.write_text()` gets this wrong and passes `self.width - self.current_indent` instead of just `self.width`.\r\n\r\n\n", "before_files": [{"content": "import typing as t\nfrom contextlib import contextmanager\nfrom gettext import gettext as _\n\nfrom ._compat import term_len\nfrom .parser import split_opt\n\n# Can force a width.  This is used by the test system\nFORCED_WIDTH: t.Optional[int] = None\n\n\ndef measure_table(rows: t.Iterable[t.Tuple[str, str]]) -> t.Tuple[int, ...]:\n    widths: t.Dict[int, int] = {}\n\n    for row in rows:\n        for idx, col in enumerate(row):\n            widths[idx] = max(widths.get(idx, 0), term_len(col))\n\n    return tuple(y for x, y in sorted(widths.items()))\n\n\ndef iter_rows(\n    rows: t.Iterable[t.Tuple[str, str]], col_count: int\n) -> t.Iterator[t.Tuple[str, ...]]:\n    for row in rows:\n        yield row + (\"\",) * (col_count - len(row))\n\n\ndef wrap_text(\n    text: str,\n    width: int = 78,\n    initial_indent: str = \"\",\n    subsequent_indent: str = \"\",\n    preserve_paragraphs: bool = False,\n) -> str:\n    \"\"\"A helper function that intelligently wraps text.  By default, it\n    assumes that it operates on a single paragraph of text but if the\n    `preserve_paragraphs` parameter is provided it will intelligently\n    handle paragraphs (defined by two empty lines).\n\n    If paragraphs are handled, a paragraph can be prefixed with an empty\n    line containing the ``\\\\b`` character (``\\\\x08``) to indicate that\n    no rewrapping should happen in that block.\n\n    :param text: the text that should be rewrapped.\n    :param width: the maximum width for the text.\n    :param initial_indent: the initial indent that should be placed on the\n                           first line as a string.\n    :param subsequent_indent: the indent string that should be placed on\n                              each consecutive line.\n    :param preserve_paragraphs: if this flag is set then the wrapping will\n                                intelligently handle paragraphs.\n    \"\"\"\n    from ._textwrap import TextWrapper\n\n    text = text.expandtabs()\n    wrapper = TextWrapper(\n        width,\n        initial_indent=initial_indent,\n        subsequent_indent=subsequent_indent,\n        replace_whitespace=False,\n    )\n    if not preserve_paragraphs:\n        return wrapper.fill(text)\n\n    p: t.List[t.Tuple[int, bool, str]] = []\n    buf: t.List[str] = []\n    indent = None\n\n    def _flush_par() -> None:\n        if not buf:\n            return\n        if buf[0].strip() == \"\\b\":\n            p.append((indent or 0, True, \"\\n\".join(buf[1:])))\n        else:\n            p.append((indent or 0, False, \" \".join(buf)))\n        del buf[:]\n\n    for line in text.splitlines():\n        if not line:\n            _flush_par()\n            indent = None\n        else:\n            if indent is None:\n                orig_len = term_len(line)\n                line = line.lstrip()\n                indent = orig_len - term_len(line)\n            buf.append(line)\n    _flush_par()\n\n    rv = []\n    for indent, raw, text in p:\n        with wrapper.extra_indent(\" \" * indent):\n            if raw:\n                rv.append(wrapper.indent_only(text))\n            else:\n                rv.append(wrapper.fill(text))\n\n    return \"\\n\\n\".join(rv)\n\n\nclass HelpFormatter:\n    \"\"\"This class helps with formatting text-based help pages.  It's\n    usually just needed for very special internal cases, but it's also\n    exposed so that developers can write their own fancy outputs.\n\n    At present, it always writes into memory.\n\n    :param indent_increment: the additional increment for each level.\n    :param width: the width for the text.  This defaults to the terminal\n                  width clamped to a maximum of 78.\n    \"\"\"\n\n    def __init__(\n        self,\n        indent_increment: int = 2,\n        width: t.Optional[int] = None,\n        max_width: t.Optional[int] = None,\n    ) -> None:\n        import shutil\n\n        self.indent_increment = indent_increment\n        if max_width is None:\n            max_width = 80\n        if width is None:\n            width = FORCED_WIDTH\n            if width is None:\n                width = max(min(shutil.get_terminal_size().columns, max_width) - 2, 50)\n        self.width = width\n        self.current_indent = 0\n        self.buffer: t.List[str] = []\n\n    def write(self, string: str) -> None:\n        \"\"\"Writes a unicode string into the internal buffer.\"\"\"\n        self.buffer.append(string)\n\n    def indent(self) -> None:\n        \"\"\"Increases the indentation.\"\"\"\n        self.current_indent += self.indent_increment\n\n    def dedent(self) -> None:\n        \"\"\"Decreases the indentation.\"\"\"\n        self.current_indent -= self.indent_increment\n\n    def write_usage(\n        self, prog: str, args: str = \"\", prefix: t.Optional[str] = None\n    ) -> None:\n        \"\"\"Writes a usage line into the buffer.\n\n        :param prog: the program name.\n        :param args: whitespace separated list of arguments.\n        :param prefix: The prefix for the first line. Defaults to\n            ``\"Usage: \"``.\n        \"\"\"\n        if prefix is None:\n            prefix = f\"{_('Usage:')} \"\n\n        usage_prefix = f\"{prefix:>{self.current_indent}}{prog} \"\n        text_width = self.width - self.current_indent\n\n        if text_width >= (term_len(usage_prefix) + 20):\n            # The arguments will fit to the right of the prefix.\n            indent = \" \" * term_len(usage_prefix)\n            self.write(\n                wrap_text(\n                    args,\n                    text_width,\n                    initial_indent=usage_prefix,\n                    subsequent_indent=indent,\n                )\n            )\n        else:\n            # The prefix is too long, put the arguments on the next line.\n            self.write(usage_prefix)\n            self.write(\"\\n\")\n            indent = \" \" * (max(self.current_indent, term_len(prefix)) + 4)\n            self.write(\n                wrap_text(\n                    args, text_width, initial_indent=indent, subsequent_indent=indent\n                )\n            )\n\n        self.write(\"\\n\")\n\n    def write_heading(self, heading: str) -> None:\n        \"\"\"Writes a heading into the buffer.\"\"\"\n        self.write(f\"{'':>{self.current_indent}}{heading}:\\n\")\n\n    def write_paragraph(self) -> None:\n        \"\"\"Writes a paragraph into the buffer.\"\"\"\n        if self.buffer:\n            self.write(\"\\n\")\n\n    def write_text(self, text: str) -> None:\n        \"\"\"Writes re-indented text into the buffer.  This rewraps and\n        preserves paragraphs.\n        \"\"\"\n        text_width = max(self.width - self.current_indent, 11)\n        indent = \" \" * self.current_indent\n        self.write(\n            wrap_text(\n                text,\n                text_width,\n                initial_indent=indent,\n                subsequent_indent=indent,\n                preserve_paragraphs=True,\n            )\n        )\n        self.write(\"\\n\")\n\n    def write_dl(\n        self,\n        rows: t.Sequence[t.Tuple[str, str]],\n        col_max: int = 30,\n        col_spacing: int = 2,\n    ) -> None:\n        \"\"\"Writes a definition list into the buffer.  This is how options\n        and commands are usually formatted.\n\n        :param rows: a list of two item tuples for the terms and values.\n        :param col_max: the maximum width of the first column.\n        :param col_spacing: the number of spaces between the first and\n                            second column.\n        \"\"\"\n        rows = list(rows)\n        widths = measure_table(rows)\n        if len(widths) != 2:\n            raise TypeError(\"Expected two columns for definition list\")\n\n        first_col = min(widths[0], col_max) + col_spacing\n\n        for first, second in iter_rows(rows, len(widths)):\n            self.write(f\"{'':>{self.current_indent}}{first}\")\n            if not second:\n                self.write(\"\\n\")\n                continue\n            if term_len(first) <= first_col - col_spacing:\n                self.write(\" \" * (first_col - term_len(first)))\n            else:\n                self.write(\"\\n\")\n                self.write(\" \" * (first_col + self.current_indent))\n\n            text_width = max(self.width - first_col - 2, 10)\n            wrapped_text = wrap_text(second, text_width, preserve_paragraphs=True)\n            lines = wrapped_text.splitlines()\n\n            if lines:\n                self.write(f\"{lines[0]}\\n\")\n\n                for line in lines[1:]:\n                    self.write(f\"{'':>{first_col + self.current_indent}}{line}\\n\")\n            else:\n                self.write(\"\\n\")\n\n    @contextmanager\n    def section(self, name: str) -> t.Iterator[None]:\n        \"\"\"Helpful context manager that writes a paragraph, a heading,\n        and the indents.\n\n        :param name: the section name that is written as heading.\n        \"\"\"\n        self.write_paragraph()\n        self.write_heading(name)\n        self.indent()\n        try:\n            yield\n        finally:\n            self.dedent()\n\n    @contextmanager\n    def indentation(self) -> t.Iterator[None]:\n        \"\"\"A context manager that increases the indentation.\"\"\"\n        self.indent()\n        try:\n            yield\n        finally:\n            self.dedent()\n\n    def getvalue(self) -> str:\n        \"\"\"Returns the buffer contents.\"\"\"\n        return \"\".join(self.buffer)\n\n\ndef join_options(options: t.Sequence[str]) -> t.Tuple[str, bool]:\n    \"\"\"Given a list of option strings this joins them in the most appropriate\n    way and returns them in the form ``(formatted_string,\n    any_prefix_is_slash)`` where the second item in the tuple is a flag that\n    indicates if any of the option prefixes was a slash.\n    \"\"\"\n    rv = []\n    any_prefix_is_slash = False\n\n    for opt in options:\n        prefix = split_opt(opt)[0]\n\n        if prefix == \"/\":\n            any_prefix_is_slash = True\n\n        rv.append((len(prefix), opt))\n\n    rv.sort(key=lambda x: x[0])\n    return \", \".join(x[1] for x in rv), any_prefix_is_slash\n", "path": "src/click/formatting.py"}], "after_files": [{"content": "import typing as t\nfrom contextlib import contextmanager\nfrom gettext import gettext as _\n\nfrom ._compat import term_len\nfrom .parser import split_opt\n\n# Can force a width.  This is used by the test system\nFORCED_WIDTH: t.Optional[int] = None\n\n\ndef measure_table(rows: t.Iterable[t.Tuple[str, str]]) -> t.Tuple[int, ...]:\n    widths: t.Dict[int, int] = {}\n\n    for row in rows:\n        for idx, col in enumerate(row):\n            widths[idx] = max(widths.get(idx, 0), term_len(col))\n\n    return tuple(y for x, y in sorted(widths.items()))\n\n\ndef iter_rows(\n    rows: t.Iterable[t.Tuple[str, str]], col_count: int\n) -> t.Iterator[t.Tuple[str, ...]]:\n    for row in rows:\n        yield row + (\"\",) * (col_count - len(row))\n\n\ndef wrap_text(\n    text: str,\n    width: int = 78,\n    initial_indent: str = \"\",\n    subsequent_indent: str = \"\",\n    preserve_paragraphs: bool = False,\n) -> str:\n    \"\"\"A helper function that intelligently wraps text.  By default, it\n    assumes that it operates on a single paragraph of text but if the\n    `preserve_paragraphs` parameter is provided it will intelligently\n    handle paragraphs (defined by two empty lines).\n\n    If paragraphs are handled, a paragraph can be prefixed with an empty\n    line containing the ``\\\\b`` character (``\\\\x08``) to indicate that\n    no rewrapping should happen in that block.\n\n    :param text: the text that should be rewrapped.\n    :param width: the maximum width for the text.\n    :param initial_indent: the initial indent that should be placed on the\n                           first line as a string.\n    :param subsequent_indent: the indent string that should be placed on\n                              each consecutive line.\n    :param preserve_paragraphs: if this flag is set then the wrapping will\n                                intelligently handle paragraphs.\n    \"\"\"\n    from ._textwrap import TextWrapper\n\n    text = text.expandtabs()\n    wrapper = TextWrapper(\n        width,\n        initial_indent=initial_indent,\n        subsequent_indent=subsequent_indent,\n        replace_whitespace=False,\n    )\n    if not preserve_paragraphs:\n        return wrapper.fill(text)\n\n    p: t.List[t.Tuple[int, bool, str]] = []\n    buf: t.List[str] = []\n    indent = None\n\n    def _flush_par() -> None:\n        if not buf:\n            return\n        if buf[0].strip() == \"\\b\":\n            p.append((indent or 0, True, \"\\n\".join(buf[1:])))\n        else:\n            p.append((indent or 0, False, \" \".join(buf)))\n        del buf[:]\n\n    for line in text.splitlines():\n        if not line:\n            _flush_par()\n            indent = None\n        else:\n            if indent is None:\n                orig_len = term_len(line)\n                line = line.lstrip()\n                indent = orig_len - term_len(line)\n            buf.append(line)\n    _flush_par()\n\n    rv = []\n    for indent, raw, text in p:\n        with wrapper.extra_indent(\" \" * indent):\n            if raw:\n                rv.append(wrapper.indent_only(text))\n            else:\n                rv.append(wrapper.fill(text))\n\n    return \"\\n\\n\".join(rv)\n\n\nclass HelpFormatter:\n    \"\"\"This class helps with formatting text-based help pages.  It's\n    usually just needed for very special internal cases, but it's also\n    exposed so that developers can write their own fancy outputs.\n\n    At present, it always writes into memory.\n\n    :param indent_increment: the additional increment for each level.\n    :param width: the width for the text.  This defaults to the terminal\n                  width clamped to a maximum of 78.\n    \"\"\"\n\n    def __init__(\n        self,\n        indent_increment: int = 2,\n        width: t.Optional[int] = None,\n        max_width: t.Optional[int] = None,\n    ) -> None:\n        import shutil\n\n        self.indent_increment = indent_increment\n        if max_width is None:\n            max_width = 80\n        if width is None:\n            width = FORCED_WIDTH\n            if width is None:\n                width = max(min(shutil.get_terminal_size().columns, max_width) - 2, 50)\n        self.width = width\n        self.current_indent = 0\n        self.buffer: t.List[str] = []\n\n    def write(self, string: str) -> None:\n        \"\"\"Writes a unicode string into the internal buffer.\"\"\"\n        self.buffer.append(string)\n\n    def indent(self) -> None:\n        \"\"\"Increases the indentation.\"\"\"\n        self.current_indent += self.indent_increment\n\n    def dedent(self) -> None:\n        \"\"\"Decreases the indentation.\"\"\"\n        self.current_indent -= self.indent_increment\n\n    def write_usage(\n        self, prog: str, args: str = \"\", prefix: t.Optional[str] = None\n    ) -> None:\n        \"\"\"Writes a usage line into the buffer.\n\n        :param prog: the program name.\n        :param args: whitespace separated list of arguments.\n        :param prefix: The prefix for the first line. Defaults to\n            ``\"Usage: \"``.\n        \"\"\"\n        if prefix is None:\n            prefix = f\"{_('Usage:')} \"\n\n        usage_prefix = f\"{prefix:>{self.current_indent}}{prog} \"\n        text_width = self.width - self.current_indent\n\n        if text_width >= (term_len(usage_prefix) + 20):\n            # The arguments will fit to the right of the prefix.\n            indent = \" \" * term_len(usage_prefix)\n            self.write(\n                wrap_text(\n                    args,\n                    text_width,\n                    initial_indent=usage_prefix,\n                    subsequent_indent=indent,\n                )\n            )\n        else:\n            # The prefix is too long, put the arguments on the next line.\n            self.write(usage_prefix)\n            self.write(\"\\n\")\n            indent = \" \" * (max(self.current_indent, term_len(prefix)) + 4)\n            self.write(\n                wrap_text(\n                    args, text_width, initial_indent=indent, subsequent_indent=indent\n                )\n            )\n\n        self.write(\"\\n\")\n\n    def write_heading(self, heading: str) -> None:\n        \"\"\"Writes a heading into the buffer.\"\"\"\n        self.write(f\"{'':>{self.current_indent}}{heading}:\\n\")\n\n    def write_paragraph(self) -> None:\n        \"\"\"Writes a paragraph into the buffer.\"\"\"\n        if self.buffer:\n            self.write(\"\\n\")\n\n    def write_text(self, text: str) -> None:\n        \"\"\"Writes re-indented text into the buffer.  This rewraps and\n        preserves paragraphs.\n        \"\"\"\n        indent = \" \" * self.current_indent\n        self.write(\n            wrap_text(\n                text,\n                self.width,\n                initial_indent=indent,\n                subsequent_indent=indent,\n                preserve_paragraphs=True,\n            )\n        )\n        self.write(\"\\n\")\n\n    def write_dl(\n        self,\n        rows: t.Sequence[t.Tuple[str, str]],\n        col_max: int = 30,\n        col_spacing: int = 2,\n    ) -> None:\n        \"\"\"Writes a definition list into the buffer.  This is how options\n        and commands are usually formatted.\n\n        :param rows: a list of two item tuples for the terms and values.\n        :param col_max: the maximum width of the first column.\n        :param col_spacing: the number of spaces between the first and\n                            second column.\n        \"\"\"\n        rows = list(rows)\n        widths = measure_table(rows)\n        if len(widths) != 2:\n            raise TypeError(\"Expected two columns for definition list\")\n\n        first_col = min(widths[0], col_max) + col_spacing\n\n        for first, second in iter_rows(rows, len(widths)):\n            self.write(f\"{'':>{self.current_indent}}{first}\")\n            if not second:\n                self.write(\"\\n\")\n                continue\n            if term_len(first) <= first_col - col_spacing:\n                self.write(\" \" * (first_col - term_len(first)))\n            else:\n                self.write(\"\\n\")\n                self.write(\" \" * (first_col + self.current_indent))\n\n            text_width = max(self.width - first_col - 2, 10)\n            wrapped_text = wrap_text(second, text_width, preserve_paragraphs=True)\n            lines = wrapped_text.splitlines()\n\n            if lines:\n                self.write(f\"{lines[0]}\\n\")\n\n                for line in lines[1:]:\n                    self.write(f\"{'':>{first_col + self.current_indent}}{line}\\n\")\n            else:\n                self.write(\"\\n\")\n\n    @contextmanager\n    def section(self, name: str) -> t.Iterator[None]:\n        \"\"\"Helpful context manager that writes a paragraph, a heading,\n        and the indents.\n\n        :param name: the section name that is written as heading.\n        \"\"\"\n        self.write_paragraph()\n        self.write_heading(name)\n        self.indent()\n        try:\n            yield\n        finally:\n            self.dedent()\n\n    @contextmanager\n    def indentation(self) -> t.Iterator[None]:\n        \"\"\"A context manager that increases the indentation.\"\"\"\n        self.indent()\n        try:\n            yield\n        finally:\n            self.dedent()\n\n    def getvalue(self) -> str:\n        \"\"\"Returns the buffer contents.\"\"\"\n        return \"\".join(self.buffer)\n\n\ndef join_options(options: t.Sequence[str]) -> t.Tuple[str, bool]:\n    \"\"\"Given a list of option strings this joins them in the most appropriate\n    way and returns them in the form ``(formatted_string,\n    any_prefix_is_slash)`` where the second item in the tuple is a flag that\n    indicates if any of the option prefixes was a slash.\n    \"\"\"\n    rv = []\n    any_prefix_is_slash = False\n\n    for opt in options:\n        prefix = split_opt(opt)[0]\n\n        if prefix == \"/\":\n            any_prefix_is_slash = True\n\n        rv.append((len(prefix), opt))\n\n    rv.sort(key=lambda x: x[0])\n    return \", \".join(x[1] for x in rv), any_prefix_is_slash\n", "path": "src/click/formatting.py"}]}