Skip to content

Commit fdb69ab

Browse files
authored
populate location list with all modified changes in a WorkspaceEdit (#555)
1 parent d821bd8 commit fdb69ab

File tree

6 files changed

+175
-2
lines changed

6 files changed

+175
-2
lines changed

autoload/lsp/utils/location.vim

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,7 @@ endfunction
5353
" 'filename',
5454
" 'lnum',
5555
" 'col',
56+
" 'text',
5657
" 'viewstart?',
5758
" 'viewend?',
5859
" }

autoload/lsp/utils/text_edit.vim

Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,70 @@ function! lsp#utils#text_edit#apply_text_edits(uri, text_edits) abort
1414
endif
1515
endfunction
1616

17+
" @summary Use this to convert textedit to vim list that is compatible with
18+
" quickfix and locllist items
19+
" @param uri = DocumentUri
20+
" @param text_edit = TextEdit | TextEdit[]
21+
" @returns []
22+
function! lsp#utils#text_edit#_lsp_to_vim_list(uri, text_edit) abort
23+
let l:result = []
24+
let l:cache = {}
25+
if type(a:text_edit) == type([]) " TextEdit[]
26+
for l:text_edit in a:text_edit
27+
let l:vim_loc = s:lsp_text_edit_item_to_vim(a:uri, l:text_edit, l:cache)
28+
if !empty(l:vim_loc)
29+
call add(l:result, l:vim_loc)
30+
endif
31+
endfor
32+
else " TextEdit
33+
let l:vim_loc = s:lsp_text_edit_item_to_vim(a:uri, a:text_edit, l:cache)
34+
if !empty(l:vim_loc)
35+
call add(l:result, l:vim_loc)
36+
endif
37+
endif
38+
return l:result
39+
endfunction
40+
41+
" @param uri = DocumentUri
42+
" @param text_edit = TextEdit
43+
" @param cache = {} empty dict
44+
" @returns {
45+
" 'filename',
46+
" 'lnum',
47+
" 'col',
48+
" 'text',
49+
" }
50+
function! s:lsp_text_edit_item_to_vim(uri, text_edit, cache) abort
51+
if !lsp#utils#is_file_uri(a:uri)
52+
return v:null
53+
endif
54+
55+
let l:path = lsp#utils#uri_to_path(a:uri)
56+
let l:range = a:text_edit['range']
57+
let [l:line, l:col] = lsp#utils#position#lsp_to_vim(l:path, l:range['start'])
58+
59+
let l:index = l:line - 1
60+
if has_key(a:cache, l:path)
61+
let l:text = a:cache[l:path][l:index]
62+
else
63+
let l:contents = getbufline(l:path, 1, '$')
64+
if !empty(l:contents)
65+
let l:text = get(l:contents, l:index, '')
66+
else
67+
let l:contents = readfile(l:path)
68+
let a:cache[l:path] = l:contents
69+
let l:text = get(l:contents, l:index, '')
70+
endif
71+
endif
72+
73+
return {
74+
\ 'filename': l:path,
75+
\ 'lnum': l:line,
76+
\ 'col': l:col,
77+
\ 'text': l:text
78+
\ }
79+
endfunction
80+
1781
"
1882
" _apply
1983
"
Lines changed: 17 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,27 @@
11
" Applies WorkspaceEdit changes.
22
function! lsp#utils#workspace_edit#apply_workspace_edit(workspace_edit) abort
3+
let l:loclist_items = []
4+
35
if has_key(a:workspace_edit, 'documentChanges')
46
for l:text_document_edit in a:workspace_edit['documentChanges']
5-
call lsp#utils#text_edit#apply_text_edits(l:text_document_edit['textDocument']['uri'], l:text_document_edit['edits'])
7+
let l:loclist_items += s:_apply(l:text_document_edit['textDocument']['uri'], l:text_document_edit['edits'])
68
endfor
79
elseif has_key(a:workspace_edit, 'changes')
810
for [l:uri, l:text_edits] in items(a:workspace_edit['changes'])
9-
call lsp#utils#text_edit#apply_text_edits(l:uri, l:text_edits)
11+
let l:loclist_items += s:_apply(l:uri, l:text_edits)
1012
endfor
1113
endif
14+
15+
if g:lsp_show_workspace_edits
16+
call setloclist(0, l:loclist_items, 'r')
17+
execute 'lopen'
18+
endif
19+
endfunction
20+
21+
"
22+
" _apply
23+
"
24+
function! s:_apply(uri, text_edits) abort
25+
call lsp#utils#text_edit#apply_text_edits(a:uri, a:text_edits)
26+
return lsp#utils#text_edit#_lsp_to_vim_list(a:uri, a:text_edits)
1227
endfunction

doc/vim-lsp.txt

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -617,6 +617,17 @@ g:lsp_signature_help_enabled *g:lsp_signature_help_enabled*
617617
let g:lsp_signature_help_enabled = 1
618618
let g:lsp_signature_help_enabled = 0
619619
620+
g:lsp_show_workspace_edits *g:lsp_show_workspace_edits*
621+
Type: |Boolean|
622+
Default: `0`
623+
624+
Enable showing changes made in a workspace edit in the |location-list|.
625+
Set to `0` to disable.
626+
627+
Example: >
628+
let g:lsp_show_workspace_edits = 1
629+
let g:lsp_show_workspace_edits = 0
630+
620631
g:lsp_fold_enabled *g:lsp_fold_enabled*
621632
Type: |Number|
622633
Default: `1`

plugin/lsp.vim

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,7 @@ let g:lsp_peek_alignment = get(g:, 'lsp_peek_alignment', 'center')
4141
let g:lsp_preview_max_width = get(g:, 'lsp_preview_max_width', -1)
4242
let g:lsp_preview_max_height = get(g:, 'lsp_preview_max_height', -1)
4343
let g:lsp_signature_help_enabled = get(g:, 'lsp_signature_help_enabled', 1)
44+
let g:lsp_show_workspace_edits = get(g:, 'lsp_show_workspace_edits', 0)
4445
let g:lsp_fold_enabled = get(g:, 'lsp_fold_enabled', 1)
4546
let g:lsp_hover_conceal = get(g:, 'lsp_hover_conceal', 1)
4647
let g:lsp_ignorecase = get(g:, 'lsp_ignorecase', &ignorecase)
Lines changed: 81 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,81 @@
1+
Describe lsp#utils#workspace_edit
2+
3+
Describe lsp#utils#text_edit#apply_workspace_edit
4+
It populates location list with changes
5+
let g:lsp_show_workspace_edits = 1
6+
7+
call lsp#utils#workspace_edit#apply_workspace_edit({
8+
\ 'documentChanges': [{
9+
\ 'textDocument': { 'uri': 'file:///path/to/file' },
10+
\ 'edits': [
11+
\ {
12+
\ "range": {
13+
\ "start": {
14+
\ "character": 0,
15+
\ "line": 1
16+
\ },
17+
\ "end": {
18+
\ "character": 0,
19+
\ "line": 1
20+
\ }
21+
\ },
22+
\ "newText": "import java.util.LinkedList;"
23+
\ },
24+
\ {
25+
\ "range": {
26+
\ "start": {
27+
\ "character": 0,
28+
\ "line": 0
29+
\ },
30+
\ "end": {
31+
\ "character": 0,
32+
\ "line": 0
33+
\ }
34+
\ },
35+
\ "newText": "import java.util.ArrayList;"
36+
\ }
37+
\ ]
38+
\ }]})
39+
40+
let l:loclist = getloclist(0)
41+
42+
Assert Equals(len(l:loclist), 2)
43+
44+
Assert Equals(l:loclist[0]['lnum'], 2)
45+
Assert Equals(l:loclist[0]['col'], 1)
46+
Assert Equals(l:loclist[0]['text'], 'import java.util.LinkedList;')
47+
48+
Assert Equals(l:loclist[1]['lnum'], 1)
49+
Assert Equals(l:loclist[1]['col'], 1)
50+
Assert Equals(l:loclist[1]['text'], 'import java.util.ArrayList;')
51+
52+
end
53+
54+
It should not set location list if not enabled
55+
let g:lsp_show_workspace_edits = 0
56+
57+
call lsp#utils#workspace_edit#apply_workspace_edit({
58+
\ 'documentChanges': [{
59+
\ 'textDocument': { 'uri': 'file:///path/to/file' },
60+
\ 'edits': [
61+
\ {
62+
\ "range": {
63+
\ "start": {
64+
\ "character": 0,
65+
\ "line": 3
66+
\ },
67+
\ "end": {
68+
\ "character": 0,
69+
\ "line": 3
70+
\ }
71+
\ },
72+
\ "newText": "import java.util.LinkedList;"
73+
\ }
74+
\ ]
75+
\ }]})
76+
77+
Assert Equals(len(getloclist(0)), 0)
78+
End
79+
End
80+
End
81+

0 commit comments

Comments
 (0)