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.
@@ -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
+
@@ -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
+
@@ -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"