neovim 0.0.3 → 0.0.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/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
|