Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

PR: Add support for textDocument/foldingRange call for code cells #15

Merged
merged 5 commits into from
Dec 11, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,7 @@ pytest -x -v pyls_spyder/tests
| LSP method | Spyder extensions |
|:-----------------------------:|:------------------------------------------------:|
| `textDocument/documentSymbol` | Find code cells `# %%` and block comments `# --` |
| `textDocument/foldingRange` | Return code cells `# %%` as code folding regions |

## Plugin configuration options
This plugin can be configured by using the key `pyls_spyder` when calling `workspace/didChangeConfiguration` on the pyls. Each configuration option is described below:
Expand Down
38 changes: 38 additions & 0 deletions pyls_spyder/plugin.py
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,13 @@ def create_symbol(name: str, document: Document,
}


def create_fold_region(start_line: int, end_line: int):
return {
'startLine': start_line,
'endLine': end_line,
}


@hookimpl
def pyls_document_symbols(config: Config,
workspace: Workspace,
Expand Down Expand Up @@ -140,3 +147,34 @@ def pyls_document_symbols(config: Config,
spyder_symbols = sorted(
spyder_symbols, key=lambda x: x['location']['range']['start']['line'])
return spyder_symbols


@hookimpl
def pyls_folding_range(
config: Config,
workspace: Workspace,
document: Document) -> List[Dict]:
lines = document.lines
cell_stack = []
cells = []
for line_num, line in enumerate(lines):
cell_rule, cell_match = CELL_REGEX.match(line)
if cell_match is not None:
percentages = cell_match.group(1)
current_line, current_level, _ = peek_symbol(cell_stack)
if cell_rule != CELL_PERCENTAGE:
cell_level = current_level + 1
else:
cell_level = len(percentages) - 1
if cell_level > current_level:
cell_stack.insert(0, (line_num, cell_level, ''))
else:
while current_level >= cell_level:
cell_stack.pop(0)
cells.append(create_fold_region(current_line, line_num))
current_line, current_level, _ = peek_symbol(cell_stack)
cell_stack.insert(0, (line_num, cell_level, ''))
for line, _, name in cell_stack:
cells.append(create_fold_region(line, line_num + 1))
cells = sorted(cells, key=lambda x: x['startLine'])
return cells
22 changes: 21 additions & 1 deletion pyls_spyder/tests/test_plugin.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@
from unittest.mock import MagicMock

# Local imports
from pyls_spyder.plugin import pyls_document_symbols
from pyls_spyder.plugin import pyls_document_symbols, pyls_folding_range


DOC_URI = uris.from_fs_path(__file__)
Expand Down Expand Up @@ -143,3 +143,23 @@ def test_disable_block_comments(config, workspace):
kind = symbol['kind']
test_results.append((name, start, end, kind))
assert expected == test_results


def test_cell_folding_regions(config, workspace):
document = Document(DOC_URI, workspace, DOC)
regions = pyls_folding_range(config, workspace, document)
expected = [
(1, 23),
(6, 10),
(10, 15),
(12, 15),
(15, 23),
(20, 23),
(23, 25)
]
test_results = []
for region in regions:
start = region['startLine']
end = region['endLine']
test_results.append((start, end))
assert expected == test_results
2 changes: 1 addition & 1 deletion setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ def get_description():
return data


REQUIREMENTS = ['python-language-server']
REQUIREMENTS = ['python-language-server >= 0.36.2']

setup(
name='pyls-spyder',
Expand Down