lsp_router 0.1.1 → 0.1.3

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: c3ba53e8db9e41cea66c0d4f935517fe4f3e4e8e24a6173794e53ea409556847
4
- data.tar.gz: 984ea810f99d29a70efbb798b76c5d9f161b5bb5433ab0b96c52ed015529699c
3
+ metadata.gz: 5b81686d10b1edcb9c6b6ab51eedd3f8bd4ca71c3bd3d44b820fd416f2a48f0e
4
+ data.tar.gz: 85e81047822d36218ac021ccccb240af5fdc896dcb0218a8c835f613343dea1a
5
5
  SHA512:
6
- metadata.gz: 40903c06994c73209c64535f12b417c913e59db4a7b856eae9504aac1e86102a273656e6f3a4148b3fa54e8c862855cd846e5e29d00f457b6a8e691b727ee919
7
- data.tar.gz: bde44dd17b4288879bf96dee727320241ebf143d13e4e5ee8fadbf562223db6a0c5214c584847369a6ff97f20b2048192dc2faaea076fbfc7f213b68b479818c
6
+ metadata.gz: 289f4683fc2aead84ac11c7655b1faeb142f3692d26af1683d62181a3fb6ea7ac345f016e1e27946c5229dd755c9e49afed0ef4d00b5b28a481e42b6763dc933
7
+ data.tar.gz: c1e65b91db8a71ba1ebfacd134dc2b3a133d569a7ae67346fcc7a004502a4eff1fba2924d755f9f14420f3ff6369e89bb36f60a60a01f014f5249aba160f7e02
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-lsp'
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-lsp` と `solargraph stdio` を起動して、クライアントからの処理を振り分ける。
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,6 +16,7 @@ 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]
@@ -31,6 +32,7 @@ class LspRouter
31
32
 
32
33
  # @param data [Hash]
33
34
  def write(data)
35
+ return if @terminated
34
36
  log("#{name}<", data)
35
37
  json = data.to_json
36
38
  @stdin.puts "Content-Length: #{json.bytesize}\r\n\r\n"
@@ -40,8 +42,12 @@ class LspRouter
40
42
 
41
43
  # @return [Hash]
42
44
  def read
45
+ return nil if @terminated
43
46
  header = @stdout.gets("\r\n\r\n")
44
- return unless header
47
+ unless header
48
+ @terminated = true
49
+ return nil
50
+ end
45
51
  fields = header.lines.map do |line|
46
52
  n, v = line.chomp.split(/: */, 2)
47
53
  [n.downcase, v] if n
@@ -1,3 +1,3 @@
1
1
  class LspRouter
2
- VERSION = '0.1.1'
2
+ VERSION = '0.1.3'
3
3
  end
data/lib/lsp_router.rb CHANGED
@@ -42,13 +42,21 @@ class LspRouter
42
42
  end
43
43
 
44
44
  def loop
45
- req = @client.read
46
- servers = @config.servers.map{LspRouter::ServerSide.new(_1, logger: @logger)}
47
- primary = servers.first
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
- capa_server = {}
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,58 @@ 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
- thr = Thread.new do
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['id']
70
- # request
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
- server = capa_server[method] || primary
73
- server.write(data)
74
- else
75
- # notification
76
- servers.each do |server|
77
- server.write(data)
86
+ if data['method'] # request
87
+ server = @capa_server[method] || @primary
88
+ data['id'] = [server.name, data['id']].to_json
89
+ else # response
90
+ server_name, id = JSON.parse(data['id'])
91
+ data['id'] = id
92
+ server = @server_map[server_name]
78
93
  end
94
+ server.write(data)
95
+ else # notification
96
+ @servers.each{_1.write(data)}
79
97
  end
80
98
  end
99
+ @logger.info "client: end"
81
100
  end
101
+ end
82
102
 
83
- servers.each do |server|
103
+ def server_loop
104
+ @servers.map do |server|
84
105
  Thread.new do
85
106
  Thread.abort_on_exception = true
86
107
  while true
87
108
  data = server.read
88
109
  break unless data
110
+ if data['id'] && data['method'] # request
111
+ data['id'] = [server.name, data['id']].to_json
112
+ elsif data['id'] # response
113
+ data['id'] = JSON.parse(data['id']).last rescue data['id']
114
+ end
89
115
  @client.write(data)
90
116
  end
117
+ @logger.info "server: [#{server.name}] end"
91
118
  end
92
119
  end
93
- thr.join
94
120
  end
95
121
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: lsp_router
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.1
4
+ version: 0.1.3
5
5
  platform: ruby
6
6
  authors:
7
7
  - TOMITA Masahiro
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2023-12-20 00:00:00.000000000 Z
11
+ date: 2023-12-23 00:00:00.000000000 Z
12
12
  dependencies: []
13
13
  description: routing multiple LSP server by capability
14
14
  email: