Skip to content

Commit 3779896

Browse files
committed
Add include_docstring setting to *jedi_hover* plugin.
1 parent dd03085 commit 3779896

File tree

8 files changed

+187
-15
lines changed

8 files changed

+187
-15
lines changed

CONFIGURATION.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,8 +37,10 @@ This server can be configured using the `workspace/didChangeConfiguration` metho
3737
| `pylsp.plugins.jedi_definition.follow_builtin_imports` | `boolean` | If follow_imports is True will decide if it follow builtin imports. | `true` |
3838
| `pylsp.plugins.jedi_definition.follow_builtin_definitions` | `boolean` | Follow builtin and extension definitions to stubs. | `true` |
3939
| `pylsp.plugins.jedi_hover.enabled` | `boolean` | Enable or disable the plugin. | `true` |
40+
| `pylsp.plugins.jedi_hover.include_docstring` | `boolean` | Include signature docstring in the output. | `true` |
4041
| `pylsp.plugins.jedi_references.enabled` | `boolean` | Enable or disable the plugin. | `true` |
4142
| `pylsp.plugins.jedi_signature_help.enabled` | `boolean` | Enable or disable the plugin. | `true` |
43+
| `pylsp.plugins.jedi_signature_help.include_docstring` | `boolean` | Include signature docstring in the output. | `true` |
4244
| `pylsp.plugins.jedi_symbols.enabled` | `boolean` | Enable or disable the plugin. | `true` |
4345
| `pylsp.plugins.jedi_symbols.all_scopes` | `boolean` | If True lists the names of all scopes instead of only the module namespace. | `true` |
4446
| `pylsp.plugins.jedi_symbols.include_import_symbols` | `boolean` | If True includes symbols imported from other libraries. | `true` |

EXPECTED_CONFIGURATION.md

Lines changed: 83 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,83 @@
1+
# Python Language Server Configuration
2+
This server can be configured using the `workspace/didChangeConfiguration` method. Each configuration option is described below. Note, a value of `null` means that we do not set a value and thus use the plugin's default value.
3+
4+
| **Configuration Key** | **Type** | **Description** | **Default**
5+
|----|----|----|----|
6+
| `pylsp.configurationSources` | `array` of unique `string` (one of: `'pycodestyle'`, `'flake8'`) items | List of configuration sources to use. | `["pycodestyle"]` |
7+
| `pylsp.plugins.autopep8.enabled` | `boolean` | Enable or disable the plugin (disabling required to use `yapf`). | `true` |
8+
| `pylsp.plugins.flake8.config` | `string` | Path to the config file that will be the authoritative config source. | `null` |
9+
| `pylsp.plugins.flake8.enabled` | `boolean` | Enable or disable the plugin. | `false` |
10+
| `pylsp.plugins.flake8.exclude` | `array` of `string` items | List of files or directories to exclude. | `[]` |
11+
| `pylsp.plugins.flake8.extendIgnore` | `array` of `string` items | List of errors and warnings to append to ignore list. | `[]` |
12+
| `pylsp.plugins.flake8.extendSelect` | `array` of `string` items | List of errors and warnings to append to select list. | `[]` |
13+
| `pylsp.plugins.flake8.executable` | `string` | Path to the flake8 executable. | `"flake8"` |
14+
| `pylsp.plugins.flake8.filename` | `string` | Only check for filenames matching the patterns in this list. | `null` |
15+
| `pylsp.plugins.flake8.hangClosing` | `boolean` | Hang closing bracket instead of matching indentation of opening bracket's line. | `null` |
16+
| `pylsp.plugins.flake8.ignore` | `array` of `string` items | List of errors and warnings to ignore (or skip). | `[]` |
17+
| `pylsp.plugins.flake8.maxComplexity` | `integer` | Maximum allowed complexity threshold. | `null` |
18+
| `pylsp.plugins.flake8.maxLineLength` | `integer` | Maximum allowed line length for the entirety of this run. | `null` |
19+
| `pylsp.plugins.flake8.indentSize` | `integer` | Set indentation spaces. | `null` |
20+
| `pylsp.plugins.flake8.perFileIgnores` | `array` of `string` items | A pairing of filenames and violation codes that defines which violations to ignore in a particular file, for example: `["file_path.py:W305,W304"]`). | `[]` |
21+
| `pylsp.plugins.flake8.select` | `array` of unique `string` items | List of errors and warnings to enable. | `null` |
22+
| `pylsp.plugins.jedi.auto_import_modules` | `array` of `string` items | List of module names for jedi.settings.auto_import_modules. | `["numpy"]` |
23+
| `pylsp.plugins.jedi.extra_paths` | `array` of `string` items | Define extra paths for jedi.Script. | `[]` |
24+
| `pylsp.plugins.jedi.prioritize_extra_paths` | `boolean` | Whether to place extra_paths at the beginning (true) or end (false) of `sys.path` | `false` |
25+
| `pylsp.plugins.jedi.env_vars` | `object` | Define environment variables for jedi.Script and Jedi.names. | `null` |
26+
| `pylsp.plugins.jedi.environment` | `string` | Define environment for jedi.Script and Jedi.names. | `null` |
27+
| `pylsp.plugins.jedi_completion.enabled` | `boolean` | Enable or disable the plugin. | `true` |
28+
| `pylsp.plugins.jedi_completion.include_params` | `boolean` | Auto-completes methods and classes with tabstops for each parameter. | `true` |
29+
| `pylsp.plugins.jedi_completion.include_class_objects` | `boolean` | Adds class objects as a separate completion item. | `false` |
30+
| `pylsp.plugins.jedi_completion.include_function_objects` | `boolean` | Adds function objects as a separate completion item. | `false` |
31+
| `pylsp.plugins.jedi_completion.fuzzy` | `boolean` | Enable fuzzy when requesting autocomplete. | `false` |
32+
| `pylsp.plugins.jedi_completion.eager` | `boolean` | Resolve documentation and detail eagerly. | `false` |
33+
| `pylsp.plugins.jedi_completion.resolve_at_most` | `integer` | How many labels and snippets (at most) should be resolved? | `25` |
34+
| `pylsp.plugins.jedi_completion.cache_for` | `array` of `string` items | Modules for which labels and snippets should be cached. | `["pandas", "numpy", "tensorflow", "matplotlib"]` |
35+
| `pylsp.plugins.jedi_definition.enabled` | `boolean` | Enable or disable the plugin. | `true` |
36+
| `pylsp.plugins.jedi_definition.follow_imports` | `boolean` | The goto call will follow imports. | `true` |
37+
| `pylsp.plugins.jedi_definition.follow_builtin_imports` | `boolean` | If follow_imports is True will decide if it follow builtin imports. | `true` |
38+
| `pylsp.plugins.jedi_definition.follow_builtin_definitions` | `boolean` | Follow builtin and extension definitions to stubs. | `true` |
39+
| `pylsp.plugins.jedi_hover.enabled` | `boolean` | Enable or disable the plugin. | `true` |
40+
| `pylsp.plugins.jedi_hover.include_docstring` | `boolean` | Include signature docstring in the output. | `true` |
41+
| `pylsp.plugins.jedi_references.enabled` | `boolean` | Enable or disable the plugin. | `true` |
42+
| `pylsp.plugins.jedi_signature_help.enabled` | `boolean` | Enable or disable the plugin. | `true` |
43+
| `pylsp.plugins.jedi_signature_help.include_docstring` | `boolean` | Include signature docstring in the output. | `true` |
44+
| `pylsp.plugins.jedi_symbols.enabled` | `boolean` | Enable or disable the plugin. | `true` |
45+
| `pylsp.plugins.jedi_symbols.all_scopes` | `boolean` | If True lists the names of all scopes instead of only the module namespace. | `true` |
46+
| `pylsp.plugins.jedi_symbols.include_import_symbols` | `boolean` | If True includes symbols imported from other libraries. | `true` |
47+
| `pylsp.plugins.mccabe.enabled` | `boolean` | Enable or disable the plugin. | `true` |
48+
| `pylsp.plugins.mccabe.threshold` | `integer` | The minimum threshold that triggers warnings about cyclomatic complexity. | `15` |
49+
| `pylsp.plugins.preload.enabled` | `boolean` | Enable or disable the plugin. | `true` |
50+
| `pylsp.plugins.preload.modules` | `array` of unique `string` items | List of modules to import on startup | `[]` |
51+
| `pylsp.plugins.pycodestyle.enabled` | `boolean` | Enable or disable the plugin. | `true` |
52+
| `pylsp.plugins.pycodestyle.exclude` | `array` of unique `string` items | Exclude files or directories which match these patterns. | `[]` |
53+
| `pylsp.plugins.pycodestyle.filename` | `array` of unique `string` items | When parsing directories, only check filenames matching these patterns. | `[]` |
54+
| `pylsp.plugins.pycodestyle.select` | `array` of unique `string` items | Select errors and warnings | `null` |
55+
| `pylsp.plugins.pycodestyle.ignore` | `array` of unique `string` items | Ignore errors and warnings | `[]` |
56+
| `pylsp.plugins.pycodestyle.hangClosing` | `boolean` | Hang closing bracket instead of matching indentation of opening bracket's line. | `null` |
57+
| `pylsp.plugins.pycodestyle.maxLineLength` | `integer` | Set maximum allowed line length. | `null` |
58+
| `pylsp.plugins.pycodestyle.indentSize` | `integer` | Set indentation spaces. | `null` |
59+
| `pylsp.plugins.pydocstyle.enabled` | `boolean` | Enable or disable the plugin. | `false` |
60+
| `pylsp.plugins.pydocstyle.convention` | `string` (one of: `'pep257'`, `'numpy'`, `'google'`, `None`) | Choose the basic list of checked errors by specifying an existing convention. | `null` |
61+
| `pylsp.plugins.pydocstyle.addIgnore` | `array` of unique `string` items | Ignore errors and warnings in addition to the specified convention. | `[]` |
62+
| `pylsp.plugins.pydocstyle.addSelect` | `array` of unique `string` items | Select errors and warnings in addition to the specified convention. | `[]` |
63+
| `pylsp.plugins.pydocstyle.ignore` | `array` of unique `string` items | Ignore errors and warnings | `[]` |
64+
| `pylsp.plugins.pydocstyle.select` | `array` of unique `string` items | Select errors and warnings | `null` |
65+
| `pylsp.plugins.pydocstyle.match` | `string` | Check only files that exactly match the given regular expression; default is to match files that don't start with 'test_' but end with '.py'. | `"(?!test_).*\\.py"` |
66+
| `pylsp.plugins.pydocstyle.matchDir` | `string` | Search only dirs that exactly match the given regular expression; default is to match dirs which do not begin with a dot. | `"[^\\.].*"` |
67+
| `pylsp.plugins.pyflakes.enabled` | `boolean` | Enable or disable the plugin. | `true` |
68+
| `pylsp.plugins.pylint.enabled` | `boolean` | Enable or disable the plugin. | `false` |
69+
| `pylsp.plugins.pylint.args` | `array` of non-unique `string` items | Arguments to pass to pylint. | `[]` |
70+
| `pylsp.plugins.pylint.executable` | `string` | Executable to run pylint with. Enabling this will run pylint on unsaved files via stdin. Can slow down workflow. Only works with python3. | `null` |
71+
| `pylsp.plugins.rope_autoimport.enabled` | `boolean` | Enable or disable autoimport. If false, neither completions nor code actions are enabled. If true, the respective features can be enabled or disabled individually. | `false` |
72+
| `pylsp.plugins.rope_autoimport.completions.enabled` | `boolean` | Enable or disable autoimport completions. | `true` |
73+
| `pylsp.plugins.rope_autoimport.code_actions.enabled` | `boolean` | Enable or disable autoimport code actions (e.g. for quick fixes). | `true` |
74+
| `pylsp.plugins.rope_autoimport.memory` | `boolean` | Make the autoimport database memory only. Drastically increases startup time. | `false` |
75+
| `pylsp.plugins.rope_completion.enabled` | `boolean` | Enable or disable the plugin. | `false` |
76+
| `pylsp.plugins.rope_completion.eager` | `boolean` | Resolve documentation and detail eagerly. | `false` |
77+
| `pylsp.plugins.yapf.enabled` | `boolean` | Enable or disable the plugin. | `true` |
78+
| `pylsp.rope.extensionModules` | `string` | Builtin and c-extension modules that are allowed to be imported and inspected by rope. | `null` |
79+
| `pylsp.rope.ropeFolder` | `array` of unique `string` items | The name of the folder in which rope stores project configurations and data. Pass `null` for not using such a folder at all. | `null` |
80+
| `pylsp.signature.formatter` | `string` (one of: `'black'`, `'ruff'`, `None`) | Formatter to use for reformatting signatures in docstrings. | `"black"` |
81+
| `pylsp.signature.line_length` | `number` | Maximum line length in signatures. | `88` |
82+
83+
This documentation was generated from `pylsp/config/schema.json`. Please do not edit this file directly.

pylsp/_utils.py

Lines changed: 18 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -315,17 +315,24 @@ def format_docstring(
315315
contents = ""
316316

317317
if markup_kind == "markdown":
318-
try:
319-
value = docstring_to_markdown.convert(contents)
320-
except docstring_to_markdown.UnknownFormatError:
321-
# try to escape the Markdown syntax instead:
322-
value = escape_markdown(contents)
323-
324-
if signatures:
325-
wrapped_signatures = convert_signatures_to_markdown(
326-
signatures, config=signature_config or {}
327-
)
328-
value = wrapped_signatures + "\n\n" + value
318+
wrapped_signatures = convert_signatures_to_markdown(
319+
signatures if signatures is not None else [], config=signature_config or {}
320+
)
321+
322+
if contents != "":
323+
try:
324+
value = docstring_to_markdown.convert(contents)
325+
except docstring_to_markdown.UnknownFormatError:
326+
# try to escape the Markdown syntax instead:
327+
value = escape_markdown(contents)
328+
329+
if signatures:
330+
value = wrapped_signatures + "\n\n" + value
331+
else:
332+
value = contents
333+
334+
if signatures:
335+
value = wrapped_signatures
329336

330337
return {"kind": "markdown", "value": value}
331338
value = contents

pylsp/config/schema.json

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -245,6 +245,11 @@
245245
"default": true,
246246
"description": "Enable or disable the plugin."
247247
},
248+
"pylsp.plugins.jedi_hover.include_docstring": {
249+
"type": "boolean",
250+
"default": true,
251+
"description": "Include signature docstring in the output."
252+
},
248253
"pylsp.plugins.jedi_references.enabled": {
249254
"type": "boolean",
250255
"default": true,
@@ -255,6 +260,11 @@
255260
"default": true,
256261
"description": "Enable or disable the plugin."
257262
},
263+
"pylsp.plugins.jedi_signature_help.include_docstring": {
264+
"type": "boolean",
265+
"default": true,
266+
"description": "Include signature docstring in the output."
267+
},
258268
"pylsp.plugins.jedi_symbols.enabled": {
259269
"type": "boolean",
260270
"default": true,
@@ -531,4 +541,4 @@
531541
"description": "Maximum line length in signatures."
532542
}
533543
}
534-
}
544+
}

pylsp/plugins/hover.py

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
@hookimpl
1212
def pylsp_hover(config, document, position):
1313
signature_config = config.settings().get("signature", {})
14+
settings = config.plugin_settings("jedi_hover", document_path=document.path)
1415
code_position = _utils.position_to_jedi_linecolumn(document, position)
1516
definitions = document.jedi_script(use_document_path=True).infer(**code_position)
1617
word = document.word_at_position(position)
@@ -41,10 +42,19 @@ def pylsp_hover(config, document, position):
4142
"",
4243
)
4344

45+
include_docstring = settings.get("include_docstring", True)
46+
47+
# raw docstring returns only doc, without signature
48+
docstring = definition.docstring(raw=True)
49+
if include_docstring is False:
50+
if signature:
51+
docstring = ""
52+
else:
53+
docstring = docstring.strip().split("\n")[0].strip()
54+
4455
return {
4556
"contents": _utils.format_docstring(
46-
# raw docstring returns only doc, without signature
47-
definition.docstring(raw=True),
57+
docstring,
4858
preferred_markup_kind,
4959
signatures=[signature] if signature else None,
5060
signature_config=signature_config,

pylsp/plugins/signature.py

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,9 @@
1717

1818
@hookimpl
1919
def pylsp_signature_help(config, document, position):
20+
settings = config.plugin_settings(
21+
"jedi_signature_help", document_path=document.path
22+
)
2023
code_position = _utils.position_to_jedi_linecolumn(document, position)
2124
signatures = document.jedi_script().get_signatures(**code_position)
2225

@@ -41,10 +44,15 @@ def pylsp_signature_help(config, document, position):
4144
# Docstring contains one or more lines of signature, followed by empty line, followed by docstring
4245
function_sig_lines = (docstring.split("\n\n") or [""])[0].splitlines()
4346
function_sig = " ".join([line.strip() for line in function_sig_lines])
47+
48+
signature_docstring = s.docstring(raw=True)
49+
if settings.get("include_docstring", True) is False:
50+
signature_docstring = ""
51+
4452
sig = {
4553
"label": function_sig,
4654
"documentation": _utils.format_docstring(
47-
s.docstring(raw=True), markup_kind=preferred_markup_kind
55+
signature_docstring, markup_kind=preferred_markup_kind
4856
),
4957
}
5058

test/plugins/test_hover.py

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,8 @@
33

44
import os
55

6+
import pytest
7+
68
from pylsp import uris
79
from pylsp.plugins.hover import pylsp_hover
810
from pylsp.workspace import Document
@@ -23,6 +25,17 @@ def main(a: float, b: float):
2325
"""
2426

2527

28+
@pytest.fixture
29+
def workspace_with_hover_docstring_disabled(workspace) -> None:
30+
workspace._config._settings["plugins"] = {
31+
"jedi_hover": {
32+
"include_docstring": False,
33+
},
34+
}
35+
36+
yield workspace
37+
38+
2639
def test_numpy_hover(workspace) -> None:
2740
# Over the blank line
2841
no_hov_position = {"line": 1, "character": 0}
@@ -143,3 +156,17 @@ def foo():
143156
contents = pylsp_hover(doc._config, doc, cursor_pos)["contents"]
144157

145158
assert "A docstring for foo." in contents["value"]
159+
160+
161+
def test_hover_without_docstring(workspace_with_hover_docstring_disabled) -> None:
162+
# Over 'main' in def main():
163+
hov_position = {"line": 2, "character": 6}
164+
165+
doc = Document(DOC_URI, workspace_with_hover_docstring_disabled, DOC)
166+
167+
contents = {
168+
"kind": "markdown",
169+
"value": "```python\nmain(a: float, b: float)\n```\n",
170+
}
171+
172+
assert {"contents": contents} == pylsp_hover(doc._config, doc, hov_position)

test/plugins/test_signature.py

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,17 @@ def main(param1=None,
4242
"""
4343

4444

45+
@pytest.fixture
46+
def workspace_with_signature_docstring_disabled(workspace) -> None:
47+
workspace._config._settings["plugins"] = {
48+
"jedi_signature_help": {
49+
"include_docstring": False,
50+
},
51+
}
52+
53+
yield workspace
54+
55+
4556
def test_no_signature(workspace) -> None:
4657
# Over blank line
4758
sig_position = {"line": 9, "character": 0}
@@ -104,3 +115,17 @@ def test_docstring_params(regex, doc) -> None:
104115
m = regex.match(doc)
105116
assert m.group("param") == "test"
106117
assert m.group("doc") == "parameter docstring"
118+
119+
120+
def test_signature_without_docstring(
121+
workspace_with_signature_docstring_disabled,
122+
) -> None:
123+
# Over '( ' in main(
124+
sig_position = {"line": 10, "character": 5}
125+
doc = Document(DOC_URI, workspace_with_signature_docstring_disabled, DOC)
126+
127+
sig_info = signature.pylsp_signature_help(doc._config, doc, sig_position)
128+
129+
sigs = sig_info["signatures"]
130+
assert len(sigs) == 1
131+
assert sigs[0]["documentation"] == {"kind": "markdown", "value": ""}

0 commit comments

Comments
 (0)