Skip to content

Commit 9c715d1

Browse files
committed
Determine columns for found implementations
1 parent 41a8852 commit 9c715d1

File tree

2 files changed

+41
-14
lines changed

2 files changed

+41
-14
lines changed

pylsp/plugins/rope_implementation.py

Lines changed: 35 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,11 @@
22
# Copyright 2021- Python Language Server Contributors.
33
import logging
44
import os
5+
from typing import Any
56

6-
from rope.contrib.findit import find_implementations
7+
from rope.base.project import Project
8+
from rope.base.resources import Resource
9+
from rope.contrib.findit import Location, find_implementations
710

811
from pylsp import hookimpl, uris
912

@@ -31,13 +34,37 @@ def pylsp_implementations(config, workspace, document, position):
3134
document.uri,
3235
path=os.path.join(workspace.root_path, impl.resource.path),
3336
),
34-
"range": {
35-
# TODO: `impl.region` seems to be from the start of the file
36-
# and offsets from the start of the line difficult to obtain,
37-
# so we just return the whole line for now:
38-
"start": {"line": impl.lineno - 1, "character": 0},
39-
"end": {"line": impl.lineno - 1, "character": 999},
40-
},
37+
"range": _rope_location_to_range(impl, rope_project),
4138
}
4239
for impl in impls
4340
]
41+
42+
43+
def _rope_location_to_range(
44+
location: Location, rope_project: Project
45+
) -> dict[str, Any]:
46+
# NOTE: This assumes the result is confined to a single line, which should
47+
# always be the case here because Python doesn't allow splitting up
48+
# identifiers across more than one line.
49+
start_column, end_column = _rope_region_to_columns(
50+
location.region, location.lineno, location.resource, rope_project
51+
)
52+
return {
53+
"start": {"line": location.lineno - 1, "character": start_column},
54+
"end": {"line": location.lineno - 1, "character": end_column},
55+
}
56+
57+
58+
def _rope_region_to_columns(
59+
offsets: tuple[int, int], line: int, rope_resource: Resource, rope_project: Project
60+
) -> tuple[int, int]:
61+
"""
62+
Convert pair of offsets from start of file to columns within line.
63+
64+
Assumes both offsets reside within the same line and will return nonsense
65+
for the end offset if this isn't the case.
66+
"""
67+
line_start_offset = rope_project.get_pymodule(rope_resource).lines.get_line_start(
68+
line
69+
)
70+
return offsets[0] - line_start_offset, offsets[1] - line_start_offset

test/plugins/test_implementations.py

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -47,8 +47,8 @@ def test_implementations(config, workspace, doc_uri) -> None:
4747

4848
# The implementation of 'Bird.fly'
4949
def_range = {
50-
"start": {"line": 21, "character": 0},
51-
"end": {"line": 21, "character": 999},
50+
"start": {"line": 21, "character": 8},
51+
"end": {"line": 21, "character": 11},
5252
}
5353

5454
doc = workspace.get_document(doc_uri)
@@ -63,8 +63,8 @@ def test_implementations_skipping_one_class(config, workspace, doc_uri) -> None:
6363

6464
# The implementation of 'breathe', skipping intermediate classes
6565
def_range = {
66-
"start": {"line": 18, "character": 0},
67-
"end": {"line": 18, "character": 999},
66+
"start": {"line": 18, "character": 8},
67+
"end": {"line": 18, "character": 15},
6868
}
6969

7070
doc = workspace.get_document(doc_uri)
@@ -82,8 +82,8 @@ def test_property_implementations(config, workspace, doc_uri) -> None:
8282

8383
# The property implementation 'Bird.size'
8484
def_range = {
85-
"start": {"line": 25, "character": 0},
86-
"end": {"line": 25, "character": 999},
85+
"start": {"line": 25, "character": 8},
86+
"end": {"line": 25, "character": 12},
8787
}
8888

8989
doc = workspace.get_document(doc_uri)

0 commit comments

Comments
 (0)