Add tcp feature (#985)

* Add tcp feature

* Update doc

* Update async.vim embed

* Update doc
This commit is contained in:
mattn
2021-01-01 01:28:06 +09:00
committed by GitHub
parent 5743ae2110
commit ee854b4c55
4 changed files with 98 additions and 36 deletions

View File

@@ -412,6 +412,16 @@ function! s:ensure_start(buf, server_name, cb) abort
return
endif
if has_key(l:server_info, 'tcp')
let l:tcp = l:server_info['tcp'](l:server_info)
let l:lsp_id = lsp#client#start({
\ 'tcp': l:tcp,
\ 'on_stderr': function('s:on_stderr', [a:server_name]),
\ 'on_exit': function('s:on_exit', [a:server_name]),
\ 'on_notification': function('s:on_notification', [a:server_name]),
\ 'on_request': function('s:on_request', [a:server_name]),
\ })
elseif has_key(l:server_info, 'cmd')
let l:cmd_type = type(l:server_info['cmd'])
if l:cmd_type == v:t_list
let l:cmd = l:server_info['cmd']
@@ -435,6 +445,7 @@ function! s:ensure_start(buf, server_name, cb) abort
\ 'on_notification': function('s:on_notification', [a:server_name]),
\ 'on_request': function('s:on_request', [a:server_name]),
\ })
endif
if l:lsp_id > 0
let l:server['lsp_id'] = l:lsp_id

View File

@@ -183,15 +183,21 @@ function! s:on_exit(id, status, event) abort
endfunction
function! s:lsp_start(opts) abort
if !has_key(a:opts, 'cmd')
return -1
endif
if has_key(a:opts, 'cmd')
let l:client_id = lsp#utils#job#start(a:opts.cmd, {
\ 'on_stdout': function('s:on_stdout'),
\ 'on_stderr': function('s:on_stderr'),
\ 'on_exit': function('s:on_exit'),
\ })
elseif has_key(a:opts, 'tcp')
let l:client_id = lsp#utils#job#connect(a:opts.tcp, {
\ 'on_stdout': function('s:on_stdout'),
\ 'on_stderr': function('s:on_stderr'),
\ 'on_exit': function('s:on_exit'),
\ })
else
return -1
endif
let l:ctx = s:create_context(l:client_id, a:opts)
let l:ctx['id'] = l:client_id

View File

@@ -1,4 +1,4 @@
" https://github.com/prabirshrestha/async.vim#d15123af3483350e235397116b554cb37e705130 (dirty)
" https://github.com/prabirshrestha/async.vim#236debf1a68d69a74f1f6647c273b0477e1ec1bf (dirty)
" :AsyncEmbed path=./autoload/lsp/utils/job.vim namespace=lsp#utils#job
" Author: Prabir Shrestha <mail at prabir dot me>
@@ -195,7 +195,11 @@ function! s:job_stop(jobid) abort
" silently for 'E900: Invalid job id' exception
endtry
elseif l:jobinfo.type == s:job_type_vimjob
if type(s:jobs[a:jobid].job) == v:t_job
call job_stop(s:jobs[a:jobid].job)
elseif type(s:jobs[a:jobid].job) == v:t_channel
call ch_close(s:jobs[a:jobid].job)
endif
endif
endif
endfunction
@@ -306,6 +310,21 @@ function! s:job_pid(jobid) abort
return 0
endfunction
function! s:callback_cb(jobid, opts, ch, data) abort
if has_key(a:opts, 'on_stdout')
call a:opts.on_stdout(a:jobid, split(a:data, "\n", 1), 'stdout')
endif
endfunction
function! s:close_cb(jobid, opts, ch) abort
if has_key(a:opts, 'on_exit')
call a:opts.on_exit(a:jobid, 'closed', 'exit')
endif
if has_key(s:jobs, a:jobid)
call remove(s:jobs, a:jobid)
endif
endfunction
" public apis {{{
function! lsp#utils#job#start(cmd, opts) abort
return s:job_start(a:cmd, a:opts)
@@ -328,6 +347,33 @@ endfunction
function! lsp#utils#job#pid(jobid) abort
return s:job_pid(a:jobid)
endfunction
function! lsp#utils#job#connect(addr, opts) abort
let s:jobidseq = s:jobidseq + 1
let l:jobid = s:jobidseq
let l:retry = 0
while l:retry < 5
let l:ch = ch_open(a:addr, {'waittime': 1000})
call ch_setoptions(l:ch, {
\ 'callback': function('s:callback_cb', [l:jobid, a:opts]),
\ 'close_cb': function('s:close_cb', [l:jobid, a:opts]),
\ 'mode': 'raw',
\})
if ch_status(l:ch) ==# 'open'
break
endif
sleep 100m
let l:retry += 1
endwhile
let s:jobs[l:jobid] = {
\ 'type': s:job_type_vimjob,
\ 'opts': a:opts,
\ 'job': l:ch,
\ 'channel': l:ch,
\ 'buffer': ''
\}
return l:jobid
endfunction
" }}}
let &cpo = s:save_cpo

View File

@@ -220,15 +220,14 @@ on pyls (https://github.com/palantir/python-language-server)
augroup END
<
TCP SERVERS *vim-lsp-tcp*
You can use netcat to connect to LSP servers that don't support stdio, but do
support TCP. Set your cmd to use your netcat executable (`nc` on unix-likes),
localhost, and your server's port. The Godot game engine uses 6008 as its LSP
port and godot ftplugins define gdscript or gdscript3 filetype: >
You can use tcp to connect to LSP servers that don't support stdio. Set host
and port to tcp. The Godot game engine uses 6008 as its LSP port and godot
ftplugins define gdscript or gdscript3 filetype: >
au User lsp_setup
\ call lsp#register_server({
\ 'name': 'godot',
\ 'cmd': ["nc", "localhost", "6008"],
\ 'tcp': "localhost:6008",
\ 'allowlist': ['gdscript3', 'gdscript']
\ })
>