Skip to content

Commit 8c5a7a3

Browse files
committed
Further prettifies / simplifies markdown
This fix should make it so that no docstrings mess up the user view. Additionally, IMHO, it more-tersely presents hover information to user.
1 parent 09736f7 commit 8c5a7a3

File tree

1 file changed

+93
-25
lines changed

1 file changed

+93
-25
lines changed

jedi_language_server/jedi_utils.py

Lines changed: 93 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -384,6 +384,39 @@ def lsp_completion_item(
384384
return completion_item
385385

386386

387+
def _md_bold(value: str, markup_kind: MarkupKind) -> str:
388+
"""Add bold surrounding when markup_kind is markdown."""
389+
return f"**{value}**" if markup_kind == MarkupKind.Markdown else value
390+
391+
392+
def _md_italic(value: str, markup_kind: MarkupKind) -> str:
393+
"""Add italic surrounding when markup_kind is markdown."""
394+
return f"*{value}*" if markup_kind == MarkupKind.Markdown else value
395+
396+
397+
def _md_text(value: str, markup_kind: MarkupKind) -> str:
398+
"""Surround a markdown string with a Python fence."""
399+
return (
400+
f"```text\n{value}\n```"
401+
if markup_kind == MarkupKind.Markdown
402+
else value
403+
)
404+
405+
406+
def _md_python(value: str, markup_kind: MarkupKind) -> str:
407+
"""Surround a markdown string with a Python fence."""
408+
return (
409+
f"```python\n{value}\n```"
410+
if markup_kind == MarkupKind.Markdown
411+
else value
412+
)
413+
414+
415+
def _md_text_sl(value: str, markup_kind: MarkupKind) -> str:
416+
"""Surround markdown text with single line backtick."""
417+
return f"`{value}`" if markup_kind == MarkupKind.Markdown else value
418+
419+
387420
def convert_docstring(docstring: str, markup_kind: MarkupKind) -> str:
388421
"""Take a docstring and convert it to markup kind if possible.
389422
@@ -398,58 +431,93 @@ def convert_docstring(docstring: str, markup_kind: MarkupKind) -> str:
398431
try:
399432
return docstring_to_markdown.convert(docstring).strip()
400433
except docstring_to_markdown.UnknownFormatError:
401-
return docstring.strip()
434+
return _md_text(docstring.strip(), markup_kind)
402435
except Exception as error: # pylint: disable=broad-except
403-
return (
404-
docstring
436+
result = (
437+
docstring.strip()
405438
+ "\n"
406439
+ "jedi-language-server error: "
407440
+ "Uncaught exception while converting docstring to markdown. "
408441
+ "Please open issue at "
409442
+ "https://github.com/pappasam/jedi-language-server/issues. "
410443
+ f"Traceback:\n{error}"
411444
).strip()
445+
return _md_text(result, markup_kind)
412446
return docstring.strip()
413447

414448

415-
def _bold(value: str, markup_kind: MarkupKind) -> str:
416-
"""Add bold surrounding when markup_kind is markdown."""
417-
return f"**{value}**" if markup_kind == MarkupKind.Markdown else value
418-
449+
_HOVER_SIGNATURE_TYPES = {"class", "instance", "function"}
419450

420-
def _italic(value: str, markup_kind: MarkupKind) -> str:
421-
"""Add italic surrounding when markup_kind is markdown."""
422-
return f"*{value}*" if markup_kind == MarkupKind.Markdown else value
451+
_HOVER_TYPE_TRANSLATION = {
452+
"module": "module",
453+
"class": "class",
454+
"instance": "instance",
455+
"function": "def",
456+
"param": "param",
457+
"path": "path",
458+
"keyword": "keyword",
459+
"property": "property",
460+
"statement": "statement",
461+
}
423462

424463

425464
def hover_text(names: List[Name], markup_kind: MarkupKind) -> Optional[str]:
426465
"""Get a hover string from a list of names."""
466+
# pylint: disable=too-many-branches
427467
if not names:
428468
return None
429469
name = names[0]
470+
name_type = name.type
471+
hover_type = _HOVER_TYPE_TRANSLATION[name_type]
472+
signatures = (
473+
[f"{hover_type} {s.to_string()}" for s in name.get_signatures()]
474+
if name_type in _HOVER_SIGNATURE_TYPES
475+
else []
476+
)
430477
name_str = name.name
431478
full_name = name.full_name
432479
description = name.description
433-
docstring = name.docstring()
434-
try:
435-
type_hint = name.get_type_hint()
436-
except Exception: # pylint: disable=broad-except
437-
# jedi randomly raises NotImplemented, TypeError, and possibly more
438-
# errors here. One example from jls: test_hover.test_hover_on_method
480+
docstring = name.docstring(raw=True)
481+
if not signatures and name_type != "class":
482+
try:
483+
type_hint = name.get_type_hint()
484+
except Exception: # pylint: disable=broad-except
485+
# jedi randomly raises NotImplemented, TypeError, and possibly more
486+
# errors here. One example from jls -
487+
# test_hover.test_hover_on_method
488+
type_hint = ""
489+
else:
439490
type_hint = ""
491+
492+
if signatures:
493+
header_plain = "\n".join(signatures)
494+
elif name_type == "class":
495+
header_plain = f"{hover_type} {name_str}"
496+
elif type_hint:
497+
header_plain = f"{name_str}: {type_hint}"
498+
else:
499+
header_plain = f"{hover_type} {name_str}"
500+
header = _md_python(header_plain, markup_kind)
501+
440502
result: List[str] = []
441-
if name:
442-
result.append(f"{_bold('Name:', markup_kind)} {name_str}")
443-
result.append("")
503+
result.append(header)
444504
if docstring:
505+
result.append("---")
445506
result.append(convert_docstring(docstring, markup_kind))
446-
result.append("")
447-
if description:
448-
result.append(f"{_italic('Desc:', markup_kind)} {description}")
449-
if type_hint:
450-
result.append(f"{_italic('Type:', markup_kind)} {type_hint}")
507+
elif header_plain.strip().startswith(description.strip()):
508+
pass
509+
else:
510+
result.append("---")
511+
result.append(_md_python(description, markup_kind))
512+
451513
if full_name:
452-
result.append(f"{_italic('Path:', markup_kind)} {full_name}")
514+
if len(result) == 1:
515+
result.append("---")
516+
result.append(
517+
_md_bold("Path:", markup_kind)
518+
+ " "
519+
+ _md_text_sl(full_name, markup_kind)
520+
)
453521
if not result:
454522
return None
455523
return "\n".join(result).strip()

0 commit comments

Comments
 (0)