6
6
from yapf .yapflib import file_resources
7
7
from yapf .yapflib .yapf_api import FormatCode
8
8
from pylsp import hookimpl
9
+ import whatthepatch
9
10
10
11
log = logging .getLogger (__name__ )
11
12
@@ -34,10 +35,11 @@ def pylsp_format_range(document, range): # pylint: disable=redefined-builtin
34
35
35
36
36
37
def _format (document , lines = None ):
37
- new_source , changed = FormatCode (
38
+ diff_txt , changed = FormatCode (
38
39
document .source ,
39
40
lines = lines ,
40
41
filename = document .filename ,
42
+ print_diff = True ,
41
43
style_config = file_resources .GetDefaultStyleForDir (
42
44
os .path .dirname (document .path )
43
45
)
@@ -46,13 +48,57 @@ def _format(document, lines=None):
46
48
if not changed :
47
49
return []
48
50
49
- # I'm too lazy at the moment to parse diffs into TextEdit items
50
- # So let's just return the entire file...
51
- return [{
52
- 'range' : {
53
- 'start' : {'line' : 0 , 'character' : 0 },
54
- # End char 0 of the line after our document
55
- 'end' : {'line' : len (document .lines ), 'character' : 0 }
56
- },
57
- 'newText' : new_source
58
- }]
51
+ patch_generator = whatthepatch .parse_patch (diff_txt )
52
+ diff = next (patch_generator )
53
+ patch_generator .close ()
54
+
55
+ # To keep things simple our text edits will be line based
56
+ # and uncompacted
57
+ textEdits = []
58
+ # keep track of line number since additions
59
+ # don't include the line number it's being added
60
+ # to in diffs. lsp is 0-indexed so we'll start with -1
61
+ prev_line_no = - 1
62
+ for change in diff .changes :
63
+ if change .old and change .new :
64
+ # no change
65
+ # diffs are 1-indexed
66
+ prev_line_no = change .old - 1
67
+ elif change .new :
68
+ # addition
69
+ textEdits .append ({
70
+ 'range' : {
71
+ 'start' : {
72
+ 'line' : prev_line_no + 1 ,
73
+ 'character' : 0
74
+ },
75
+ 'end' : {
76
+ 'line' : prev_line_no + 1 ,
77
+ 'character' : 0
78
+ }
79
+ },
80
+ 'newText' : change .line + '\n '
81
+ })
82
+ elif change .old :
83
+ # remove
84
+ lsp_line_no = change .old - 1
85
+ textEdits .append ({
86
+ 'range' : {
87
+ 'start' : {
88
+ 'line' : lsp_line_no ,
89
+ 'character' : 0
90
+ },
91
+ 'end' : {
92
+ # From LSP spec:
93
+ # If you want to specify a range that contains a line
94
+ # including the line ending character(s) then use an
95
+ # end position denoting the start of the next line.
96
+ 'line' : lsp_line_no + 1 ,
97
+ 'character' : 0
98
+ }
99
+ },
100
+ 'newText' : ''
101
+ })
102
+ prev_line_no = lsp_line_no
103
+
104
+ return textEdits
0 commit comments