diff --git a/pylsp/_utils.py b/pylsp/_utils.py index 92376f6c..3a5f178f 100644 --- a/pylsp/_utils.py +++ b/pylsp/_utils.py @@ -6,6 +6,7 @@ import logging import os import pathlib +import re import threading import jedi @@ -14,6 +15,8 @@ log = logging.getLogger(__name__) +EX_SNIPPET_RE = re.compile(r"\>\>\> .*(?:\r?\n(?!\r?\n).*)*") + def debounce(interval_s, keyed_by=None): """Debounce calls to this function until interval_s seconds have passed.""" @@ -146,6 +149,19 @@ def format_docstring(contents): """ contents = contents.replace('\t', u'\u00A0' * 4) contents = contents.replace(' ', u'\u00A0' * 2) + + # If examples exist in the docstring wrap them in backticks + if ">>>" in contents: + # add an additional newline just in case the end of the + # docstring doesn't end in a blank line. + if contents[-2:] != "\n\n": + contents = f"{contents}\n" + # search for the example block regex + example_snippets = re.findall(EX_SNIPPET_RE, contents) + # wrap the snippets that were found in backticks + for snippet in example_snippets: + contents = contents.replace(snippet, f"```python\n{snippet}\n```") + return contents diff --git a/test/test_utils.py b/test/test_utils.py index 4b41155b..c03880d8 100644 --- a/test/test_utils.py +++ b/test/test_utils.py @@ -94,3 +94,82 @@ def test_clip_column(): assert _utils.clip_column(2, ['123\n', '123'], 0) == 2 assert _utils.clip_column(3, ['123\n', '123'], 0) == 3 assert _utils.clip_column(4, ['123\n', '123'], 1) == 3 + + +def test_format_docstring(): + teststr = """\ +Examples +-------- +Abc + +>>> a = 'test' +>>> b = 5 +>>> a +test +>>> b + 3 +8 + +another + +>>> x = np.array([1, 2, 3]) +>>> y = np.array([4, 5, 6]) +>>> x + y +array([5, 7, 9]) + +""" + resultstr = _utils.format_docstring(teststr) + assert resultstr == """\ +Examples +-------- +Abc + +```python +>>> a = 'test' +>>> b = 5 +>>> a +test +>>> b + 3 +8 +``` + +another + +```python +>>> x = np.array([1, 2, 3]) +>>> y = np.array([4, 5, 6]) +>>> x + y +array([5, 7, 9]) +``` + +""" + + +def test_format_docstring_missing_newline(): + teststr = """\ +Examples +-------- +Abc + +>>> a = 'test' +>>> b = 5 +>>> a +test +>>> b + 3 +8 +""" + resultstr = _utils.format_docstring(teststr) + assert resultstr == """\ +Examples +-------- +Abc + +```python +>>> a = 'test' +>>> b = 5 +>>> a +test +>>> b + 3 +8 +``` + +"""