Skip to content

Commit 4630823

Browse files
authored
Implement register command (#735)
* Implemente register command * Add server_name to command context * Expose lsp_to_vim, vim_to_lsp API's as public
1 parent 5537fec commit 4630823

File tree

16 files changed

+212
-90
lines changed

16 files changed

+212
-90
lines changed

autoload/lsp.vim

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -166,6 +166,16 @@ function! lsp#register_server(server_info) abort
166166
doautocmd User lsp_register_server
167167
endfunction
168168

169+
"
170+
" lsp#register_command
171+
"
172+
" @param {command_name} = string
173+
" @param {callback} = funcref
174+
"
175+
function! lsp#register_command(command_name, callback) abort
176+
call lsp#ui#vim#execute_command#_register(a:command_name, a:callback)
177+
endfunction
178+
169179
function! lsp#register_notifications(name, callback) abort
170180
call add(s:notification_callbacks, { 'name': a:name, 'callback': a:callback })
171181
endfunction

autoload/lsp/ui/vim.vim

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -469,8 +469,8 @@ function! s:handle_rename_prepare(server, last_command_id, type, data) abort
469469

470470
let l:range = a:data['response']['result']
471471
let l:lines = getline(1, '$')
472-
let [l:start_line, l:start_col] = lsp#utils#position#_lsp_to_vim('%', l:range['start'])
473-
let [l:end_line, l:end_col] = lsp#utils#position#_lsp_to_vim('%', l:range['end'])
472+
let [l:start_line, l:start_col] = lsp#utils#position#lsp_to_vim('%', l:range['start'])
473+
let [l:end_line, l:end_col] = lsp#utils#position#lsp_to_vim('%', l:range['end'])
474474
if l:start_line ==# l:end_line
475475
let l:name = l:lines[l:start_line - 1][l:start_col - 1 : l:end_col - 2]
476476
else

autoload/lsp/ui/vim/code_action.vim

Lines changed: 19 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@ function! lsp#ui#vim#code_action#do(option) abort
3232
let l:range = lsp#utils#range#_get_current_line_range()
3333
endif
3434

35+
let l:bufnr = bufnr('%')
3536
let l:command_id = lsp#_new_command()
3637
for l:server_name in l:server_names
3738
let l:diagnostic = lsp#ui#vim#diagnostics#get_diagnostics_under_cursor(l:server_name)
@@ -46,13 +47,13 @@ function! lsp#ui#vim#code_action#do(option) abort
4647
\ },
4748
\ },
4849
\ 'sync': l:sync,
49-
\ 'on_notification': function('s:handle_code_action', [l:server_name, l:command_id, l:sync, l:query]),
50+
\ 'on_notification': function('s:handle_code_action', [l:server_name, l:command_id, l:sync, l:query, l:bufnr]),
5051
\ })
5152
endfor
5253
echo 'Retrieving code actions ...'
5354
endfunction
5455

55-
function! s:handle_code_action(server_name, command_id, sync, query, data) abort
56+
function! s:handle_code_action(server_name, command_id, sync, query, bufnr, data) abort
5657
" Ignore old request.
5758
if a:command_id != lsp#_last_command()
5859
return
@@ -87,40 +88,35 @@ function! s:handle_code_action(server_name, command_id, sync, query, data) abort
8788

8889
" Execute code action.
8990
if 0 < l:index && l:index <= len(l:code_actions)
90-
call s:handle_one_code_action(a:server_name, a:sync, l:code_actions[l:index - 1])
91+
call s:handle_one_code_action(a:server_name, a:sync, a:bufnr, l:code_actions[l:index - 1])
9192
endif
9293
endfunction
9394

94-
function! s:handle_executeCommand(server_name, command_or_code_action, data) abort
95-
if lsp#client#is_error(a:data['response'])
96-
call lsp#utils#error('Failed to '. a:command_or_code_action['command'] . ' for ' . a:server_name . ': ' . lsp#client#error_message(a:data['response']))
97-
return
98-
endif
99-
endfunction
100-
101-
function! s:handle_one_code_action(server_name, sync, command_or_code_action) abort
95+
function! s:handle_one_code_action(server_name, sync, bufnr, command_or_code_action) abort
10296
" has WorkspaceEdit.
10397
if has_key(a:command_or_code_action, 'edit')
10498
call lsp#utils#workspace_edit#apply_workspace_edit(a:command_or_code_action['edit'])
10599
endif
106100

107101
" Command.
108102
if has_key(a:command_or_code_action, 'command') && type(a:command_or_code_action['command']) == type('')
109-
call lsp#send_request(a:server_name, {
110-
\ 'method': 'workspace/executeCommand',
111-
\ 'params': a:command_or_code_action,
112-
\ 'sync': a:sync,
113-
\ 'on_notification': function('s:handle_executeCommand', [a:server_name, a:command_or_code_action]),
114-
\ })
103+
call lsp#ui#vim#execute_command#_execute({
104+
\ 'server_name': a:server_name,
105+
\ 'command_name': get(a:command_or_code_action, 'command', ''),
106+
\ 'command_args': get(a:command_or_code_action, 'arguments', v:null),
107+
\ 'sync': a:sync,
108+
\ 'bufnr': a:bufnr,
109+
\ })
115110

116111
" has Command.
117112
elseif has_key(a:command_or_code_action, 'command') && type(a:command_or_code_action['command']) == type({})
118-
call lsp#send_request(a:server_name, {
119-
\ 'method': 'workspace/executeCommand',
120-
\ 'params': a:command_or_code_action['command'],
121-
\ 'sync': a:sync,
122-
\ 'on_notification': function('s:handle_executeCommand', [a:server_name, a:command_or_code_action]),
123-
\ })
113+
call lsp#ui#vim#execute_command#_execute({
114+
\ 'server_name': a:server_name,
115+
\ 'command_name': get(a:command_or_code_action['command'], 'command', ''),
116+
\ 'command_args': get(a:command_or_code_action['command'], 'arguments', v:null),
117+
\ 'sync': a:sync,
118+
\ 'bufnr': a:bufnr,
119+
\ })
124120
endif
125121
endfunction
126122

autoload/lsp/ui/vim/completion.vim

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -199,7 +199,7 @@ function! s:clear_inserted_text(line, position, completed_item, completion_item)
199199
\ }])
200200

201201
" Move to complete start position.
202-
call cursor(lsp#utils#position#_lsp_to_vim('%', l:range['start']))
202+
call cursor(lsp#utils#position#lsp_to_vim('%', l:range['start']))
203203
endfunction
204204

205205
"
@@ -240,7 +240,7 @@ function! s:simple_expand_text(text) abort
240240
\ 'newText': l:text
241241
\ }])
242242

243-
let l:pos = lsp#utils#position#_lsp_to_vim('%', {
243+
let l:pos = lsp#utils#position#lsp_to_vim('%', {
244244
\ 'line': l:pos['line'],
245245
\ 'character': l:pos['character'] + l:offset
246246
\ })

autoload/lsp/ui/vim/diagnostics.vim

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -86,7 +86,7 @@ function! lsp#ui#vim#diagnostics#get_diagnostics_under_cursor(...) abort
8686
let l:closest_distance = -1
8787

8888
for l:diagnostic in l:diagnostics
89-
let [l:start_line, l:start_col] = lsp#utils#position#_lsp_to_vim('%', l:diagnostic['range']['start'])
89+
let [l:start_line, l:start_col] = lsp#utils#position#lsp_to_vim('%', l:diagnostic['range']['start'])
9090

9191
if l:line == l:start_line
9292
let l:distance = abs(l:start_col - l:col)
@@ -126,7 +126,7 @@ function! s:next_diagnostic(diagnostics) abort
126126
let l:next_line = 0
127127
let l:next_col = 0
128128
for l:diagnostic in a:diagnostics
129-
let [l:line, l:col] = lsp#utils#position#_lsp_to_vim('%', l:diagnostic['range']['start'])
129+
let [l:line, l:col] = lsp#utils#position#lsp_to_vim('%', l:diagnostic['range']['start'])
130130
if l:line > l:view['lnum']
131131
\ || (l:line == l:view['lnum'] && l:col > l:view['col'] + 1)
132132
let l:next_line = l:line
@@ -137,7 +137,7 @@ function! s:next_diagnostic(diagnostics) abort
137137

138138
if l:next_line == 0
139139
" Wrap to start
140-
let [l:next_line, l:next_col] = lsp#utils#position#_lsp_to_vim('%', a:diagnostics[0]['range']['start'])
140+
let [l:next_line, l:next_col] = lsp#utils#position#lsp_to_vim('%', a:diagnostics[0]['range']['start'])
141141
let l:next_col -= 1
142142
endif
143143

@@ -184,7 +184,7 @@ function! s:previous_diagnostic(diagnostics) abort
184184
let l:next_col = 0
185185
let l:index = len(a:diagnostics) - 1
186186
while l:index >= 0
187-
let [l:line, l:col] = lsp#utils#position#_lsp_to_vim('%', a:diagnostics[l:index]['range']['start'])
187+
let [l:line, l:col] = lsp#utils#position#lsp_to_vim('%', a:diagnostics[l:index]['range']['start'])
188188
if l:line < l:view['lnum']
189189
\ || (l:line == l:view['lnum'] && l:col < l:view['col'])
190190
let l:next_line = l:line
@@ -196,7 +196,7 @@ function! s:previous_diagnostic(diagnostics) abort
196196

197197
if l:next_line == 0
198198
" Wrap to end
199-
let [l:next_line, l:next_col] = lsp#utils#position#_lsp_to_vim('%', a:diagnostics[-1]['range']['start'])
199+
let [l:next_line, l:next_col] = lsp#utils#position#lsp_to_vim('%', a:diagnostics[-1]['range']['start'])
200200
let l:next_col -= 1
201201
endif
202202

autoload/lsp/ui/vim/diagnostics/textprop.vim

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -125,8 +125,8 @@ function! s:place_highlights(server_name, path, diagnostics) abort
125125
let l:bufnr = bufnr(a:path)
126126
if !empty(a:diagnostics) && l:bufnr >= 0
127127
for l:item in a:diagnostics
128-
let [l:start_line, l:start_col] = lsp#utils#position#_lsp_to_vim(l:bufnr, l:item['range']['start'])
129-
let [l:end_line, l:end_col] = lsp#utils#position#_lsp_to_vim(l:bufnr, l:item['range']['end'])
128+
let [l:start_line, l:start_col] = lsp#utils#position#lsp_to_vim(l:bufnr, l:item['range']['start'])
129+
let [l:end_line, l:end_col] = lsp#utils#position#lsp_to_vim(l:bufnr, l:item['range']['end'])
130130

131131
let l:prop_type = s:get_prop_type(a:server_name, get(l:item, 'severity', 1))
132132
try
Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
let s:commands = {}
2+
3+
"
4+
" @param {name} = string
5+
" @param {callback} = funcref
6+
"
7+
function! lsp#ui#vim#execute_command#_register(command_name, callback) abort
8+
if has_key(s:commands, a:command_name)
9+
throw printf('lsp#ui#vim#execute_command#_register_command: %s already registered.', a:command_name)
10+
endif
11+
12+
let s:commands[a:command_name] = a:callback
13+
endfunction
14+
15+
"
16+
" TODO: This method does not handle any return value.
17+
"
18+
function! lsp#ui#vim#execute_command#_execute(params) abort
19+
let l:command_name = a:params['command_name']
20+
let l:command_args = get(a:params, 'command_args', v:null)
21+
let l:server_name = get(a:params, 'server_name', '')
22+
let l:bufnr = get(a:params, 'bufnr', -1)
23+
let l:sync = get(a:params, 'sync', v:false)
24+
25+
" create command.
26+
let l:command = { 'command': l:command_name }
27+
if l:command_args isnot v:null
28+
let l:command['arguments'] = l:command_args
29+
endif
30+
31+
" execute command on local.
32+
if has_key(s:commands, l:command_name)
33+
try
34+
call s:commands[l:command_name]({
35+
\ 'bufnr': l:bufnr,
36+
\ 'server_name': l:server_name,
37+
\ 'command': l:command,
38+
\ })
39+
catch /.*/
40+
call lsp#utils#error(printf('Execute command failed: %s', string(a:params)))
41+
endtry
42+
return
43+
endif
44+
45+
" execute command on server.
46+
if !empty(l:server_name)
47+
call lsp#send_request(l:server_name, {
48+
\ 'method': 'workspace/executeCommand',
49+
\ 'params': l:command,
50+
\ 'sync': l:sync,
51+
\ 'on_notification': function('s:handle_execute_command', [l:server_name, l:command]),
52+
\ })
53+
endif
54+
endfunction
55+
56+
"
57+
" handle workspace/executeCommand response
58+
"
59+
function! s:handle_execute_command(server_name, command, data) abort
60+
if lsp#client#is_error(a:data['response'])
61+
call lsp#utils#error('Execute command failed on ' . a:server_name . ': ' . string(a:command) . ' -> ' . string(a:data))
62+
endif
63+
endfunction
64+

autoload/lsp/ui/vim/highlights.vim

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -95,8 +95,8 @@ function! s:place_highlights(server_name, path, diagnostics) abort
9595

9696
if !empty(a:diagnostics) && l:bufnr >= 0
9797
for l:item in a:diagnostics
98-
let [l:line, l:start_col] = lsp#utils#position#_lsp_to_vim(l:bufnr, l:item['range']['start'])
99-
let [l:_, l:end_col] = lsp#utils#position#_lsp_to_vim(l:bufnr, l:item['range']['end'])
98+
let [l:line, l:start_col] = lsp#utils#position#lsp_to_vim(l:bufnr, l:item['range']['start'])
99+
let [l:_, l:end_col] = lsp#utils#position#lsp_to_vim(l:bufnr, l:item['range']['end'])
100100

101101
let l:name = get(s:severity_sign_names_mapping, l:item['severity'], 'LspError')
102102
let l:hl_name = l:name . 'Highlight'

autoload/lsp/ui/vim/references.vim

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,8 +14,8 @@ endif
1414
function! s:range_to_position(bufnr, range) abort
1515
let l:position = []
1616

17-
let [l:start_line, l:start_col] = lsp#utils#position#_lsp_to_vim(a:bufnr, a:range['start'])
18-
let [l:end_line, l:end_col] = lsp#utils#position#_lsp_to_vim(a:bufnr, a:range['end'])
17+
let [l:start_line, l:start_col] = lsp#utils#position#lsp_to_vim(a:bufnr, a:range['start'])
18+
let [l:end_line, l:end_col] = lsp#utils#position#lsp_to_vim(a:bufnr, a:range['end'])
1919
if l:end_line == l:start_line
2020
let l:position = [[
2121
\ l:start_line,

autoload/lsp/ui/vim/utils.vim

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,7 @@ let s:diagnostic_severity = {
3838

3939
function! s:symbols_to_loc_list_children(server, path, list, symbols, depth) abort
4040
for l:symbol in a:symbols
41-
let [l:line, l:col] = lsp#utils#position#_lsp_to_vim(a:path, l:symbol['range']['start'])
41+
let [l:line, l:col] = lsp#utils#position#lsp_to_vim(a:path, l:symbol['range']['start'])
4242

4343
call add(a:list, {
4444
\ 'filename': a:path,
@@ -67,7 +67,7 @@ function! lsp#ui#vim#utils#symbols_to_loc_list(server, result) abort
6767
let l:location = l:symbol['location']
6868
if lsp#utils#is_file_uri(l:location['uri'])
6969
let l:path = lsp#utils#uri_to_path(l:location['uri'])
70-
let [l:line, l:col] = lsp#utils#position#_lsp_to_vim(l:path, l:location['range']['start'])
70+
let [l:line, l:col] = lsp#utils#position#lsp_to_vim(l:path, l:location['range']['start'])
7171
call add(l:list, {
7272
\ 'filename': l:path,
7373
\ 'lnum': l:line,
@@ -79,7 +79,7 @@ function! lsp#ui#vim#utils#symbols_to_loc_list(server, result) abort
7979
let l:location = a:result['request']['params']['textDocument']['uri']
8080
if lsp#utils#is_file_uri(l:location)
8181
let l:path = lsp#utils#uri_to_path(l:location)
82-
let [l:line, l:col] = lsp#utils#position#_lsp_to_vim(l:path, l:symbol['range']['start'])
82+
let [l:line, l:col] = lsp#utils#position#lsp_to_vim(l:path, l:symbol['range']['start'])
8383
call add(l:list, {
8484
\ 'filename': l:path,
8585
\ 'lnum': l:line,
@@ -121,7 +121,7 @@ function! lsp#ui#vim#utils#diagnostics_to_loc_list(result) abort
121121
let l:text .= l:item['code'] . ':'
122122
endif
123123
let l:text .= l:item['message']
124-
let [l:line, l:col] = lsp#utils#position#_lsp_to_vim(l:path, l:item['range']['start'])
124+
let [l:line, l:col] = lsp#utils#position#lsp_to_vim(l:path, l:item['range']['start'])
125125
call add(l:list, {
126126
\ 'filename': l:path,
127127
\ 'lnum': l:line,

0 commit comments

Comments
 (0)