nvim 1.0.0
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 +7 -0
- data/INFO.yaml +18 -0
- data/LICENSE +52 -0
- data/README.md +264 -0
- data/Rakefile +68 -0
- data/bin/neovim-ruby-host +51 -0
- data/lib/neovim/client.rb +108 -0
- data/lib/neovim/connection.rb +129 -0
- data/lib/neovim/foreign/mplight/bufferio.rb +51 -0
- data/lib/neovim/foreign/mplight.rb +327 -0
- data/lib/neovim/foreign/supplement/socket.rb +20 -0
- data/lib/neovim/foreign/supplement.rb +34 -0
- data/lib/neovim/handler.rb +139 -0
- data/lib/neovim/host.rb +87 -0
- data/lib/neovim/info.rb +10 -0
- data/lib/neovim/logging.rb +249 -0
- data/lib/neovim/messager.rb +185 -0
- data/lib/neovim/meta.rb +68 -0
- data/lib/neovim/remote.rb +56 -0
- data/lib/neovim/remote_object.rb +331 -0
- data/lib/neovim/ruby_provider.rb +372 -0
- data/lib/neovim/session.rb +60 -0
- data/lib/neovim/vimscript_provider.rb +49 -0
- data/lib/neovim.rb +22 -0
- metadata +66 -0
@@ -0,0 +1,51 @@
|
|
1
|
+
#
|
2
|
+
# neovim/foreign/mplight/bufferio.rb -- Buffer behaving like an IO
|
3
|
+
#
|
4
|
+
|
5
|
+
# The purpose of this is simply to reduce dependencies.
|
6
|
+
|
7
|
+
begin
|
8
|
+
require "mplight/bufferio"
|
9
|
+
rescue LoadError
|
10
|
+
|
11
|
+
# ----------------------------------------------------------------
|
12
|
+
#
|
13
|
+
# mplight/bufferio.rb -- Buffer behaving like an IO
|
14
|
+
#
|
15
|
+
|
16
|
+
|
17
|
+
module MPLight
|
18
|
+
|
19
|
+
class BufferIO
|
20
|
+
|
21
|
+
attr_reader :data
|
22
|
+
|
23
|
+
def initialize str = nil
|
24
|
+
@data = str||""
|
25
|
+
end
|
26
|
+
|
27
|
+
def binmode
|
28
|
+
@data.force_encoding Encoding::ASCII_8BIT
|
29
|
+
end
|
30
|
+
def sync= _ ; end
|
31
|
+
def sync ; true ; end
|
32
|
+
|
33
|
+
def write d
|
34
|
+
@data << d
|
35
|
+
end
|
36
|
+
|
37
|
+
def read n
|
38
|
+
@data.slice! 0, n
|
39
|
+
end
|
40
|
+
|
41
|
+
def flush
|
42
|
+
end
|
43
|
+
|
44
|
+
end
|
45
|
+
|
46
|
+
end
|
47
|
+
|
48
|
+
# ----------------------------------------------------------------
|
49
|
+
|
50
|
+
end
|
51
|
+
|
@@ -0,0 +1,327 @@
|
|
1
|
+
#
|
2
|
+
# neovim/foreign/mplight.rb -- Lightweight MessagePack implementation
|
3
|
+
#
|
4
|
+
|
5
|
+
# The purpose of this is simply to reduce dependencies.
|
6
|
+
|
7
|
+
begin
|
8
|
+
require "mplight"
|
9
|
+
rescue LoadError
|
10
|
+
|
11
|
+
# ----------------------------------------------------------------
|
12
|
+
#
|
13
|
+
# mplight.rb -- Lightweight MessagePack implementation
|
14
|
+
#
|
15
|
+
|
16
|
+
|
17
|
+
module MPLight
|
18
|
+
|
19
|
+
VERSION = "1.0".freeze
|
20
|
+
|
21
|
+
class Error ; end
|
22
|
+
|
23
|
+
|
24
|
+
class Types
|
25
|
+
|
26
|
+
def initialize *args, **kwargs
|
27
|
+
@cls = {}
|
28
|
+
@ids = {}
|
29
|
+
register -1, Time
|
30
|
+
end
|
31
|
+
|
32
|
+
def register id, klass
|
33
|
+
@cls[ id], @ids[ klass] = klass, id
|
34
|
+
end
|
35
|
+
|
36
|
+
def dump obj
|
37
|
+
t = @ids[ obj.class]
|
38
|
+
unless t then
|
39
|
+
return if @default_to_string
|
40
|
+
raise Error, "Unregistered class: #{obj.class}"
|
41
|
+
end
|
42
|
+
[ t, obj.to_mpdata]
|
43
|
+
end
|
44
|
+
|
45
|
+
def default_to_string! ; @default_to_string = true ; end
|
46
|
+
|
47
|
+
def create id, data
|
48
|
+
c = @cls[ id]
|
49
|
+
c or raise Error, "Unregistered type id: #{obj.class}"
|
50
|
+
c.from_mpdata data, *additional_data
|
51
|
+
end
|
52
|
+
|
53
|
+
def additional_data
|
54
|
+
[]
|
55
|
+
end
|
56
|
+
|
57
|
+
end
|
58
|
+
|
59
|
+
|
60
|
+
module Packer
|
61
|
+
|
62
|
+
attr_reader :output
|
63
|
+
|
64
|
+
def init_output output
|
65
|
+
@output = output
|
66
|
+
@output.binmode
|
67
|
+
@output.sync = true
|
68
|
+
self
|
69
|
+
end
|
70
|
+
|
71
|
+
def do_output output
|
72
|
+
oi = @output
|
73
|
+
init_output output
|
74
|
+
yield
|
75
|
+
ensure
|
76
|
+
@output = oi
|
77
|
+
end
|
78
|
+
|
79
|
+
def put obj
|
80
|
+
case obj
|
81
|
+
when nil then write_fmt 0xc0
|
82
|
+
when false then write_fmt 0xc2
|
83
|
+
when true then write_fmt 0xc3
|
84
|
+
when Integer then
|
85
|
+
if obj >= 0 then
|
86
|
+
case obj
|
87
|
+
when ...0x80 then write_fmt obj
|
88
|
+
when ...0x100 then write_fmt 0xcc ; write_pack obj, "C"
|
89
|
+
when ...0x10000 then write_fmt 0xcd ; write_pack obj, "S>"
|
90
|
+
when ...0x100000000 then write_fmt 0xce ; write_pack obj, "L>"
|
91
|
+
when ...0x10000000000000000 then write_fmt 0xcf ; write_pack obj, "Q>"
|
92
|
+
else raise ArgumentError, "Integer too large: #{obj}"
|
93
|
+
end
|
94
|
+
else
|
95
|
+
case obj
|
96
|
+
when -0x20... then write_fmt obj+256
|
97
|
+
when -0x80... then write_fmt 0xd0 ; write_pack obj, "c"
|
98
|
+
when -0x8000... then write_fmt 0xd1 ; write_pack obj, "s>"
|
99
|
+
when -0x80000000... then write_fmt 0xd2 ; write_pack obj, "l>"
|
100
|
+
when -0x8000000000000000... then write_fmt 0xd3 ; write_pack obj, "q>"
|
101
|
+
else raise ArgumentError, "Integer too large: #{obj}"
|
102
|
+
end
|
103
|
+
end
|
104
|
+
when Float then
|
105
|
+
case
|
106
|
+
when false then write_fmt 0xca ; write_pack obj, "g"
|
107
|
+
else write_fmt 0xcb ; write_pack obj, "G"
|
108
|
+
end
|
109
|
+
when String then
|
110
|
+
if obj.encoding == Encoding::ASCII_8BIT then
|
111
|
+
l = obj.size
|
112
|
+
case l
|
113
|
+
when ...0x100 then write_fmt 0xc4 ; write_pack l, "C"
|
114
|
+
when ...0x10000 then write_fmt 0xc5 ; write_pack l, "S>"
|
115
|
+
when ...0x100000000 then write_fmt 0xc6 ; write_pack l, "L>"
|
116
|
+
else raise ArgumentError, "Byte array too long: #{l} bytes"
|
117
|
+
end
|
118
|
+
else
|
119
|
+
obj = obj.encode Encoding::UTF_8 unless obj.encoding == Encoding::UTF_8
|
120
|
+
l = obj.bytesize
|
121
|
+
case l
|
122
|
+
when ...0x20 then write_fmt 0xa0+l
|
123
|
+
when ...0x100 then write_fmt 0xd9 ; write_pack l, "C"
|
124
|
+
when ...0x10000 then write_fmt 0xda ; write_pack l, "S>"
|
125
|
+
when ...0x100000000 then write_fmt 0xdb ; write_pack l, "L>"
|
126
|
+
else raise ArgumentError, "String too long: #{l} bytes"
|
127
|
+
end
|
128
|
+
end
|
129
|
+
write_pack obj, "A*"
|
130
|
+
when Array then
|
131
|
+
l = obj.length
|
132
|
+
case l
|
133
|
+
when ...0x10 then write_fmt 0x90+l
|
134
|
+
when ...0x10000 then write_fmt 0xdc ; write_pack l, "S>"
|
135
|
+
when ...0x100000000 then write_fmt 0xdd ; write_pack l, "L>"
|
136
|
+
else raise ArgumentError, "Array too long: #{l} elements"
|
137
|
+
end
|
138
|
+
obj.each { |o| put o }
|
139
|
+
when Hash then
|
140
|
+
l = obj.length
|
141
|
+
case l
|
142
|
+
when ...0x10 then write_fmt 0x80+l
|
143
|
+
when ...0x10000 then write_fmt 0xde ; write_pack l, "S>"
|
144
|
+
when ...0x100000000 then write_fmt 0xdf ; write_pack l, "L>"
|
145
|
+
else raise ArgumentError, "Hash too long: #{l} keys"
|
146
|
+
end
|
147
|
+
obj.each { |k,v| put k ; put v }
|
148
|
+
when Symbol then
|
149
|
+
put obj.to_s
|
150
|
+
else
|
151
|
+
type, data = dump obj
|
152
|
+
type or return put obj.to_s
|
153
|
+
l = data.bytesize
|
154
|
+
case l
|
155
|
+
when 0x01 then write_fmt 0xd4 ; write_pack type, "c"
|
156
|
+
when 0x02 then write_fmt 0xd5 ; write_pack type, "c"
|
157
|
+
when 0x04 then write_fmt 0xd6 ; write_pack type, "c"
|
158
|
+
when 0x08 then write_fmt 0xd7 ; write_pack type, "c"
|
159
|
+
when 0x10 then write_fmt 0xd8 ; write_pack type, "c"
|
160
|
+
when ...0x100 then write_fmt 0xc7 ; write_pack l, "C" ; write_pack type, "c"
|
161
|
+
when ...0x10000 then write_fmt 0xc8 ; write_pack l, "S>" ; write_pack type, "c"
|
162
|
+
when ...0x100000000 then write_fmt 0xc9 ; write_pack l, "L>" ; write_pack type, "c"
|
163
|
+
else raise ArgumentError, "Object too large: #{l} bytes"
|
164
|
+
end
|
165
|
+
write_pack data, "A*"
|
166
|
+
end
|
167
|
+
self
|
168
|
+
end
|
169
|
+
|
170
|
+
private
|
171
|
+
|
172
|
+
def write_pack i, t
|
173
|
+
d = [i].pack t
|
174
|
+
@output.write d
|
175
|
+
end
|
176
|
+
|
177
|
+
def write_fmt i
|
178
|
+
write_pack i, "C"
|
179
|
+
end
|
180
|
+
|
181
|
+
end
|
182
|
+
|
183
|
+
|
184
|
+
module Unpacker
|
185
|
+
|
186
|
+
attr_reader :input
|
187
|
+
|
188
|
+
def init_input input
|
189
|
+
@input = input
|
190
|
+
@input.binmode
|
191
|
+
self
|
192
|
+
end
|
193
|
+
|
194
|
+
def do_input input
|
195
|
+
oi = @input
|
196
|
+
init_input input
|
197
|
+
yield
|
198
|
+
ensure
|
199
|
+
@input = oi
|
200
|
+
end
|
201
|
+
|
202
|
+
def eof?
|
203
|
+
@input.eof?
|
204
|
+
end
|
205
|
+
|
206
|
+
def get
|
207
|
+
fmt = (read 1).unpack1 "C"
|
208
|
+
case fmt >> 7
|
209
|
+
when 0b0 then fmt
|
210
|
+
else
|
211
|
+
case fmt >> 5
|
212
|
+
when 0b111 then fmt - 256
|
213
|
+
when 0b101 then get_str fmt&0b11111
|
214
|
+
else
|
215
|
+
case fmt >> 4
|
216
|
+
when 0b1000 then get_hsh fmt&0b1111
|
217
|
+
when 0b1001 then get_ary fmt&0b1111
|
218
|
+
else
|
219
|
+
case fmt
|
220
|
+
when 0xc0 then nil
|
221
|
+
when 0xc1 then raise ArgumentError, "Illegal format: #{fmt}"
|
222
|
+
when 0xc2 then false
|
223
|
+
when 0xc3 then true
|
224
|
+
when 0xc4 then read get_len1
|
225
|
+
when 0xc5 then read get_len2
|
226
|
+
when 0xc6 then read get_len4
|
227
|
+
when 0xc7 then get_ext get_len1
|
228
|
+
when 0xc8 then get_ext get_len2
|
229
|
+
when 0xc9 then get_ext get_len4
|
230
|
+
when 0xca then (read 4).unpack1 "g"
|
231
|
+
when 0xcb then (read 8).unpack1 "G"
|
232
|
+
when 0xcc then (read 1).unpack1 "C"
|
233
|
+
when 0xcd then (read 2).unpack1 "S>"
|
234
|
+
when 0xce then (read 4).unpack1 "L>"
|
235
|
+
when 0xcf then (read 8).unpack1 "Q>"
|
236
|
+
when 0xd0 then (read 1).unpack1 "c"
|
237
|
+
when 0xd1 then (read 2).unpack1 "s>"
|
238
|
+
when 0xd2 then (read 4).unpack1 "l>"
|
239
|
+
when 0xd3 then (read 8).unpack1 "q>"
|
240
|
+
when 0xd4 then get_ext 1
|
241
|
+
when 0xd5 then get_ext 2
|
242
|
+
when 0xd6 then get_ext 4
|
243
|
+
when 0xd7 then get_ext 8
|
244
|
+
when 0xd8 then get_ext 16
|
245
|
+
when 0xd9 then get_str get_len1
|
246
|
+
when 0xda then get_str get_len2
|
247
|
+
when 0xdb then get_str get_len4
|
248
|
+
when 0xdc then get_ary get_len2
|
249
|
+
when 0xdd then get_ary get_len4
|
250
|
+
when 0xde then get_hsh get_len2
|
251
|
+
when 0xdf then get_hsh get_len4
|
252
|
+
end
|
253
|
+
end
|
254
|
+
end
|
255
|
+
end
|
256
|
+
end
|
257
|
+
|
258
|
+
private
|
259
|
+
|
260
|
+
def read n
|
261
|
+
@input.read n
|
262
|
+
end
|
263
|
+
|
264
|
+
def get_len1 ; (read 1).unpack1 "C" ; end
|
265
|
+
def get_len2 ; (read 2).unpack1 "S>" ; end
|
266
|
+
def get_len4 ; (read 4).unpack1 "L>" ; end
|
267
|
+
|
268
|
+
def get_str len
|
269
|
+
(read len).force_encoding Encoding::UTF_8
|
270
|
+
end
|
271
|
+
|
272
|
+
def get_ary len
|
273
|
+
(0...len).map { get }
|
274
|
+
end
|
275
|
+
|
276
|
+
def get_hsh len
|
277
|
+
(0...len).inject Hash.new do |h,| k = get ; h[k] = get ; h end
|
278
|
+
end
|
279
|
+
|
280
|
+
def get_ext len
|
281
|
+
type = (read 1).unpack1 "c"
|
282
|
+
create type, (read len)
|
283
|
+
end
|
284
|
+
|
285
|
+
end
|
286
|
+
|
287
|
+
end
|
288
|
+
|
289
|
+
|
290
|
+
class Time
|
291
|
+
|
292
|
+
class <<self
|
293
|
+
|
294
|
+
def from_mpdata data, *args
|
295
|
+
case data.length
|
296
|
+
when 4 then
|
297
|
+
s, = data.unpack "L>"
|
298
|
+
Time.at s
|
299
|
+
when 8 then
|
300
|
+
t, = data.unpack "Q>"
|
301
|
+
n = t >> 34
|
302
|
+
t &= 0x3ffffffff
|
303
|
+
Time.at t, n, :nanosecond
|
304
|
+
when 12 then
|
305
|
+
n, s = data.unpack "L>Q>"
|
306
|
+
Time.at s, n, :nanosecond
|
307
|
+
else
|
308
|
+
raise ArgumentError, "Illegal time data: #{data.inspect}"
|
309
|
+
end
|
310
|
+
end
|
311
|
+
|
312
|
+
end
|
313
|
+
|
314
|
+
def to_mpdata
|
315
|
+
case
|
316
|
+
when tv_nsec.zero? && tv_sec < 0x100000000 then [ tv_sec].pack "L>"
|
317
|
+
when tv_sec < 0x400000000 then [ (tv_nsec << 34)|tv_sec].pack "Q>"
|
318
|
+
else [ tv_nsec, tv_sec].pack "L>Q>"
|
319
|
+
end
|
320
|
+
end
|
321
|
+
|
322
|
+
end
|
323
|
+
|
324
|
+
# ----------------------------------------------------------------
|
325
|
+
|
326
|
+
end
|
327
|
+
|
@@ -0,0 +1,20 @@
|
|
1
|
+
#
|
2
|
+
# neovim/foreign/supplement/socket.rb -- Addition usefull Ruby socket functions
|
3
|
+
#
|
4
|
+
|
5
|
+
# The purpose of this is simply to reduce dependencies.
|
6
|
+
|
7
|
+
begin
|
8
|
+
require "supplement/socket"
|
9
|
+
rescue LoadError
|
10
|
+
require "socket"
|
11
|
+
class TCPServer
|
12
|
+
alias accept_orig accept
|
13
|
+
private :accept_orig
|
14
|
+
def accept
|
15
|
+
a = accept_orig
|
16
|
+
if block_given? then yield a else a end
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
@@ -0,0 +1,34 @@
|
|
1
|
+
#
|
2
|
+
# neovim/foreign/supplement.rb -- Addition usefull Ruby functions
|
3
|
+
#
|
4
|
+
|
5
|
+
# The purpose of this is simply to reduce dependencies.
|
6
|
+
|
7
|
+
begin
|
8
|
+
require "supplement"
|
9
|
+
rescue LoadError
|
10
|
+
class NilClass ; def notempty? ; end ; end
|
11
|
+
class String ; def notempty? ; self unless empty? ; end ; end
|
12
|
+
class Array ; def notempty? ; self unless empty? ; end ; end
|
13
|
+
class NilClass ; def to_bool ; false ; end ; end
|
14
|
+
class FalseClass ; def to_bool ; false ; end ; end
|
15
|
+
class Object ; def to_bool ; true ; end ; end
|
16
|
+
class <<Struct ; alias [] new ; end
|
17
|
+
class String
|
18
|
+
def axe n
|
19
|
+
if n < length then
|
20
|
+
e = "..."
|
21
|
+
l = e.length
|
22
|
+
if n > l then
|
23
|
+
n -= l
|
24
|
+
else
|
25
|
+
l = 0
|
26
|
+
end
|
27
|
+
(slice 0, n) << "..."[0,l]
|
28
|
+
else
|
29
|
+
self
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
@@ -0,0 +1,139 @@
|
|
1
|
+
#
|
2
|
+
# lib/neovim/handler.rb -- Handlers
|
3
|
+
#
|
4
|
+
|
5
|
+
require "neovim/foreign/supplement"
|
6
|
+
|
7
|
+
|
8
|
+
module Neovim
|
9
|
+
|
10
|
+
class Handler
|
11
|
+
|
12
|
+
attr_reader :spec
|
13
|
+
|
14
|
+
def initialize name, type = nil, sync = nil, **options, &block
|
15
|
+
@block = block
|
16
|
+
standardize options
|
17
|
+
@spec = {
|
18
|
+
name: name,
|
19
|
+
opts: options,
|
20
|
+
type: type,
|
21
|
+
sync: sync,
|
22
|
+
}
|
23
|
+
@spec.compact!
|
24
|
+
end
|
25
|
+
|
26
|
+
def name ; @spec[ :name] ; end
|
27
|
+
def opts ; @spec[ :opts] ; end
|
28
|
+
alias options opts
|
29
|
+
def sync ; @spec[ :sync] ; end
|
30
|
+
alias sync? sync
|
31
|
+
|
32
|
+
def execute *args
|
33
|
+
@block.call *args
|
34
|
+
end
|
35
|
+
|
36
|
+
private
|
37
|
+
|
38
|
+
def standardize opts
|
39
|
+
opts.each { |k,v|
|
40
|
+
case v
|
41
|
+
when false then opts[ k] = nil
|
42
|
+
when true then opts[ k] = ""
|
43
|
+
when String, Integer then
|
44
|
+
else opts[ k] = v.to_s
|
45
|
+
end
|
46
|
+
}
|
47
|
+
opts.compact!
|
48
|
+
end
|
49
|
+
|
50
|
+
end
|
51
|
+
|
52
|
+
class DslBase
|
53
|
+
|
54
|
+
class Plugins
|
55
|
+
|
56
|
+
attr_reader :type
|
57
|
+
|
58
|
+
def initialize type, setup_blocks, handlers
|
59
|
+
@type, @setup_blocks, @handlers = type, setup_blocks, handlers
|
60
|
+
end
|
61
|
+
|
62
|
+
def setup client
|
63
|
+
@setup_blocks.each { |b| b.call client }
|
64
|
+
end
|
65
|
+
|
66
|
+
def get_handler name
|
67
|
+
@handlers[ name]
|
68
|
+
end
|
69
|
+
|
70
|
+
def specs
|
71
|
+
@handlers.map { |_,handler| handler.spec }
|
72
|
+
end
|
73
|
+
|
74
|
+
def options
|
75
|
+
@handlers.each { |name,handler| yield name, handler.options }
|
76
|
+
end
|
77
|
+
|
78
|
+
end
|
79
|
+
|
80
|
+
include Logging
|
81
|
+
|
82
|
+
class <<self
|
83
|
+
private :new
|
84
|
+
def open source, host
|
85
|
+
i = new source
|
86
|
+
yield i
|
87
|
+
i.add_plugins source, host
|
88
|
+
end
|
89
|
+
end
|
90
|
+
|
91
|
+
def initialize source
|
92
|
+
@setup_blocks = []
|
93
|
+
@handlers = {}
|
94
|
+
end
|
95
|
+
|
96
|
+
def add_plugins source, host
|
97
|
+
host.add_plugins source, (Plugins.new self.class::TYPE, @setup_blocks, @handlers)
|
98
|
+
end
|
99
|
+
|
100
|
+
private
|
101
|
+
|
102
|
+
def add_handler qualified_name, name, type = nil, sync = nil, **opts, &block
|
103
|
+
name = name.to_s
|
104
|
+
qualified_name ||= name
|
105
|
+
h = Handler.new name, type, sync, **opts, &block
|
106
|
+
log :info, "Adding Handler", qualified_name: qualified_name, handler: h.spec
|
107
|
+
@handlers[ qualified_name] = h
|
108
|
+
end
|
109
|
+
|
110
|
+
def add_setup_block &block
|
111
|
+
@setup_blocks.push block
|
112
|
+
end
|
113
|
+
|
114
|
+
end
|
115
|
+
|
116
|
+
class DslPlain < DslBase
|
117
|
+
|
118
|
+
TYPE = :base
|
119
|
+
|
120
|
+
def plain name, **opts
|
121
|
+
add_handler nil, name, **opts do |client,*args|
|
122
|
+
yield *args
|
123
|
+
end
|
124
|
+
end
|
125
|
+
|
126
|
+
end
|
127
|
+
|
128
|
+
class DslRemote < DslBase
|
129
|
+
|
130
|
+
TYPE = :remote
|
131
|
+
|
132
|
+
def register_handler name, &block
|
133
|
+
add_handler nil, name, &block
|
134
|
+
end
|
135
|
+
|
136
|
+
end
|
137
|
+
|
138
|
+
end
|
139
|
+
|
data/lib/neovim/host.rb
ADDED
@@ -0,0 +1,87 @@
|
|
1
|
+
#
|
2
|
+
# neovim/host.rb -- Host for Neovim
|
3
|
+
#
|
4
|
+
|
5
|
+
require "neovim/remote"
|
6
|
+
|
7
|
+
|
8
|
+
module Neovim
|
9
|
+
|
10
|
+
class Host < Remote
|
11
|
+
|
12
|
+
class <<self
|
13
|
+
|
14
|
+
def start
|
15
|
+
super ConnectionStdio do |h|
|
16
|
+
yield h
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
end
|
21
|
+
|
22
|
+
attr_reader :plugins
|
23
|
+
|
24
|
+
BASE = :base
|
25
|
+
|
26
|
+
def initialize conn
|
27
|
+
super
|
28
|
+
DslPlain.open BASE, self do |dsl|
|
29
|
+
dsl.plain "poll" do
|
30
|
+
start
|
31
|
+
@plugins.each_value { |p| p.setup @conn.client }
|
32
|
+
"ok"
|
33
|
+
end
|
34
|
+
dsl.plain "specs", nargs: 1 do |source|
|
35
|
+
p = @plugins[ source]
|
36
|
+
p or raise "Unknown plugin #{source}"
|
37
|
+
p.specs
|
38
|
+
end
|
39
|
+
dsl.plain "nvim_error_event", nargs: 2 do |errid,msg|
|
40
|
+
raise "#{@conn.error errid} from Neovim: #{msg}"
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
def client_name
|
46
|
+
types = @plugins.map { |_,p| p.type if p.type != BASE }
|
47
|
+
types.uniq!
|
48
|
+
types.compact!
|
49
|
+
name = types.join "-"
|
50
|
+
log :info, "Client Name", name: name
|
51
|
+
"ruby-#{name}-host"
|
52
|
+
end
|
53
|
+
|
54
|
+
def client_methods
|
55
|
+
r = {}
|
56
|
+
@plugins[ BASE].options { |name,opts| r[ name] = opts }
|
57
|
+
r
|
58
|
+
end
|
59
|
+
|
60
|
+
|
61
|
+
class <<self
|
62
|
+
|
63
|
+
def run
|
64
|
+
$stdin.tty? and raise "This program expects to be called by Neovim. It can't run interactively."
|
65
|
+
Host.start do |h|
|
66
|
+
yield h
|
67
|
+
h.run
|
68
|
+
nil
|
69
|
+
rescue Messager::Disconnected
|
70
|
+
log :fatal, "Disconnected"
|
71
|
+
nil
|
72
|
+
rescue SignalException
|
73
|
+
n = $!.signm
|
74
|
+
log :fatal, "Signal was caught: #{n}"
|
75
|
+
(n =~ /\A(?:SIG)?TERM\z/) ? 0 : 1
|
76
|
+
rescue Exception
|
77
|
+
log_exception :fatal
|
78
|
+
2
|
79
|
+
end
|
80
|
+
end
|
81
|
+
|
82
|
+
end
|
83
|
+
|
84
|
+
end
|
85
|
+
|
86
|
+
end
|
87
|
+
|
data/lib/neovim/info.rb
ADDED
@@ -0,0 +1,10 @@
|
|
1
|
+
require "neovim/meta.rb"
|
2
|
+
Neovim::INFO = Neovim::Meta.new "nvim",
|
3
|
+
version: "1.0.0",
|
4
|
+
license: "BSD-2-Clause+",
|
5
|
+
authors: ["Bertram Scharpf"],
|
6
|
+
email: "software@bertram-scharpf.de",
|
7
|
+
summary: "Yet another Ruby client for Neovim",
|
8
|
+
description: "A simple Ruby client for Neovim.\nClean code, minimal dependecies, no frills, no wokeness.",
|
9
|
+
homepage: "http://bertram-scharpf.de",
|
10
|
+
commit: "e927f7e"
|