lsp_router 0.1.1 → 0.1.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/.rubocop.yml +0 -2
- data/README.md +6 -2
- data/lib/lsp_router/server_side.rb +14 -5
- data/lib/lsp_router/version.rb +1 -1
- data/lib/lsp_router.rb +40 -17
- metadata +3 -6
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: a4434480350b472e4784e0bc3dcd003f5863eeb5ee25accbcc5491d07ecdac39
|
4
|
+
data.tar.gz: ba46303f99aa22018ade578cf1534ccfb7149b356b43ca262ae65c5cb729eb64
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 4e5716f9fab94ec450991faf87af92d81544341df78a795c9506a94b7feee39add469211144762b7514f5d46b76128e4c68b21d8ef12f300dbae9c28f3bdd7e4
|
7
|
+
data.tar.gz: 7795648666367d4bada69bfa336c7cdbcf41f3f4039f17e819c0c79a61acbfbd2a3381c44f1b2e222f889cb9df81b32e61bf83b0e34fbfb51862b8009798c069
|
data/.rubocop.yml
CHANGED
data/README.md
CHANGED
@@ -17,7 +17,7 @@ logfile '/tmp/lsp_router'
|
|
17
17
|
loglevel :info
|
18
18
|
|
19
19
|
server :rubocop do
|
20
|
-
command 'rubocop
|
20
|
+
command 'rubocop --lsp'
|
21
21
|
mode :stdio
|
22
22
|
end
|
23
23
|
|
@@ -27,7 +27,7 @@ server :solargraph do
|
|
27
27
|
end
|
28
28
|
```
|
29
29
|
|
30
|
-
この例では、`rubocop
|
30
|
+
この例では、`rubocop --lsp` と `solargraph stdio` を起動して、クライアントからの処理を振り分ける。
|
31
31
|
最初に各サーバーの capabilities を確認して、各サーバーにどの機能があるかを確認し、クライアントからの REQUEST は対応しているサーバーに渡す。複数のサーバーが同じ機能を持っていれば上に書いたサーバーが優先される。NOTIFICATION は全サーバーに渡す。
|
32
32
|
|
33
33
|
## Example
|
@@ -37,3 +37,7 @@ Emacs の Eglot の場合はこんな感じに設定するといいっぽい。
|
|
37
37
|
```
|
38
38
|
(add-to-list 'eglot-server-programs '((ruby-mode ruby-ts-mode) . ("lsp_router" "--error=lsp_router.err" "lsp_router.conf")))
|
39
39
|
```
|
40
|
+
|
41
|
+
## License
|
42
|
+
|
43
|
+
GPLv3
|
@@ -16,21 +16,26 @@ class LspRouter
|
|
16
16
|
@command = server.attr[:command]
|
17
17
|
@stdin, @stdout, @stderr = Open3.popen3(@command)
|
18
18
|
@capabilities = {}
|
19
|
+
@terminated = false
|
19
20
|
end
|
20
21
|
|
21
22
|
# @param req [Hash]
|
22
23
|
def init(req)
|
23
24
|
write(req)
|
24
|
-
data = read
|
25
|
-
|
26
|
-
|
27
|
-
|
25
|
+
while (data = read)
|
26
|
+
capa = data.dig('result', 'capabilities')
|
27
|
+
next unless capa
|
28
|
+
capa.keys.grep(/Provider/).each do |key|
|
29
|
+
@capabilities[key.sub(/Provider\z/, '')] = true
|
30
|
+
end
|
31
|
+
break
|
28
32
|
end
|
29
33
|
data
|
30
34
|
end
|
31
35
|
|
32
36
|
# @param data [Hash]
|
33
37
|
def write(data)
|
38
|
+
return if @terminated
|
34
39
|
log("#{name}<", data)
|
35
40
|
json = data.to_json
|
36
41
|
@stdin.puts "Content-Length: #{json.bytesize}\r\n\r\n"
|
@@ -40,8 +45,12 @@ class LspRouter
|
|
40
45
|
|
41
46
|
# @return [Hash]
|
42
47
|
def read
|
48
|
+
return nil if @terminated
|
43
49
|
header = @stdout.gets("\r\n\r\n")
|
44
|
-
|
50
|
+
unless header
|
51
|
+
@terminated = true
|
52
|
+
return nil
|
53
|
+
end
|
45
54
|
fields = header.lines.map do |line|
|
46
55
|
n, v = line.chomp.split(/: */, 2)
|
47
56
|
[n.downcase, v] if n
|
data/lib/lsp_router/version.rb
CHANGED
data/lib/lsp_router.rb
CHANGED
@@ -42,13 +42,21 @@ class LspRouter
|
|
42
42
|
end
|
43
43
|
|
44
44
|
def loop
|
45
|
-
|
46
|
-
|
47
|
-
|
45
|
+
@servers = @config.servers.map{LspRouter::ServerSide.new(_1, logger: @logger)}
|
46
|
+
@primary = @servers.first
|
47
|
+
@server_map = @servers.map.to_h{[_1.name.to_s, _1]}
|
48
|
+
@capa_server = {}
|
49
|
+
|
50
|
+
initial_packet
|
51
|
+
threads = server_loop
|
52
|
+
threads.push client_loop
|
53
|
+
threads.each(&:join)
|
54
|
+
end
|
48
55
|
|
56
|
+
def initial_packet
|
57
|
+
req = @client.read
|
49
58
|
res = nil
|
50
|
-
|
51
|
-
servers.each do |server|
|
59
|
+
@servers.each do |server|
|
52
60
|
data = server.init(req)
|
53
61
|
if res
|
54
62
|
res['result']['capabilities'].update(data.dig('result', 'capabilities')){|_, v, _| v}
|
@@ -56,40 +64,55 @@ class LspRouter
|
|
56
64
|
res = data
|
57
65
|
end
|
58
66
|
server.capabilities.each_key do |key|
|
59
|
-
capa_server[key] ||= server
|
67
|
+
@capa_server[key] ||= server
|
60
68
|
end
|
61
69
|
end
|
62
70
|
@client.write(res)
|
71
|
+
end
|
63
72
|
|
64
|
-
|
73
|
+
def client_loop
|
74
|
+
Thread.new do
|
65
75
|
Thread.abort_on_exception = true
|
66
76
|
while true
|
67
77
|
data = @client.read
|
68
78
|
break unless data
|
69
|
-
if data['
|
70
|
-
|
79
|
+
if data['method'] == 'shutdown' || data['method'] == 'exit'
|
80
|
+
@servers.each{_1.write(data)}
|
81
|
+
break if data['method'] == 'exit'
|
82
|
+
next
|
83
|
+
end
|
84
|
+
if data['id'] # request or response
|
71
85
|
method = data['method']&.split('/')&.last
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
server
|
86
|
+
if data['method'] # request
|
87
|
+
server = @capa_server[method] || @primary
|
88
|
+
else # response
|
89
|
+
server_name, id = JSON.parse(data['id'])
|
90
|
+
data['id'] = id
|
91
|
+
server = @server_map[server_name]
|
78
92
|
end
|
93
|
+
server.write(data)
|
94
|
+
else # notification
|
95
|
+
@servers.each{_1.write(data)}
|
79
96
|
end
|
80
97
|
end
|
98
|
+
@logger.info "client: end"
|
81
99
|
end
|
100
|
+
end
|
82
101
|
|
83
|
-
|
102
|
+
def server_loop
|
103
|
+
@servers.map do |server|
|
84
104
|
Thread.new do
|
85
105
|
Thread.abort_on_exception = true
|
86
106
|
while true
|
87
107
|
data = server.read
|
88
108
|
break unless data
|
109
|
+
if data['id'] && data['method'] # request
|
110
|
+
data['id'] = [server.name, data['id']].to_json
|
111
|
+
end
|
89
112
|
@client.write(data)
|
90
113
|
end
|
114
|
+
@logger.info "server: [#{server.name}] end"
|
91
115
|
end
|
92
116
|
end
|
93
|
-
thr.join
|
94
117
|
end
|
95
118
|
end
|
metadata
CHANGED
@@ -1,14 +1,13 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: lsp_router
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.1.
|
4
|
+
version: 0.1.4
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- TOMITA Masahiro
|
8
|
-
autorequire:
|
9
8
|
bindir: exe
|
10
9
|
cert_chain: []
|
11
|
-
date:
|
10
|
+
date: 1980-01-02 00:00:00.000000000 Z
|
12
11
|
dependencies: []
|
13
12
|
description: routing multiple LSP server by capability
|
14
13
|
email:
|
@@ -38,7 +37,6 @@ metadata:
|
|
38
37
|
homepage_uri: https://gitlab.com/tmtms/lsp_router
|
39
38
|
source_code_uri: https://gitlab.com/tmtms/lsp_router
|
40
39
|
rubygems_mfa_required: 'true'
|
41
|
-
post_install_message:
|
42
40
|
rdoc_options: []
|
43
41
|
require_paths:
|
44
42
|
- lib
|
@@ -53,8 +51,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
53
51
|
- !ruby/object:Gem::Version
|
54
52
|
version: '0'
|
55
53
|
requirements: []
|
56
|
-
rubygems_version: 3.
|
57
|
-
signing_key:
|
54
|
+
rubygems_version: 3.7.0.dev
|
58
55
|
specification_version: 4
|
59
56
|
summary: LSP router
|
60
57
|
test_files: []
|