Skip to content

Commit

Permalink
Narrow text edits
Browse files Browse the repository at this point in the history
  • Loading branch information
MichaReiser committed Feb 1, 2024
1 parent 2e67c8e commit 29d0ef8
Showing 1 changed file with 36 additions and 4 deletions.
40 changes: 36 additions & 4 deletions ruff_lsp/server.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,6 @@
from pathlib import Path
from typing import Any, List, NamedTuple, Sequence, Union, cast

from lsprotocol import validators
from lsprotocol.types import (
CODE_ACTION_RESOLVE,
INITIALIZE,
Expand Down Expand Up @@ -1376,16 +1375,49 @@ def _fixed_source_to_edits(
fixed_source = "".join(fixed_source)

new_source = _match_line_endings(original_source, fixed_source)

if new_source == original_source:
return []

# Reduce the text edit by omitting the common suffix and postfix (lines)
# from the text edit. I chose this basic diffing because "proper" diffing has
# the downside that it can be very slow in some cases. Black uses a diffing approach
# that takes time into consideration, but it requires spawning a thread to stop
# the diffing after a given time, which feels very heavy weight.
# This basic "diffing" has a guaranteed `O(n)` runtime and is sufficient to
# prevent transmitting the entire source document when formatting a range
# or formatting a document where most of the code remains unchanged.
#
# https://github.com/microsoft/vscode-black-formatter/blob/main/bundled/tool/lsp_edit_utils.py
new_lines = new_source.splitlines(True)
original_lines = original_source.splitlines(True)

start_offset = 0
end_offset = 0

for new_line, original_line in zip(new_lines, original_lines):
if new_line == original_line:
start_offset += 1
else:
break

for new_line, original_line in zip(
reversed(new_lines[start_offset:]), reversed(original_lines[start_offset:])
):
if new_line == original_line:
end_offset += 1
else:
break

trimmed_new_source = "".join(new_lines[start_offset : len(new_lines) - end_offset])

return [
TextEdit(
range=Range(
start=Position(line=0, character=0),
end=Position(line=validators.UINTEGER_MAX_VALUE, character=0),
start=Position(line=start_offset, character=0),
end=Position(line=len(original_lines) - end_offset, character=0),
),
new_text=new_source,
new_text=trimmed_new_source,
)
]

Expand Down

0 comments on commit 29d0ef8

Please sign in to comment.