Problem
The formatting of signatures in hover and code completion documentation is fine for signatures of small functions:

but is not necessarily readable for functions with many complex arguments:

Proposed solution
Add a hook allowing to format the signature with a formatter of choice, e.g. with black. Users could then customize the number of characters in a lines, wrapping, and potentially custom highlighting (instead of using code fences).
Context
Currently docstrings in hover and completion documentation are composed of two parts:
- signature
- the docstring itself
The docstring gets formatted by docstring-to-markdown which now supports entrypoints allowing to add support for custom formats used in internal codebases or to override the formatting.
|
def format_docstring( |
|
contents: str, markup_kind: str, signatures: Optional[List[str]] = None |
|
): |
|
"""Transform the provided docstring into a MarkupContent object. |
|
|
|
If `markup_kind` is 'markdown' the docstring will get converted to |
|
markdown representation using `docstring-to-markdown`; if it is |
|
`plaintext`, it will be returned as plain text. |
|
Call signatures of functions (or equivalent code summaries) |
|
provided in optional `signatures` argument will be prepended |
|
to the provided contents of the docstring if given. |
|
""" |
|
if not isinstance(contents, str): |
|
contents = "" |
|
|
|
if markup_kind == "markdown": |
|
try: |
|
value = docstring_to_markdown.convert(contents) |
|
except docstring_to_markdown.UnknownFormatError: |
|
# try to escape the Markdown syntax instead: |
|
value = escape_markdown(contents) |
|
|
|
if signatures: |
|
value = wrap_signature("\n".join(signatures)) + "\n\n" + value |
|
|
|
return {"kind": "markdown", "value": value} |
|
value = contents |
|
if signatures: |
|
value = "\n".join(signatures) + "\n\n" + value |
|
return {"kind": "plaintext", "value": escape_plain_text(value)} |
The signature part formatting is hard-coded to use wrap_signature:
|
def wrap_signature(signature): |
|
return "```python\n" + signature + "\n```\n" |
The signature strings come from jedi's BaseSignature.to_string() method:
|
docs = _utils.format_docstring( |
|
d.docstring(raw=True), |
|
signatures=[signature.to_string() for signature in d.get_signatures()], |
|
markup_kind=markup_kind, |
|
# Find first exact matching signature |
|
signature = next( |
|
( |
|
x.to_string() |
|
for x in definition.get_signatures() |
|
if (x.name == word and x.type not in ["module"]) |
|
), |
|
"", |
|
) |
|
|
|
return { |
|
"contents": _utils.format_docstring( |
|
# raw docstring returns only doc, without signature |
|
definition.docstring(raw=True), |
|
preferred_markup_kind, |
|
signatures=[signature] if signature else None, |
|
) |
|
} |
Problem
The formatting of signatures in hover and code completion documentation is fine for signatures of small functions:
but is not necessarily readable for functions with many complex arguments:
Proposed solution
Add a hook allowing to format the signature with a formatter of choice, e.g. with
black. Users could then customize the number of characters in a lines, wrapping, and potentially custom highlighting (instead of using code fences).Context
Currently docstrings in hover and completion documentation are composed of two parts:
The docstring gets formatted by
docstring-to-markdownwhich now supports entrypoints allowing to add support for custom formats used in internal codebases or to override the formatting.python-lsp-server/pylsp/_utils.py
Lines 212 to 241 in cc6d398
The signature part formatting is hard-coded to use
wrap_signature:python-lsp-server/pylsp/_utils.py
Lines 194 to 195 in cc6d398
The signature strings come from jedi's
BaseSignature.to_string()method:python-lsp-server/pylsp/plugins/jedi_completion.py
Lines 213 to 216 in cc6d398
python-lsp-server/pylsp/plugins/hover.py
Lines 33 to 50 in cc6d398