Feature: Add support for named-pipe sockets for LSPs (#3509)

* Add support for using named pipes for lsp 'socket' servers; documentation updated accordingly
* Add tests for connecting to named pipe sockets
This commit is contained in:
Kevin Svetlitski
2021-01-26 14:43:17 -06:00
committed by GitHub
parent 3a1728297a
commit cab4280d02
4 changed files with 103 additions and 12 deletions

View File

@@ -0,0 +1,42 @@
"""
This Python script creates a named pipe server that does nothing but send its input
back to the client that connects to it. Only one argument must be given, the path
of a named pipe to bind to.
"""
import os
import socket
import sys
def main():
if len(sys.argv) < 2:
sys.exit('You must specify a filepath')
sock = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM)
sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
if os.path.exists(sys.argv[1]):
os.remove(sys.argv[1])
sock.bind(sys.argv[1])
sock.listen(0)
pid = os.fork()
if pid:
print(pid)
sys.exit()
while True:
connection = sock.accept()[0]
connection.settimeout(5)
while True:
try:
connection.send(connection.recv(1024))
except socket.timeout:
break
connection.close()
if __name__ == "__main__":
main()

View File

@@ -28,11 +28,17 @@ Before:
endfunction
let g:port = 10347
let g:pid = str2nr(system(
let g:pid_tcp = str2nr(system(
\ 'python'
\ . ' ' . ale#Escape(g:dir . '/dumb_tcp_server.py')
\ . ' ' . g:port
\))
let g:pipe_path = 'tmp_named_pipe'
let g:pid_pipe = str2nr(system(
\ 'python'
\ . ' ' . ale#Escape(g:dir . '/dumb_named_pipe_server.py')
\ . ' ' . g:pipe_path
\))
endif
After:
@@ -46,17 +52,23 @@ After:
delfunction WaitForData
delfunction TestCallback
if has_key(g:, 'pid')
call system('kill ' . g:pid)
if has_key(g:, 'pid_tcp')
call system('kill ' . g:pid_tcp)
endif
unlet! g:pid
if has_key(g:, 'pid_pipe')
call system('kill ' . g:pid_pipe)
endif
unlet! g:pid_tcp
unlet! g:port
unlet! g:pid_pipe
unlet! g:pipe_path
endif
unlet! g:can_run_socket_tests
Execute(Sending and receiving connections to sockets should work):
Execute(Sending and receiving connections to tcp sockets should work):
if g:can_run_socket_tests
let g:channel_id = ale#socket#Open(
\ '127.0.0.1:' . g:port,
@@ -90,3 +102,38 @@ Execute(Sending and receiving connections to sockets should work):
\ {'callback': function('function')}
\)
endif
Execute(Sending and receiving connections to named pipe sockets should work):
if g:can_run_socket_tests && has('nvim')
let g:channel_id = ale#socket#Open(
\ g:pipe_path,
\ {'callback': function('TestCallback')}
\)
Assert g:channel_id >= 0, 'The socket was not opened!'
call ale#socket#Send(g:channel_id, 'hello')
call ale#socket#Send(g:channel_id, ' world')
AssertEqual 1, ale#socket#IsOpen(g:channel_id)
" Wait up to 1 second for the expected data to arrive.
call WaitForData('hello world', 1000)
AssertEqual g:channel_id, g:channel_id_received
AssertEqual 'hello world', g:data_received
AssertEqual g:pipe_path, ale#socket#GetAddress(g:channel_id)
call ale#socket#Close(g:channel_id)
AssertEqual 0, ale#socket#IsOpen(g:channel_id)
AssertEqual '', ale#socket#GetAddress(g:channel_id)
endif
" NeoVim versions which can't connect to sockets should just fail.
if has('nvim') && !exists('*chanclose')
AssertEqual -1, ale#socket#Open(
\ 'tmp_named_pipe',
\ {'callback': function('function')}
\)
endif