-
Notifications
You must be signed in to change notification settings - Fork 187
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Parse YAPF diffs into TextEdits (instead of sending the full doc) (#136)
- Loading branch information
1 parent
66c7cca
commit a9d503c
Showing
8 changed files
with
618 additions
and
69 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,94 @@ | ||
# Copyright 2017-2020 Palantir Technologies, Inc. | ||
# Copyright 2021- Python Language Server Contributors. | ||
|
||
def get_well_formatted_range(lsp_range): | ||
start = lsp_range['start'] | ||
end = lsp_range['end'] | ||
|
||
if start['line'] > end['line'] or (start['line'] == end['line'] and start['character'] > end['character']): | ||
return {'start': end, 'end': start} | ||
|
||
return lsp_range | ||
|
||
|
||
def get_well_formatted_edit(text_edit): | ||
lsp_range = get_well_formatted_range(text_edit['range']) | ||
if lsp_range != text_edit['range']: | ||
return {'newText': text_edit['newText'], 'range': lsp_range} | ||
|
||
return text_edit | ||
|
||
|
||
def compare_text_edits(a, b): | ||
diff = a['range']['start']['line'] - b['range']['start']['line'] | ||
if diff == 0: | ||
return a['range']['start']['character'] - b['range']['start']['character'] | ||
|
||
return diff | ||
|
||
|
||
def merge_sort_text_edits(text_edits): | ||
if len(text_edits) <= 1: | ||
return text_edits | ||
|
||
p = len(text_edits) // 2 | ||
left = text_edits[:p] | ||
right = text_edits[p:] | ||
|
||
merge_sort_text_edits(left) | ||
merge_sort_text_edits(right) | ||
|
||
left_idx = 0 | ||
right_idx = 0 | ||
i = 0 | ||
while left_idx < len(left) and right_idx < len(right): | ||
ret = compare_text_edits(left[left_idx], right[right_idx]) | ||
if ret <= 0: | ||
# smaller_equal -> take left to preserve order | ||
text_edits[i] = left[left_idx] | ||
i += 1 | ||
left_idx += 1 | ||
else: | ||
# greater -> take right | ||
text_edits[i] = right[right_idx] | ||
i += 1 | ||
right_idx += 1 | ||
while left_idx < len(left): | ||
text_edits[i] = left[left_idx] | ||
i += 1 | ||
left_idx += 1 | ||
while right_idx < len(right): | ||
text_edits[i] = right[right_idx] | ||
i += 1 | ||
right_idx += 1 | ||
return text_edits | ||
|
||
|
||
class OverLappingTextEditException(Exception): | ||
""" | ||
Text edits are expected to be sorted | ||
and compressed instead of overlapping. | ||
This error is raised when two edits | ||
are overlapping. | ||
""" | ||
|
||
|
||
def apply_text_edits(doc, text_edits): | ||
text = doc.source | ||
sorted_edits = merge_sort_text_edits(list(map(get_well_formatted_edit, text_edits))) | ||
last_modified_offset = 0 | ||
spans = [] | ||
for e in sorted_edits: | ||
start_offset = doc.offset_at_position(e['range']['start']) | ||
if start_offset < last_modified_offset: | ||
raise OverLappingTextEditException('overlapping edit') | ||
|
||
if start_offset > last_modified_offset: | ||
spans.append(text[last_modified_offset:start_offset]) | ||
|
||
if len(e['newText']): | ||
spans.append(e['newText']) | ||
last_modified_offset = doc.offset_at_position(e['range']['end']) | ||
|
||
spans.append(text[last_modified_offset:]) | ||
return ''.join(spans) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.