61 lines
2 KiB
Python
61 lines
2 KiB
Python
# Copyright 2017-2020 Palantir Technologies, Inc.
|
|
# Copyright 2021- Python Language Server Contributors.
|
|
|
|
import logging
|
|
|
|
from pylsp import _utils, hookimpl
|
|
|
|
log = logging.getLogger(__name__)
|
|
|
|
|
|
@hookimpl
|
|
def pylsp_hover(config, document, position):
|
|
signature_config = config.settings().get("signature", {})
|
|
code_position = _utils.position_to_jedi_linecolumn(document, position)
|
|
definitions = document.jedi_script(use_document_path=True).infer(**code_position)
|
|
word = document.word_at_position(position)
|
|
|
|
# Find first exact matching definition
|
|
definition = next((x for x in definitions if x.name == word), None)
|
|
|
|
# Ensure a definition is used if only one is available
|
|
# even if the word doesn't match. An example of this case is 'np'
|
|
# where 'numpy' doesn't match with 'np'. Same for NumPy ufuncs
|
|
if len(definitions) == 1:
|
|
definition = definitions[0]
|
|
|
|
if not definition:
|
|
return {"contents": ""}
|
|
|
|
hover_capabilities = config.capabilities.get("textDocument", {}).get("hover", {})
|
|
supported_markup_kinds = hover_capabilities.get("contentFormat", ["markdown"])
|
|
preferred_markup_kind = _utils.choose_markup_kind(supported_markup_kinds)
|
|
|
|
# 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"])
|
|
),
|
|
"",
|
|
)
|
|
|
|
include_docstring = signature_config.get("include_docstring", True)
|
|
|
|
# raw docstring returns only doc, without signature
|
|
docstring = definition.docstring(raw=True)
|
|
if not include_docstring:
|
|
if signature:
|
|
docstring = ""
|
|
else:
|
|
docstring = docstring.strip().split("\n")[0].strip()
|
|
|
|
return {
|
|
"contents": _utils.format_docstring(
|
|
docstring,
|
|
preferred_markup_kind,
|
|
signatures=[signature] if signature else None,
|
|
signature_config=signature_config,
|
|
)
|
|
}
|