neovim 0.0.3 → 0.0.4
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +7 -0
- data/bin/neovim-ruby-host +1 -2
- data/lib/neovim.rb +13 -12
- data/lib/neovim/api_info.rb +1 -1
- data/lib/neovim/async_session.rb +4 -6
- data/lib/neovim/buffer.rb +2 -62
- data/lib/neovim/client.rb +0 -4
- data/lib/neovim/current.rb +9 -0
- data/lib/neovim/event_loop.rb +14 -13
- data/lib/neovim/host.rb +17 -55
- data/lib/neovim/line_range.rb +61 -0
- data/lib/neovim/manifest.rb +62 -0
- data/lib/neovim/msgpack_stream.rb +3 -6
- data/lib/neovim/notification.rb +5 -1
- data/lib/neovim/plugin.rb +77 -35
- data/lib/neovim/request.rb +5 -1
- data/lib/neovim/version.rb +1 -1
- data/spec/acceptance/neovim-ruby-host_spec.rb +15 -24
- data/spec/helper.rb +2 -0
- data/spec/neovim/async_session_spec.rb +2 -2
- data/spec/neovim/buffer_spec.rb +3 -41
- data/spec/neovim/current_spec.rb +14 -0
- data/spec/neovim/event_loop_spec.rb +54 -6
- data/spec/neovim/host_spec.rb +7 -46
- data/spec/neovim/line_range_spec.rb +68 -0
- data/spec/neovim/manifest_spec.rb +113 -0
- data/spec/neovim/msgpack_stream_spec.rb +5 -3
- data/spec/neovim/plugin_spec.rb +33 -33
- data/spec/neovim/session_spec.rb +97 -18
- data/spec/neovim_spec.rb +13 -4
- metadata +9 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 6d788e73532acb46ec8b33b5391fb1a1077bd69d
|
4
|
+
data.tar.gz: 3456c2d23d5f98802b0bbb2ac29612e20a51e11c
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: fa3098403bd3e78a7b56eaf21f8810190d1cb34b17fd8365cfe424537294440b99351d67b33408e3d1f4b094cd2013f193be87b1eb66db6f4d4c6b59cb9e084a
|
7
|
+
data.tar.gz: 5a12541cec062aa8643decc49b580aa76c562f734d1319ce77e8284a503b2b37a6afa9eb075abbe9e2d97278a003a301ea2d51dc469bc05713f1bc121b25e3e1
|
data/CHANGELOG.md
CHANGED
@@ -1,3 +1,10 @@
|
|
1
|
+
# 0.0.4
|
2
|
+
- Add support for loading Ruby remote plugins from nvim
|
3
|
+
- Add Current#range to return a LineRange enumerable object
|
4
|
+
- Support sending large messages
|
5
|
+
- Remove unecessary #stop methods
|
6
|
+
- Add setup callback support to event loop
|
7
|
+
|
1
8
|
# 0.0.3
|
2
9
|
|
3
10
|
- Add Buffer#lines enumerable interface
|
data/bin/neovim-ruby-host
CHANGED
data/lib/neovim.rb
CHANGED
@@ -7,7 +7,9 @@ require "neovim/session"
|
|
7
7
|
require "neovim/plugin"
|
8
8
|
|
9
9
|
module Neovim
|
10
|
-
|
10
|
+
class << self
|
11
|
+
attr_accessor :__configured_plugin_manifest, :__configured_plugin_path
|
12
|
+
end
|
11
13
|
|
12
14
|
def self.attach_tcp(host, port)
|
13
15
|
attach_event_loop(EventLoop.tcp(host, port))
|
@@ -26,22 +28,21 @@ module Neovim
|
|
26
28
|
end
|
27
29
|
|
28
30
|
def self.plugin(&block)
|
29
|
-
Plugin.from_config_block(&block).tap do |plugin|
|
30
|
-
|
31
|
+
Plugin.from_config_block(__configured_plugin_path, &block).tap do |plugin|
|
32
|
+
if __configured_plugin_manifest.respond_to?(:register)
|
33
|
+
__configured_plugin_manifest.register(plugin)
|
34
|
+
end
|
31
35
|
end
|
32
36
|
end
|
33
37
|
|
34
|
-
class << self
|
35
|
-
attr_accessor :__configured_plugins
|
36
38
|
|
37
|
-
private
|
38
39
|
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
40
|
+
def self.attach_event_loop(event_loop)
|
41
|
+
msgpack_stream = MsgpackStream.new(event_loop)
|
42
|
+
async_session = AsyncSession.new(msgpack_stream)
|
43
|
+
session = Session.new(async_session)
|
43
44
|
|
44
|
-
|
45
|
-
end
|
45
|
+
Client.new(session)
|
46
46
|
end
|
47
|
+
private_class_method :attach_event_loop
|
47
48
|
end
|
data/lib/neovim/api_info.rb
CHANGED
data/lib/neovim/async_session.rb
CHANGED
@@ -27,11 +27,12 @@ module Neovim
|
|
27
27
|
self
|
28
28
|
end
|
29
29
|
|
30
|
-
def run(request_cb=nil, notification_cb=nil)
|
30
|
+
def run(request_cb=nil, notification_cb=nil, setup_cb=nil)
|
31
31
|
request_cb ||= Proc.new {}
|
32
32
|
notification_cb ||= Proc.new {}
|
33
|
+
setup_cb ||= Proc.new {}
|
33
34
|
|
34
|
-
|
35
|
+
msg_cb = Proc.new do |msg|
|
35
36
|
kind, *rest = msg
|
36
37
|
|
37
38
|
case kind
|
@@ -46,11 +47,8 @@ module Neovim
|
|
46
47
|
notification_cb.call(Notification.new(method, args))
|
47
48
|
end
|
48
49
|
end
|
49
|
-
end
|
50
50
|
|
51
|
-
|
52
|
-
@msgpack_stream.stop
|
53
|
-
self
|
51
|
+
@msgpack_stream.run(msg_cb, setup_cb)
|
54
52
|
end
|
55
53
|
end
|
56
54
|
end
|
data/lib/neovim/buffer.rb
CHANGED
@@ -1,74 +1,14 @@
|
|
1
1
|
require "neovim/object"
|
2
|
+
require "neovim/line_range"
|
2
3
|
|
3
4
|
module Neovim
|
4
5
|
class Buffer < Neovim::Object
|
5
6
|
def lines
|
6
|
-
@lines ||=
|
7
|
+
@lines ||= LineRange.new(self, 0, -1)
|
7
8
|
end
|
8
9
|
|
9
10
|
def lines=(arr)
|
10
11
|
lines[0..-1] = arr
|
11
12
|
end
|
12
|
-
|
13
|
-
class Lines
|
14
|
-
include Enumerable
|
15
|
-
|
16
|
-
def initialize(buffer)
|
17
|
-
@buffer = buffer
|
18
|
-
end
|
19
|
-
|
20
|
-
def ==(other)
|
21
|
-
case other
|
22
|
-
when Array
|
23
|
-
to_a == other
|
24
|
-
else
|
25
|
-
super
|
26
|
-
end
|
27
|
-
end
|
28
|
-
|
29
|
-
def to_a
|
30
|
-
self[0..-1]
|
31
|
-
end
|
32
|
-
|
33
|
-
def each(&block)
|
34
|
-
to_a.each(&block)
|
35
|
-
end
|
36
|
-
|
37
|
-
def [](idx, len=nil)
|
38
|
-
case idx
|
39
|
-
when Range
|
40
|
-
@buffer.get_line_slice(idx.begin, idx.end, true, !idx.exclude_end?)
|
41
|
-
else
|
42
|
-
if len
|
43
|
-
@buffer.get_line_slice(idx, idx + len, true, false)
|
44
|
-
else
|
45
|
-
@buffer.get_line(idx)
|
46
|
-
end
|
47
|
-
end
|
48
|
-
end
|
49
|
-
alias_method :slice, :[]
|
50
|
-
|
51
|
-
def []=(*args)
|
52
|
-
*target, val = args
|
53
|
-
idx, len = target
|
54
|
-
|
55
|
-
case idx
|
56
|
-
when Range
|
57
|
-
@buffer.set_line_slice(
|
58
|
-
idx.begin,
|
59
|
-
idx.end,
|
60
|
-
true,
|
61
|
-
!idx.exclude_end?,
|
62
|
-
val
|
63
|
-
)
|
64
|
-
else
|
65
|
-
if len
|
66
|
-
@buffer.set_line_slice(idx, idx + len, true, false, val)
|
67
|
-
else
|
68
|
-
@buffer.set_line(idx, val)
|
69
|
-
end
|
70
|
-
end
|
71
|
-
end
|
72
|
-
end
|
73
13
|
end
|
74
14
|
end
|
data/lib/neovim/client.rb
CHANGED
data/lib/neovim/current.rb
CHANGED
@@ -42,5 +42,14 @@ module Neovim
|
|
42
42
|
tabpage = Tabpage.new(tabpage_index, @session)
|
43
43
|
@session.request(:vim_set_current_tabpage, tabpage)
|
44
44
|
end
|
45
|
+
|
46
|
+
def range
|
47
|
+
@range ||= LineRange.new(buffer, 0, -1)
|
48
|
+
end
|
49
|
+
|
50
|
+
def range=(_range)
|
51
|
+
_end = _range.exclude_end? ? _range.end - 1 : _range.end
|
52
|
+
@range = LineRange.new(buffer, _range.begin, _end)
|
53
|
+
end
|
45
54
|
end
|
46
55
|
end
|
data/lib/neovim/event_loop.rb
CHANGED
@@ -28,28 +28,29 @@ module Neovim
|
|
28
28
|
end
|
29
29
|
|
30
30
|
def send(data)
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
31
|
+
start = 0
|
32
|
+
size = data.size
|
33
|
+
|
34
|
+
begin
|
35
|
+
while start < size
|
36
|
+
start += @wr.write_nonblock(data[start..-1])
|
37
|
+
end
|
38
|
+
self
|
39
|
+
rescue IO::WaitWritable
|
40
|
+
IO.select(nil, [@wr])
|
41
|
+
retry
|
42
|
+
end
|
36
43
|
end
|
37
44
|
|
38
|
-
def run(
|
45
|
+
def run(message_callback, setup_callback=nil)
|
39
46
|
@running = true
|
40
|
-
|
47
|
+
setup_callback.call if setup_callback.respond_to?(:call)
|
41
48
|
|
42
49
|
loop do
|
43
50
|
break unless @running
|
44
51
|
message_callback.call(@rd.readpartial(1024 * 16))
|
45
52
|
end
|
46
53
|
rescue EOFError
|
47
|
-
stop
|
48
|
-
end
|
49
|
-
|
50
|
-
def stop
|
51
|
-
@running = false
|
52
|
-
self
|
53
54
|
end
|
54
55
|
end
|
55
56
|
end
|
data/lib/neovim/host.rb
CHANGED
@@ -1,85 +1,47 @@
|
|
1
|
+
require "neovim/manifest"
|
2
|
+
|
1
3
|
module Neovim
|
2
4
|
class Host
|
3
|
-
def self.load_from_files(rplugin_paths)
|
4
|
-
|
5
|
-
|
5
|
+
def self.load_from_files(rplugin_paths, target_manifest=Manifest.new)
|
6
|
+
old_manifest = Neovim.__configured_plugin_manifest
|
7
|
+
old_path = Neovim.__configured_plugin_path
|
6
8
|
|
7
9
|
begin
|
8
|
-
Neovim.
|
10
|
+
Neovim.__configured_plugin_manifest = target_manifest
|
9
11
|
|
10
12
|
rplugin_paths.each do |rplugin_path|
|
13
|
+
Neovim.__configured_plugin_path = rplugin_path
|
11
14
|
Kernel.load(rplugin_path, true)
|
12
15
|
end
|
13
16
|
|
14
|
-
new(
|
17
|
+
new(target_manifest)
|
15
18
|
ensure
|
16
|
-
Neovim.
|
19
|
+
Neovim.__configured_plugin_manifest = old_manifest
|
20
|
+
Neovim.__configured_plugin_path = old_path
|
17
21
|
end
|
18
22
|
end
|
19
23
|
|
20
|
-
attr_reader :
|
24
|
+
attr_reader :manifest
|
21
25
|
|
22
|
-
def initialize(
|
23
|
-
@
|
24
|
-
@handlers = compile_handlers(plugins)
|
26
|
+
def initialize(manifest)
|
27
|
+
@manifest = manifest
|
25
28
|
@event_loop = EventLoop.stdio
|
26
29
|
@msgpack_stream = MsgpackStream.new(@event_loop)
|
27
30
|
@async_session = AsyncSession.new(@msgpack_stream)
|
28
31
|
end
|
29
32
|
|
30
33
|
def run
|
31
|
-
|
32
|
-
@
|
33
|
-
end
|
34
|
-
|
35
|
-
request_callback = Proc.new do |request|
|
36
|
-
@handlers[:request][request.method_name].call(client, request)
|
34
|
+
callback = Proc.new do |msg|
|
35
|
+
@manifest.handle(msg, client)
|
37
36
|
end
|
38
37
|
|
39
|
-
@async_session.run(
|
38
|
+
@async_session.run(callback, callback)
|
40
39
|
end
|
41
40
|
|
42
41
|
private
|
43
42
|
|
44
43
|
def client
|
45
|
-
@client ||= Client.new(
|
46
|
-
end
|
47
|
-
|
48
|
-
def session
|
49
|
-
@session ||= Session.new(@async_session)
|
50
|
-
end
|
51
|
-
|
52
|
-
def compile_handlers(plugins)
|
53
|
-
default_req_handler = Proc.new do |_, request|
|
54
|
-
request.error("Unknown request #{request.method_name.inspect}")
|
55
|
-
end
|
56
|
-
|
57
|
-
default_ntf_handler = Proc.new {}
|
58
|
-
|
59
|
-
base = {
|
60
|
-
:request => Hash.new(default_req_handler),
|
61
|
-
:notification => Hash.new(default_ntf_handler)
|
62
|
-
}
|
63
|
-
|
64
|
-
base[:request][:poll] = lambda do |_, request|
|
65
|
-
request.respond("ok")
|
66
|
-
end
|
67
|
-
|
68
|
-
plugins.inject(base) do |handlers, plugin|
|
69
|
-
plugin.specs.each do |spec|
|
70
|
-
if spec[:sync]
|
71
|
-
handlers[:request][spec[:name]] = lambda do |client, request|
|
72
|
-
request.respond(spec[:proc].call(client, *request.arguments))
|
73
|
-
end
|
74
|
-
else
|
75
|
-
handlers[:notification][spec[:name]] = lambda do |client, notification|
|
76
|
-
spec[:proc].call(client, *notification.arguments)
|
77
|
-
end
|
78
|
-
end
|
79
|
-
end
|
80
|
-
|
81
|
-
handlers
|
82
|
-
end
|
44
|
+
@client ||= Client.new(Session.new(@async_session))
|
83
45
|
end
|
84
46
|
end
|
85
47
|
end
|
@@ -0,0 +1,61 @@
|
|
1
|
+
module Neovim
|
2
|
+
class LineRange
|
3
|
+
include Enumerable
|
4
|
+
|
5
|
+
def initialize(buffer, _begin, _end)
|
6
|
+
@buffer = buffer
|
7
|
+
@begin = _begin
|
8
|
+
@end = _end
|
9
|
+
end
|
10
|
+
|
11
|
+
def to_a
|
12
|
+
@buffer.get_line_slice(@begin, @end, true, true)
|
13
|
+
end
|
14
|
+
|
15
|
+
def each(&block)
|
16
|
+
to_a.each(&block)
|
17
|
+
end
|
18
|
+
|
19
|
+
def [](idx, len=nil)
|
20
|
+
case idx
|
21
|
+
when ::Range
|
22
|
+
_end = idx.exclude_end? ? idx.end - 1 : idx.end
|
23
|
+
LineRange.new(@buffer, idx.begin, _end)
|
24
|
+
else
|
25
|
+
if len
|
26
|
+
LineRange.new(@buffer, idx, idx + len - 1)
|
27
|
+
else
|
28
|
+
@buffer.get_line(idx)
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
32
|
+
alias_method :slice, :[]
|
33
|
+
|
34
|
+
def []=(*args)
|
35
|
+
*target, val = args
|
36
|
+
idx, len = target
|
37
|
+
|
38
|
+
case idx
|
39
|
+
when ::Range
|
40
|
+
@buffer.set_line_slice(
|
41
|
+
idx.begin,
|
42
|
+
idx.end,
|
43
|
+
true,
|
44
|
+
!idx.exclude_end?,
|
45
|
+
val
|
46
|
+
)
|
47
|
+
else
|
48
|
+
if len
|
49
|
+
@buffer.set_line_slice(idx, idx + len, true, false, val)
|
50
|
+
else
|
51
|
+
@buffer.set_line(idx, val)
|
52
|
+
end
|
53
|
+
end
|
54
|
+
end
|
55
|
+
|
56
|
+
def replace(other_ary)
|
57
|
+
self[0..-1] = other_ary
|
58
|
+
self
|
59
|
+
end
|
60
|
+
end
|
61
|
+
end
|
@@ -0,0 +1,62 @@
|
|
1
|
+
module Neovim
|
2
|
+
class Manifest
|
3
|
+
attr_reader :handlers, :specs
|
4
|
+
|
5
|
+
def initialize
|
6
|
+
@handlers = {"poll" => poll_handler, "specs" => specs_handler}
|
7
|
+
@specs = {}
|
8
|
+
end
|
9
|
+
|
10
|
+
def register(plugin)
|
11
|
+
plugin.handlers.each do |handler|
|
12
|
+
wrapped_handler = handler.sync? ? wrap_sync(handler) : wrap_async(handler)
|
13
|
+
@handlers[handler.qualified_name] = wrapped_handler
|
14
|
+
end
|
15
|
+
|
16
|
+
@specs[plugin.source] = plugin.specs
|
17
|
+
end
|
18
|
+
|
19
|
+
def handle(msg, client)
|
20
|
+
default_handler = msg.sync? ? default_sync_handler : default_async_handler
|
21
|
+
@handlers.fetch(msg.method_name, default_handler).call(client, msg)
|
22
|
+
end
|
23
|
+
|
24
|
+
private
|
25
|
+
|
26
|
+
def poll_handler
|
27
|
+
@poll_handler ||= Proc.new { |_, req| req.respond("ok") }
|
28
|
+
end
|
29
|
+
|
30
|
+
def specs_handler
|
31
|
+
@specs_handler ||= Proc.new do |_, req|
|
32
|
+
source = req.arguments.fetch(0)
|
33
|
+
|
34
|
+
if @specs.key?(source)
|
35
|
+
req.respond(@specs.fetch(source))
|
36
|
+
else
|
37
|
+
req.error("Unknown plugin #{source}")
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
def default_sync_handler
|
43
|
+
@default_sync_handler ||= Proc.new { |_, req| req.error("Unknown request #{req.method_name}") }
|
44
|
+
end
|
45
|
+
|
46
|
+
def default_async_handler
|
47
|
+
@default_async_handler ||= Proc.new {}
|
48
|
+
end
|
49
|
+
|
50
|
+
def wrap_sync(handler)
|
51
|
+
Proc.new do |client, request|
|
52
|
+
request.respond(handler.call(client, *request.arguments))
|
53
|
+
end
|
54
|
+
end
|
55
|
+
|
56
|
+
def wrap_async(handler)
|
57
|
+
Proc.new do |client, notification|
|
58
|
+
handler.call(client, *notification.arguments)
|
59
|
+
end
|
60
|
+
end
|
61
|
+
end
|
62
|
+
end
|