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

Start to add rename functioinality #70

Merged
merged 1 commit into from
Oct 30, 2024
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.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
27 changes: 25 additions & 2 deletions pylspclient/lsp_client.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,13 +8,13 @@
SymbolInformation,
LocationLink,
Location,
)
from .lsp_pydantic_strcuts import (
Position,
SignatureHelp,
CompletionContext,
CompletionItem,
CompletionList,
WorkspaceEdit,
TextEdit,
)


Expand Down Expand Up @@ -261,3 +261,26 @@ def definition(
return [Location.model_validate(result) for result in result_dict]
except ValidationError:
return [LocationLink.model_validate(result) for result in result_dict]

def rename(self, text_document: TextDocumentIdentifier, position: Position, new_name: str) -> WorkspaceEdit:
"""Send a rename request to the language server at the specified position."""
response = self.lsp_endpoint.call_method(
"textDocument/rename",
textDocument=text_document,
position=position.dict(),
newName=new_name,
)

# Parse response into WorkspaceEdit using Pydantic
changes = {
uri: [
TextEdit(
range_start=Position(**edit["range"]["start"]),
range_end=Position(**edit["range"]["end"]),
new_text=edit["newText"]
)
for edit in edits
]
for uri, edits in response.get("changes", {}).items()
}
return WorkspaceEdit(changes=changes)
2 changes: 1 addition & 1 deletion pylspclient/lsp_endpoint.py
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,7 @@ def run(self) -> None:
# a call for notify
if method not in self.notify_callbacks:
# Have nothing to do with this.
print("Notify method not found: {method}.".format(method=method))
print("Notify method not found: {method}, {params}".format(method=method, params=params))
else:
self.notify_callbacks[method](params)
else:
Expand Down
10 changes: 9 additions & 1 deletion pylspclient/lsp_pydantic_strcuts.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
from typing import Optional, List, Union
from typing import Dict, Optional, List, Union
from enum import Enum, IntEnum
from pydantic import BaseModel, HttpUrl

Expand Down Expand Up @@ -240,3 +240,11 @@ class CompletionItem(BaseModel):
class CompletionList(BaseModel):
isIncomplete: bool
items: List[CompletionItem]

class TextEdit(BaseModel):
range_start: Position
range_end: Position
new_text: str

class WorkspaceEdit(BaseModel):
changes: Dict[str, List[TextEdit]]
23 changes: 10 additions & 13 deletions tests/test_pylsp_integration.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@
from os import path, listdir
import pytest
import subprocess
import threading

import pylspclient
from pylspclient.lsp_pydantic_strcuts import TextDocumentIdentifier, TextDocumentItem, LanguageIdentifier, Position, Range, CompletionTriggerKind, CompletionContext
Expand All @@ -18,18 +17,6 @@ def from_uri(path: str) -> str:
return path.replace("uri://", "").replace("uri:", "")


class ReadPipe(threading.Thread):
def __init__(self, pipe):
threading.Thread.__init__(self)
self.pipe = pipe

def run(self):
line = self.pipe.readline().decode('utf-8')
while line:
print(line)
line = self.pipe.readline().decode('utf-8')


@pytest.fixture
def server_process() -> subprocess.Popen:
pylsp_cmd = ["python", "-m", "pylsp"]
Expand Down Expand Up @@ -188,3 +175,13 @@ def test_completion(lsp_client: pylspclient.LspClient):
context = CompletionContext(triggerKind=CompletionTriggerKind.Invoked)
completion_result = lsp_client.completion(TextDocumentIdentifier(uri=uri), position, context)
assert all([i.insertText.startswith(to_complete) for i in completion_result.items])


def test_rename(lsp_client: pylspclient.LspClient):
add_dir(lsp_client, DEFAULT_ROOT)
file_path = "lsp_client.py"
relative_file_path = path.join(DEFAULT_ROOT, file_path)
uri = to_uri(relative_file_path)
file_content = open(relative_file_path, "r").read()
position = string_in_text_to_position(file_content, "call_method")
lsp_client.rename(TextDocumentIdentifier(uri=uri), position, "call_method2")
Loading