File: hover.py

package info (click to toggle)
python-lsp-server 1.14.0-1
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 836 kB
  • sloc: python: 8,297; sh: 12; makefile: 4
file content (61 lines) | stat: -rw-r--r-- 2,016 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
# 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,
        )
    }