Skip to content

Commit ee854b4

Browse files
authored
Add tcp feature (#985)
* Add tcp feature * Update doc * Update async.vim embed * Update doc
1 parent 5743ae2 commit ee854b4

File tree

4 files changed

+96
-34
lines changed

4 files changed

+96
-34
lines changed

autoload/lsp.vim

Lines changed: 31 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -412,29 +412,40 @@ function! s:ensure_start(buf, server_name, cb) abort
412412
return
413413
endif
414414

415-
let l:cmd_type = type(l:server_info['cmd'])
416-
if l:cmd_type == v:t_list
417-
let l:cmd = l:server_info['cmd']
418-
else
419-
let l:cmd = l:server_info['cmd'](l:server_info)
420-
endif
415+
if has_key(l:server_info, 'tcp')
416+
let l:tcp = l:server_info['tcp'](l:server_info)
417+
let l:lsp_id = lsp#client#start({
418+
\ 'tcp': l:tcp,
419+
\ 'on_stderr': function('s:on_stderr', [a:server_name]),
420+
\ 'on_exit': function('s:on_exit', [a:server_name]),
421+
\ 'on_notification': function('s:on_notification', [a:server_name]),
422+
\ 'on_request': function('s:on_request', [a:server_name]),
423+
\ })
424+
elseif has_key(l:server_info, 'cmd')
425+
let l:cmd_type = type(l:server_info['cmd'])
426+
if l:cmd_type == v:t_list
427+
let l:cmd = l:server_info['cmd']
428+
else
429+
let l:cmd = l:server_info['cmd'](l:server_info)
430+
endif
421431

422-
if empty(l:cmd)
423-
let l:msg = s:new_rpc_error('ignore server start since cmd is empty', { 'server_name': a:server_name })
424-
call lsp#log(l:msg)
425-
call a:cb(l:msg)
426-
return
427-
endif
432+
if empty(l:cmd)
433+
let l:msg = s:new_rpc_error('ignore server start since cmd is empty', { 'server_name': a:server_name })
434+
call lsp#log(l:msg)
435+
call a:cb(l:msg)
436+
return
437+
endif
428438

429-
call lsp#log('Starting server', a:server_name, l:cmd)
439+
call lsp#log('Starting server', a:server_name, l:cmd)
430440

431-
let l:lsp_id = lsp#client#start({
432-
\ 'cmd': l:cmd,
433-
\ 'on_stderr': function('s:on_stderr', [a:server_name]),
434-
\ 'on_exit': function('s:on_exit', [a:server_name]),
435-
\ 'on_notification': function('s:on_notification', [a:server_name]),
436-
\ 'on_request': function('s:on_request', [a:server_name]),
437-
\ })
441+
let l:lsp_id = lsp#client#start({
442+
\ 'cmd': l:cmd,
443+
\ 'on_stderr': function('s:on_stderr', [a:server_name]),
444+
\ 'on_exit': function('s:on_exit', [a:server_name]),
445+
\ 'on_notification': function('s:on_notification', [a:server_name]),
446+
\ 'on_request': function('s:on_request', [a:server_name]),
447+
\ })
448+
endif
438449

439450
if l:lsp_id > 0
440451
let l:server['lsp_id'] = l:lsp_id

autoload/lsp/client.vim

Lines changed: 13 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -183,16 +183,22 @@ function! s:on_exit(id, status, event) abort
183183
endfunction
184184

185185
function! s:lsp_start(opts) abort
186-
if !has_key(a:opts, 'cmd')
186+
if has_key(a:opts, 'cmd')
187+
let l:client_id = lsp#utils#job#start(a:opts.cmd, {
188+
\ 'on_stdout': function('s:on_stdout'),
189+
\ 'on_stderr': function('s:on_stderr'),
190+
\ 'on_exit': function('s:on_exit'),
191+
\ })
192+
elseif has_key(a:opts, 'tcp')
193+
let l:client_id = lsp#utils#job#connect(a:opts.tcp, {
194+
\ 'on_stdout': function('s:on_stdout'),
195+
\ 'on_stderr': function('s:on_stderr'),
196+
\ 'on_exit': function('s:on_exit'),
197+
\ })
198+
else
187199
return -1
188200
endif
189201

190-
let l:client_id = lsp#utils#job#start(a:opts.cmd, {
191-
\ 'on_stdout': function('s:on_stdout'),
192-
\ 'on_stderr': function('s:on_stderr'),
193-
\ 'on_exit': function('s:on_exit'),
194-
\ })
195-
196202
let l:ctx = s:create_context(l:client_id, a:opts)
197203
let l:ctx['id'] = l:client_id
198204

autoload/lsp/utils/job.vim

Lines changed: 48 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
" https://github.com/prabirshrestha/async.vim#d15123af3483350e235397116b554cb37e705130 (dirty)
1+
" https://github.com/prabirshrestha/async.vim#236debf1a68d69a74f1f6647c273b0477e1ec1bf (dirty)
22
" :AsyncEmbed path=./autoload/lsp/utils/job.vim namespace=lsp#utils#job
33

44
" Author: Prabir Shrestha <mail at prabir dot me>
@@ -195,7 +195,11 @@ function! s:job_stop(jobid) abort
195195
" silently for 'E900: Invalid job id' exception
196196
endtry
197197
elseif l:jobinfo.type == s:job_type_vimjob
198-
call job_stop(s:jobs[a:jobid].job)
198+
if type(s:jobs[a:jobid].job) == v:t_job
199+
call job_stop(s:jobs[a:jobid].job)
200+
elseif type(s:jobs[a:jobid].job) == v:t_channel
201+
call ch_close(s:jobs[a:jobid].job)
202+
endif
199203
endif
200204
endif
201205
endfunction
@@ -306,6 +310,21 @@ function! s:job_pid(jobid) abort
306310
return 0
307311
endfunction
308312

313+
function! s:callback_cb(jobid, opts, ch, data) abort
314+
if has_key(a:opts, 'on_stdout')
315+
call a:opts.on_stdout(a:jobid, split(a:data, "\n", 1), 'stdout')
316+
endif
317+
endfunction
318+
319+
function! s:close_cb(jobid, opts, ch) abort
320+
if has_key(a:opts, 'on_exit')
321+
call a:opts.on_exit(a:jobid, 'closed', 'exit')
322+
endif
323+
if has_key(s:jobs, a:jobid)
324+
call remove(s:jobs, a:jobid)
325+
endif
326+
endfunction
327+
309328
" public apis {{{
310329
function! lsp#utils#job#start(cmd, opts) abort
311330
return s:job_start(a:cmd, a:opts)
@@ -328,6 +347,33 @@ endfunction
328347
function! lsp#utils#job#pid(jobid) abort
329348
return s:job_pid(a:jobid)
330349
endfunction
350+
351+
function! lsp#utils#job#connect(addr, opts) abort
352+
let s:jobidseq = s:jobidseq + 1
353+
let l:jobid = s:jobidseq
354+
let l:retry = 0
355+
while l:retry < 5
356+
let l:ch = ch_open(a:addr, {'waittime': 1000})
357+
call ch_setoptions(l:ch, {
358+
\ 'callback': function('s:callback_cb', [l:jobid, a:opts]),
359+
\ 'close_cb': function('s:close_cb', [l:jobid, a:opts]),
360+
\ 'mode': 'raw',
361+
\})
362+
if ch_status(l:ch) ==# 'open'
363+
break
364+
endif
365+
sleep 100m
366+
let l:retry += 1
367+
endwhile
368+
let s:jobs[l:jobid] = {
369+
\ 'type': s:job_type_vimjob,
370+
\ 'opts': a:opts,
371+
\ 'job': l:ch,
372+
\ 'channel': l:ch,
373+
\ 'buffer': ''
374+
\}
375+
return l:jobid
376+
endfunction
331377
" }}}
332378

333379
let &cpo = s:save_cpo

doc/vim-lsp.txt

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -220,15 +220,14 @@ on pyls (https://github.com/palantir/python-language-server)
220220
augroup END
221221
<
222222
TCP SERVERS *vim-lsp-tcp*
223-
You can use netcat to connect to LSP servers that don't support stdio, but do
224-
support TCP. Set your cmd to use your netcat executable (`nc` on unix-likes),
225-
localhost, and your server's port. The Godot game engine uses 6008 as its LSP
226-
port and godot ftplugins define gdscript or gdscript3 filetype: >
223+
You can use tcp to connect to LSP servers that don't support stdio. Set host
224+
and port to tcp. The Godot game engine uses 6008 as its LSP port and godot
225+
ftplugins define gdscript or gdscript3 filetype: >
227226
228227
au User lsp_setup
229228
\ call lsp#register_server({
230229
\ 'name': 'godot',
231-
\ 'cmd': ["nc", "localhost", "6008"],
230+
\ 'tcp': "localhost:6008",
232231
\ 'allowlist': ['gdscript3', 'gdscript']
233232
\ })
234233
>

0 commit comments

Comments
 (0)