8000 Autopep8 support (#304) · python-lsp/python-lsp-server@0f353bc · GitHub
[go: up one dir, main page]

Skip to content

Commit 0f353bc

Browse files
authored
Autopep8 support (#304)
1 parent fe32bcb commit 0f353bc

File tree

6 files changed

+116
-5
lines changed

6 files changed

+116
-5
lines changed

README.rst

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,8 @@ If the respective dependencies are found, the following optional providers will
2727
* McCabe_ linter for complexity checking
2828
* pycodestyle_ linter for style checking
2929
* pydocstyle_ linter for docstring style checking
30-
* YAPF_ for code formatting
30+
* autopep8_ for code formatting
31+
* YAPF_ for code formatting (preferred over autopep8)
3132

3233
Optional providers can be installed using the `extras` syntax. To install YAPF_ formatting for example:
3334

@@ -144,5 +145,6 @@ This project is made available under the MIT License.
144145
.. _pycodestyle: https://github.com/PyCQA/pycodestyle
145146
.. _pydocstyle: https://github.com/PyCQA/pydocstyle
146147
.. _YAPF: https://github.com/google/yapf
148+
.. _autopep8: https://github.com/hhatto/autopep8
147149
.. _pyls-mypy: https://github.com/tomv564/pyls-mypy
148150
.. _pyls-isort: https://github.com/paradoxxxzero/pyls-isort

pyls/plugins/autopep8_format.py

Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
# Copyright 2018 Palantir Technologies, Inc.
2+
import logging
3+
from autopep8 import fix_code
4+
from pyls import hookimpl
5+
6+
log = logging.getLogger(__name__)
7+
8+
9+
@hookimpl
10+
def pyls_format_document(config, document):
11+
log.info("Formatting document %s with autopep8", document)
12+
return _format(config, document)
13+
14+
15+
@hookimpl
16+
def pyls_format_range(config, document, range): # pylint: disable=redefined-builtin
17+
log.info("Formatting document %s in range %s with autopep8", document, range)
18+
19+
# First we 'round' the range up/down to full lines only
20+
range['start']['character'] = 0
21+
range['end']['line'] += 1
22+
range['end']['character'] = 0
23+
24+
# Add 1 for 1-indexing vs LSP's 0-indexing
25+
line_range = (range['start']['line'] < 8000 span class=pl-c1>+ 1, range['end']['line'] + 1)
26+
return _format(config, document, line_range=line_range)
27+
28+
29+
def _format(config, document, line_range=None):
30+
options = _autopep8_config(config)
31+
if line_range:
32+
options['line_range'] = list(line_range)
33+
34+
new_source = fix_code(document.source, options=options)
35+
36+
if new_source == document.source:
37+
return []
38+
39+
# I'm too lazy at the moment to parse diffs into TextEdit items
40+
# So let's just return the entire file...
41+
return [{
42+
'range': {
43+
'start': {'line': 0, 'character': 0},
44+
# End char 0 of the line after our document
45+
'end': {'line': len(document.lines), 'character': 0}
46+
},
47+
'newText': new_source
48+
}]
49+
50+
51+
def _autopep8_config(config):
52+
# We user pycodestyle settings to avoid redefining things
53+
settings = config.plugin_settings('pycodestyle')
54+
options = {
55+
'exclude': settings.get('exclude'),
56+
'hang_closing': settings.get('hangClosing'),
57+
'ignore': settings.get('ignore'),
58+
'max_line_length': settings.get('maxLineLength'),
59+
'select': settings.get('select'),
60+
}
61+
62+
# Filter out null options
63+
return {k: v for k, v in options.items() if v}

pyls/plugins/format.py renamed to pyls/plugins/yapf_format.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,12 +8,12 @@
88
log = logging.getLogger(__name__)
99

1010

11-
@hookimpl
11+
@hookimpl(tryfirst=True) # Prefer YAPF over autopep8 if available
1212
def pyls_format_document(document):
1313
return _format(document)
1414

1515

16-
@hookimpl
16+
@hookimpl(tryfirst=True) # Prefer YAPF over autopep8 if available
1717
def pyls_format_range(document, range): # pylint: disable=redefined-builtin
1818
# First we 'round' the range up/down to full lines only
1919
range['start']['character'] = 0

setup.py

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@
3232
# requirements files see:
3333
# https://packaging.python.org/en/latest/requirements.html
3434
install_requires=[
35+
'autopep8',
3536
'configparser',
3637
'future>=0.14.0',
3738
'futures; python_version<"3.2"',
@@ -70,6 +71,7 @@
7071
'pyls = pyls.__main__:main',
7172
],
7273
'pyls': [
74+
'autopep8 = pyls.plugins.autopep8_format',
7375
'jedi_completion = pyls.plugins.jedi_completion',
7476
'jedi_definition = pyls.plugins.definition',
7577
'jedi_hover = pyls.plugins.hover',
@@ -82,7 +84,7 @@
8284
'pyflakes = pyls.plugins.pyflakes_lint',
8385
'rope_completion = pyls.plugins.rope_completion',
8486
'rope_rename = pyls.plugins.rope_rename',
85-
'yapf = pyls.plugins.format',
87+
'yapf = pyls.plugins.yapf_format',
8688
]
8789
},
8890
)

test/plugins/test_autopep8_format.py

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
# Copyright 2017 Palantir Technologies, Inc.
2+
from pyls import uris
3+
from pyls.plugins.autopep8_format import pyls_format_document, pyls_format_range
4+
from pyls.workspace import Document
5+
6+
DOC_URI = uris.from_fs_path(__file__)
7+
DOC = """a = 123
8+
9+
10+
11+
12+
def func():
13+
pass
14+
"""
15+
16+
GOOD_DOC = """A = ['hello', 'world']\n"""
17+
18+
19+
def test_format(config):
20+
doc = Document(DOC_URI, DOC)
21+
res = pyls_format_document(config, doc)
22+
23+
assert len(res) == 1
24+
assert res[0]['newText'] == "a = 123\n\n\ndef func():\n pass\n"
25+
26+
27+
def test_range_format(config):
28+
doc = Document(DOC_URI, DOC)
29+
30+
def_range = {
31+
'start': {'line': 0, 'character': 0},
32+
'end': {'line': 2, 'character': 0}
33+
}
34+
res = pyls_format_range(config, doc, def_range)
35+
36+
assert len(res) == 1
37+
38+
# Make sure the func is still badly formatted
39+
assert res[0]['newText'] == "a = 123\n\n\n\n\ndef func():\n pass\n"
40+
41+
42+
def test_no_change(config):
43+
doc = Document(DOC_URI, GOOD_DOC)
44+
assert not pyls_format_document(config, doc)

test/plugins/test_format.py renamed to test/plugins/test_yapf_format.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
# Copyright 2017 Palantir Technologies, Inc.
22
from pyls import uris
3-
from pyls.plugins.format import pyls_format_document, pyls_format_range
3+
from pyls.plugins.yapf_format import pyls_format_document, pyls_format_range
44
from pyls.workspace import Document
55

66
DOC_URI = uris.from_fs_path(__file__)

0 commit comments

Comments
 (0)
0