|
1 |
| -function! lsp#utils#text_edit#apply_text_edits(uri, text_edits) abort |
2 |
| - let l:current_bufname = bufname('%') |
3 |
| - let l:target_bufname = lsp#utils#uri_to_path(a:uri) |
4 |
| - let l:cursor_position = lsp#get_position() |
5 |
| - |
6 |
| - call s:_switch(l:target_bufname) |
7 |
| - for l:text_edit in s:_normalize(a:text_edits) |
8 |
| - call s:_apply(bufnr(l:target_bufname), l:text_edit, l:cursor_position) |
9 |
| - endfor |
10 |
| - call s:_switch(l:current_bufname) |
| 1 | +let s:TextEdit = vital#lsp#import('VS.LSP.TextEdit') |
11 | 2 |
|
12 |
| - if bufnr(l:current_bufname) == bufnr(l:target_bufname) |
13 |
| - call cursor(lsp#utils#position#lsp_to_vim('%', l:cursor_position)) |
14 |
| - endif |
| 3 | +function! lsp#utils#text_edit#apply_text_edits(uri, text_edits) abort |
| 4 | + return s:TextEdit.apply(lsp#utils#uri_to_path(a:uri), deepcopy(a:text_edits)) |
15 | 5 | endfunction
|
16 | 6 |
|
| 7 | + |
17 | 8 | " @summary Use this to convert textedit to vim list that is compatible with
|
18 | 9 | " quickfix and locllist items
|
19 | 10 | " @param uri = DocumentUri
|
@@ -78,141 +69,3 @@ function! s:lsp_text_edit_item_to_vim(uri, text_edit, cache) abort
|
78 | 69 | \ }
|
79 | 70 | endfunction
|
80 | 71 |
|
81 |
| -" |
82 |
| -" _apply |
83 |
| -" |
84 |
| -function! s:_apply(bufnr, text_edit, cursor_position) abort |
85 |
| - " create before/after line. |
86 |
| - let l:start_line = getline(a:text_edit['range']['start']['line'] + 1) |
87 |
| - let l:end_line = getline(a:text_edit['range']['end']['line'] + 1) |
88 |
| - let l:before_line = strcharpart(l:start_line, 0, a:text_edit['range']['start']['character']) |
89 |
| - let l:after_line = strcharpart(l:end_line, a:text_edit['range']['end']['character'], strchars(l:end_line) - a:text_edit['range']['end']['character']) |
90 |
| - |
91 |
| - " create new lines. |
92 |
| - let l:new_lines = lsp#utils#_split_by_eol(a:text_edit['newText']) |
93 |
| - let l:new_lines[0] = l:before_line . l:new_lines[0] |
94 |
| - let l:new_lines[-1] = l:new_lines[-1] . l:after_line |
95 |
| - |
96 |
| - " save length. |
97 |
| - let l:new_lines_len = len(l:new_lines) |
98 |
| - let l:range_len = (a:text_edit['range']['end']['line'] - a:text_edit['range']['start']['line']) + 1 |
99 |
| - |
100 |
| - " fixendofline |
101 |
| - let l:buffer_length = len(getbufline(a:bufnr, '^', '$')) |
102 |
| - let l:should_fixendofline = lsp#utils#buffer#_get_fixendofline(a:bufnr) |
103 |
| - let l:should_fixendofline = l:should_fixendofline && l:new_lines[-1] ==# '' |
104 |
| - let l:should_fixendofline = l:should_fixendofline && l:buffer_length <= a:text_edit['range']['end']['line'] |
105 |
| - let l:should_fixendofline = l:should_fixendofline && a:text_edit['range']['end']['character'] == 0 |
106 |
| - if l:should_fixendofline |
107 |
| - call remove(l:new_lines, -1) |
108 |
| - endif |
109 |
| - |
110 |
| - " fix cursor pos |
111 |
| - if a:text_edit['range']['end']['line'] < a:cursor_position['line'] |
112 |
| - " fix cursor line |
113 |
| - let a:cursor_position['line'] += l:new_lines_len - l:range_len |
114 |
| - elseif a:text_edit['range']['end']['line'] == a:cursor_position['line'] && a:text_edit['range']['end']['character'] <= a:cursor_position['character'] |
115 |
| - " fix cursor line and col |
116 |
| - let a:cursor_position['line'] += l:new_lines_len - l:range_len |
117 |
| - let l:end_character = strchars(l:new_lines[-1]) - strchars(l:after_line) |
118 |
| - let l:end_offset = a:cursor_position['character'] - a:text_edit['range']['end']['character'] |
119 |
| - let a:cursor_position['character'] = l:end_character + l:end_offset |
120 |
| - endif |
121 |
| - |
122 |
| - " append or delete lines. |
123 |
| - if l:new_lines_len > l:range_len |
124 |
| - call append(a:text_edit['range']['start']['line'], repeat([''], l:new_lines_len - l:range_len)) |
125 |
| - elseif l:new_lines_len < l:range_len |
126 |
| - let l:offset = l:range_len - l:new_lines_len |
127 |
| - call s:delete(a:bufnr, a:text_edit['range']['start']['line'] + 1, a:text_edit['range']['start']['line'] + l:offset) |
128 |
| - endif |
129 |
| - |
130 |
| - " set lines. |
131 |
| - call setline(a:text_edit['range']['start']['line'] + 1, l:new_lines) |
132 |
| -endfunction |
133 |
| - |
134 |
| -" |
135 |
| -" _normalize |
136 |
| -" |
137 |
| -function! s:_normalize(text_edits) abort |
138 |
| - let l:text_edits = type(a:text_edits) == type([]) ? a:text_edits : [a:text_edits] |
139 |
| - let l:text_edits = filter(copy(l:text_edits), { _, text_edit -> type(text_edit) == type({}) }) |
140 |
| - let l:text_edits = s:_range(l:text_edits) |
141 |
| - let l:text_edits = sort(copy(l:text_edits), function('s:_compare', [], {})) |
142 |
| - let l:text_edits = s:_check(l:text_edits) |
143 |
| - return reverse(l:text_edits) |
144 |
| -endfunction |
145 |
| - |
146 |
| -" |
147 |
| -" _range |
148 |
| -" |
149 |
| -function! s:_range(text_edits) abort |
150 |
| - for l:text_edit in a:text_edits |
151 |
| - if l:text_edit.range.start.line > l:text_edit.range.end.line || ( |
152 |
| - \ l:text_edit.range.start.line == l:text_edit.range.end.line && |
153 |
| - \ l:text_edit.range.start.character > l:text_edit.range.end.character |
154 |
| - \ ) |
155 |
| - let l:text_edit.range = { 'start': l:text_edit.range.end, 'end': l:text_edit.range.start } |
156 |
| - endif |
157 |
| - endfor |
158 |
| - return a:text_edits |
159 |
| -endfunction |
160 |
| - |
161 |
| -" |
162 |
| -" _check |
163 |
| -" |
164 |
| -" LSP Spec says `multiple text edits can not overlap those ranges`. |
165 |
| -" This function check it. But does not throw error. |
166 |
| -" |
167 |
| -function! s:_check(text_edits) abort |
168 |
| - if len(a:text_edits) > 1 |
169 |
| - let l:range = a:text_edits[0].range |
170 |
| - for l:text_edit in a:text_edits[1 : -1] |
171 |
| - if l:range.end.line > l:text_edit.range.start.line || ( |
172 |
| - \ l:range.end.line == l:text_edit.range.start.line && |
173 |
| - \ l:range.end.character > l:text_edit.range.start.character |
174 |
| - \ ) |
175 |
| - call lsp#log('text_edit: range overlapped.') |
176 |
| - endif |
177 |
| - let l:range = l:text_edit.range |
178 |
| - endfor |
179 |
| - endif |
180 |
| - return a:text_edits |
181 |
| -endfunction |
182 |
| - |
183 |
| -" |
184 |
| -" _compare |
185 |
| -" |
186 |
| -function! s:_compare(text_edit1, text_edit2) abort |
187 |
| - let l:diff = a:text_edit1.range.start.line - a:text_edit2.range.start.line |
188 |
| - if l:diff == 0 |
189 |
| - return a:text_edit1.range.start.character - a:text_edit2.range.start.character |
190 |
| - endif |
191 |
| - return l:diff |
192 |
| -endfunction |
193 |
| - |
194 |
| -" |
195 |
| -" _switch |
196 |
| -" |
197 |
| -function! s:_switch(path) abort |
198 |
| - if bufnr(a:path) >= 0 |
199 |
| - execute printf('keepalt keepjumps %sbuffer!', bufnr(a:path)) |
200 |
| - else |
201 |
| - execute printf('keepalt keepjumps edit! %s', fnameescape(a:path)) |
202 |
| - endif |
203 |
| -endfunction |
204 |
| - |
205 |
| -" |
206 |
| -" delete |
207 |
| -" |
208 |
| -function! s:delete(bufnr, start, end) abort |
209 |
| - if exists('*deletebufline') |
210 |
| - call deletebufline(a:bufnr, a:start, a:end) |
211 |
| - else |
212 |
| - let l:foldenable = &foldenable |
213 |
| - setlocal nofoldenable |
214 |
| - execute printf('%s,%sdelete _', a:start, a:end) |
215 |
| - let &foldenable = l:foldenable |
216 |
| - endif |
217 |
| -endfunction |
218 |
| - |
0 commit comments