|
16 | 16 | from pathlib import Path |
17 | 17 | from typing import Any, List, NamedTuple, Sequence, Union, cast |
18 | 18 |
|
19 | | -from lsprotocol import validators |
20 | 19 | from lsprotocol.types import ( |
21 | 20 | CODE_ACTION_RESOLVE, |
22 | 21 | INITIALIZE, |
@@ -1379,13 +1378,45 @@ def _fixed_source_to_edits( |
1379 | 1378 | if new_source == original_source: |
1380 | 1379 | return [] |
1381 | 1380 |
|
| 1381 | + # Reduce the text edit by omitting the common suffix and postfix (lines) |
| 1382 | + # from the text edit. I chose this basic diffing because "proper" diffing has |
| 1383 | + # the downside that it can be very slow in some cases. Black uses a diffing approach |
| 1384 | + # that takes time into consideration, but it requires spawning a thread to stop |
| 1385 | + # the diffing after a given time, which feels very heavy weight. |
| 1386 | + # This basic "diffing" has a guaranteed `O(n)` runtime and is sufficient to |
| 1387 | + # prevent transmitting the entire source document when formatting a range |
| 1388 | + # or formatting a document where most of the code remains unchanged. |
| 1389 | + # |
| 1390 | + # https://github.com/microsoft/vscode-black-formatter/blob/main/bundled/tool/lsp_edit_utils.py |
| 1391 | + new_lines = new_source.splitlines(True) |
| 1392 | + original_lines = original_source.splitlines(True) |
| 1393 | + |
| 1394 | + start_offset = 0 |
| 1395 | + end_offset = 0 |
| 1396 | + |
| 1397 | + for new_line, original_line in zip(new_lines, original_lines): |
| 1398 | + if new_line == original_line: |
| 1399 | + start_offset += 1 |
| 1400 | + else: |
| 1401 | + break |
| 1402 | + |
| 1403 | + for new_line, original_line in zip( |
| 1404 | + reversed(new_lines[start_offset:]), reversed(original_lines[start_offset:]) |
| 1405 | + ): |
| 1406 | + if new_line == original_line: |
| 1407 | + end_offset += 1 |
| 1408 | + else: |
| 1409 | + break |
| 1410 | + |
| 1411 | + trimmed_new_source = "".join(new_lines[start_offset : len(new_lines) - end_offset]) |
| 1412 | + |
1382 | 1413 | return [ |
1383 | 1414 | TextEdit( |
1384 | 1415 | range=Range( |
1385 | | - start=Position(line=0, character=0), |
1386 | | - end=Position(line=validators.UINTEGER_MAX_VALUE, character=0), |
| 1416 | + start=Position(line=start_offset, character=0), |
| 1417 | + end=Position(line=len(original_lines) - end_offset, character=0), |
1387 | 1418 | ), |
1388 | | - new_text=new_source, |
| 1419 | + new_text=trimmed_new_source, |
1389 | 1420 | ) |
1390 | 1421 | ] |
1391 | 1422 |
|
|
0 commit comments