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
@@ -23,17 +23,14 @@ module Neovim
|
|
23
23
|
self
|
24
24
|
end
|
25
25
|
|
26
|
-
def run(
|
27
|
-
|
26
|
+
def run(message_cb, setup_cb=nil)
|
27
|
+
data_cb = Proc.new do |data|
|
28
28
|
@unpacker.feed_each(data) do |msg|
|
29
29
|
message_cb.call(msg)
|
30
30
|
end
|
31
31
|
end
|
32
|
-
end
|
33
32
|
|
34
|
-
|
35
|
-
@event_loop.stop
|
36
|
-
self
|
33
|
+
@event_loop.run(data_cb, setup_cb)
|
37
34
|
end
|
38
35
|
end
|
39
36
|
end
|
data/lib/neovim/notification.rb
CHANGED
data/lib/neovim/plugin.rb
CHANGED
@@ -1,15 +1,60 @@
|
|
1
1
|
module Neovim
|
2
2
|
class Plugin
|
3
|
-
def self.from_config_block(&block)
|
4
|
-
new.tap do |instance|
|
3
|
+
def self.from_config_block(source, &block)
|
4
|
+
new(source).tap do |instance|
|
5
5
|
block.call(DSL.new(instance)) if block
|
6
6
|
end
|
7
7
|
end
|
8
8
|
|
9
|
-
attr_accessor :
|
9
|
+
attr_accessor :handlers
|
10
|
+
attr_reader :source
|
10
11
|
|
11
|
-
def initialize
|
12
|
-
@
|
12
|
+
def initialize(source)
|
13
|
+
@handlers = []
|
14
|
+
@source = source
|
15
|
+
end
|
16
|
+
|
17
|
+
def specs
|
18
|
+
@handlers.map(&:to_spec)
|
19
|
+
end
|
20
|
+
|
21
|
+
class Handler
|
22
|
+
attr_reader :block
|
23
|
+
|
24
|
+
def initialize(source, type, name, sync, options, block)
|
25
|
+
@source = source
|
26
|
+
@type = type.to_sym
|
27
|
+
@name = name.to_s
|
28
|
+
@sync = !!sync
|
29
|
+
@options = options
|
30
|
+
@block = block || ::Proc.new {}
|
31
|
+
end
|
32
|
+
|
33
|
+
def qualified_name
|
34
|
+
if @type == :autocmd
|
35
|
+
pattern = @options.fetch(:pattern, "*")
|
36
|
+
"#{@source}:#{@type}:#{@name}:#{pattern}"
|
37
|
+
else
|
38
|
+
"#{@source}:#{@type}:#{@name}"
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
def sync?
|
43
|
+
@sync
|
44
|
+
end
|
45
|
+
|
46
|
+
def to_spec
|
47
|
+
{
|
48
|
+
:type => @type,
|
49
|
+
:name => @name,
|
50
|
+
:sync => @sync,
|
51
|
+
:opts => @options,
|
52
|
+
}
|
53
|
+
end
|
54
|
+
|
55
|
+
def call(*args)
|
56
|
+
@block.call(*args)
|
57
|
+
end
|
13
58
|
end
|
14
59
|
|
15
60
|
class DSL < BasicObject
|
@@ -17,44 +62,41 @@ module Neovim
|
|
17
62
|
@plugin = plugin
|
18
63
|
end
|
19
64
|
|
20
|
-
def command(name,
|
21
|
-
options
|
22
|
-
|
23
|
-
options[:range] = ::Kernel.String(options[:range])
|
65
|
+
def command(name, options={}, &block)
|
66
|
+
register_handler(:command, name, options, block)
|
67
|
+
end
|
24
68
|
|
25
|
-
|
26
|
-
|
27
|
-
:name => name.to_sym,
|
28
|
-
:sync => !!options.delete(:sync),
|
29
|
-
:opts => options,
|
30
|
-
:proc => block || ::Proc.new {}
|
31
|
-
)
|
69
|
+
def function(name, options={}, &block)
|
70
|
+
register_handler(:function, name, options, block)
|
32
71
|
end
|
33
72
|
|
34
|
-
def
|
35
|
-
options
|
36
|
-
|
37
|
-
|
73
|
+
def autocmd(name, options={}, &block)
|
74
|
+
register_handler(:autocmd, name, options, block)
|
75
|
+
end
|
76
|
+
|
77
|
+
private
|
78
|
+
|
79
|
+
def register_handler(type, name, _options, block)
|
80
|
+
if type == :autocmd
|
81
|
+
options = _options.dup
|
82
|
+
else
|
83
|
+
options = standardize_range(_options.dup)
|
84
|
+
end
|
38
85
|
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
:opts => options,
|
44
|
-
:proc => block || ::Proc.new {}
|
86
|
+
sync = options.delete(:sync)
|
87
|
+
|
88
|
+
@plugin.handlers.push(
|
89
|
+
Handler.new(@plugin.source, type, name, sync, options, block)
|
45
90
|
)
|
46
91
|
end
|
47
92
|
|
48
|
-
def
|
49
|
-
options
|
93
|
+
def standardize_range(options)
|
94
|
+
if options.key?(:range)
|
95
|
+
options[:range] = "" if options[:range] == true
|
96
|
+
options[:range] = ::Kernel.String(options[:range])
|
97
|
+
end
|
50
98
|
|
51
|
-
|
52
|
-
:type => :autocmd,
|
53
|
-
:name => name.to_sym,
|
54
|
-
:sync => !!options.delete(:sync),
|
55
|
-
:opts => options,
|
56
|
-
:proc => block || ::Proc.new {}
|
57
|
-
)
|
99
|
+
options
|
58
100
|
end
|
59
101
|
end
|
60
102
|
end
|
data/lib/neovim/request.rb
CHANGED
@@ -3,12 +3,16 @@ module Neovim
|
|
3
3
|
attr_reader :method_name, :arguments
|
4
4
|
|
5
5
|
def initialize(method_name, args, msgpack_stream, request_id)
|
6
|
-
@method_name = method_name.
|
6
|
+
@method_name = method_name.to_s
|
7
7
|
@arguments = args
|
8
8
|
@msgpack_stream = msgpack_stream
|
9
9
|
@request_id = request_id
|
10
10
|
end
|
11
11
|
|
12
|
+
def sync?
|
13
|
+
true
|
14
|
+
end
|
15
|
+
|
12
16
|
def respond(value)
|
13
17
|
@msgpack_stream.send([1, @request_id, nil, value])
|
14
18
|
self
|
data/lib/neovim/version.rb
CHANGED
@@ -2,10 +2,11 @@ require "helper"
|
|
2
2
|
require "tmpdir"
|
3
3
|
|
4
4
|
RSpec.describe "neovim-ruby-host" do
|
5
|
-
|
5
|
+
it "loads and runs plugins from Ruby source files" do
|
6
6
|
Dir.mktmpdir do |pwd|
|
7
7
|
Dir.chdir(pwd) do
|
8
|
-
File.
|
8
|
+
plugin1_path = File.expand_path("./plugin1.rb")
|
9
|
+
File.write(plugin1_path, <<-RUBY)
|
9
10
|
Neovim.plugin do |plug|
|
10
11
|
plug.command(:SyncAdd, :args => 2, :sync => true) do |nvim, x, y|
|
11
12
|
x + y
|
@@ -13,7 +14,8 @@ RSpec.describe "neovim-ruby-host" do
|
|
13
14
|
end
|
14
15
|
RUBY
|
15
16
|
|
16
|
-
File.
|
17
|
+
plugin2_path = File.expand_path("./plugin2.rb")
|
18
|
+
File.write(plugin2_path, <<-RUBY)
|
17
19
|
Neovim.plugin do |plug|
|
18
20
|
plug.command(:AsyncSetLine, :args => 1) do |nvim, str|
|
19
21
|
nvim.current.line = str
|
@@ -23,35 +25,24 @@ RSpec.describe "neovim-ruby-host" do
|
|
23
25
|
|
24
26
|
nvim = Neovim.attach_child(["--headless", "-u", "NONE", "-N", "-n"])
|
25
27
|
|
26
|
-
# Start the remote host
|
27
28
|
host_exe = File.expand_path("../../../bin/neovim-ruby-host", __FILE__)
|
28
|
-
nvim.command(
|
29
|
+
nvim.command("let host = rpcstart('#{host_exe}', ['#{plugin1_path}', '#{plugin2_path}'])")
|
29
30
|
|
30
|
-
|
31
|
-
expect(nvim.eval(
|
31
|
+
expect(nvim.eval("rpcrequest(host, 'poll')")).to eq("ok")
|
32
|
+
expect(nvim.eval("rpcrequest(host, '#{plugin1_path}:command:SyncAdd', 1, 2)")).to eq(3)
|
32
33
|
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
nvim.command("put =result")
|
38
|
-
nvim.command("normal o")
|
39
|
-
|
40
|
-
# Set the current line via the AsyncSetLine method
|
41
|
-
nvim.command(%{call rpcnotify(host, "AsyncSetLine", "foo")})
|
34
|
+
expect {
|
35
|
+
nvim.eval("rpcnotify(host, '#{plugin2_path}:command:AsyncSetLine', 'foo')")
|
36
|
+
nvim.eval("rpcrequest(host, 'poll')")
|
37
|
+
}.to change { nvim.current.buffer.lines.to_a }.from([""]).to(["foo"])
|
42
38
|
|
43
|
-
# Make an unknown notification
|
44
39
|
expect {
|
45
|
-
nvim.
|
40
|
+
nvim.eval("rpcnotify(host, 'Unknown')")
|
46
41
|
}.not_to raise_error
|
47
42
|
|
48
|
-
# Make an unknown request
|
49
43
|
expect {
|
50
|
-
nvim.
|
51
|
-
}.to raise_error(ArgumentError
|
52
|
-
|
53
|
-
# Assert the contents of the buffer
|
54
|
-
expect(nvim.current.buffer.lines).to eq(["", "3", "foo"])
|
44
|
+
nvim.eval("call rpcrequest(host, 'Unknown')")
|
45
|
+
}.to raise_error(ArgumentError)
|
55
46
|
end
|
56
47
|
end
|
57
48
|
end
|
data/spec/helper.rb
CHANGED
@@ -28,7 +28,7 @@ module Neovim
|
|
28
28
|
srv_thr.join
|
29
29
|
|
30
30
|
expect(request).to be_a(Request)
|
31
|
-
expect(request.method_name).to eq(
|
31
|
+
expect(request.method_name).to eq("func")
|
32
32
|
expect(request.arguments).to eq([1, 2, 3])
|
33
33
|
end
|
34
34
|
|
@@ -57,7 +57,7 @@ module Neovim
|
|
57
57
|
srv_thr.join
|
58
58
|
|
59
59
|
expect(notification).to be_a(Notification)
|
60
|
-
expect(notification.method_name).to eq(
|
60
|
+
expect(notification.method_name).to eq("func")
|
61
61
|
expect(notification.arguments).to eq([1, 2, 3])
|
62
62
|
end
|
63
63
|
|
data/spec/neovim/buffer_spec.rb
CHANGED
@@ -6,53 +6,15 @@ module Neovim
|
|
6
6
|
let(:buffer) { client.current.buffer }
|
7
7
|
|
8
8
|
describe "#lines" do
|
9
|
-
|
10
|
-
|
11
|
-
client.command("normal o2")
|
12
|
-
client.command("normal o3")
|
13
|
-
end
|
14
|
-
|
15
|
-
it "returns the buffer's lines as an array" do
|
16
|
-
expect(buffer.lines).to eq(["1", "2", "3"])
|
17
|
-
end
|
18
|
-
|
19
|
-
it "can be indexed into" do
|
20
|
-
expect(buffer.lines[1]).to eq("2")
|
21
|
-
end
|
22
|
-
|
23
|
-
it "can be sliced with a length" do
|
24
|
-
expect(buffer.lines[0, 2]).to eq(["1", "2"])
|
25
|
-
end
|
26
|
-
|
27
|
-
it "can be sliced with a range" do
|
28
|
-
expect(buffer.lines[0..1]).to eq(["1", "2"])
|
29
|
-
end
|
30
|
-
|
31
|
-
it "can be updated at an index" do
|
32
|
-
buffer.lines[0] = "foo"
|
33
|
-
expect(buffer.lines).to eq(["foo", "2", "3"])
|
34
|
-
end
|
35
|
-
|
36
|
-
it "can be updated with a length" do
|
37
|
-
buffer.lines[0, 2] = ["foo"]
|
38
|
-
expect(buffer.lines).to eq(["foo", "3"])
|
39
|
-
end
|
40
|
-
|
41
|
-
it "can be updated with a range" do
|
42
|
-
buffer.lines[0..1] = ["foo"]
|
43
|
-
expect(buffer.lines).to eq(["foo", "3"])
|
44
|
-
end
|
45
|
-
|
46
|
-
it "exposes the Enumerable interface" do
|
47
|
-
succ_lines = buffer.lines.collect(&:succ)
|
48
|
-
expect(succ_lines).to eq(["2", "3", "4"])
|
9
|
+
it "returns a LineRange" do
|
10
|
+
expect(buffer.lines).to be_a(LineRange)
|
49
11
|
end
|
50
12
|
end
|
51
13
|
|
52
14
|
describe "#lines=" do
|
53
15
|
it "updates the buffers lines" do
|
54
16
|
buffer.lines = ["one", "two"]
|
55
|
-
expect(buffer.lines).to eq(["one", "two"])
|
17
|
+
expect(buffer.lines.to_a).to eq(["one", "two"])
|
56
18
|
end
|
57
19
|
end
|
58
20
|
end
|
data/spec/neovim/current_spec.rb
CHANGED
@@ -74,5 +74,19 @@ module Neovim
|
|
74
74
|
}.to change { current.tabpage.index }.to(initial_index)
|
75
75
|
end
|
76
76
|
end
|
77
|
+
|
78
|
+
describe "#range" do
|
79
|
+
it "returns the current range" do
|
80
|
+
expect(current.range).to be_a(LineRange)
|
81
|
+
end
|
82
|
+
end
|
83
|
+
|
84
|
+
describe "#range=" do
|
85
|
+
it "sets the current range" do
|
86
|
+
current.buffer.lines = ["1", "2", "3"]
|
87
|
+
current.range = (1..2)
|
88
|
+
expect(current.range.to_a).to eq(["2", "3"])
|
89
|
+
end
|
90
|
+
end
|
77
91
|
end
|
78
92
|
end
|
@@ -5,6 +5,19 @@ require "fileutils"
|
|
5
5
|
|
6
6
|
module Neovim
|
7
7
|
RSpec.describe EventLoop do
|
8
|
+
it "calls the setup callback" do
|
9
|
+
messages = []
|
10
|
+
rd, wr = IO.pipe
|
11
|
+
event_loop = EventLoop.new(rd, wr)
|
12
|
+
|
13
|
+
fiber = Fiber.new do
|
14
|
+
setup_cb = Proc.new { Fiber.yield(:setup) }
|
15
|
+
event_loop.run(nil, setup_cb)
|
16
|
+
end
|
17
|
+
|
18
|
+
expect(fiber.resume).to eq(:setup)
|
19
|
+
end
|
20
|
+
|
8
21
|
shared_context "socket behavior" do
|
9
22
|
it "sends and receives data" do
|
10
23
|
messages = []
|
@@ -14,12 +27,13 @@ module Neovim
|
|
14
27
|
messages << client.readpartial(1024)
|
15
28
|
|
16
29
|
client.write("OK")
|
30
|
+
client.close
|
31
|
+
server.close
|
17
32
|
end
|
18
33
|
|
19
34
|
fiber = Fiber.new do
|
20
|
-
|
21
|
-
|
22
|
-
end
|
35
|
+
msg_cb = Proc.new { |msg| Fiber.yield(msg) }
|
36
|
+
event_loop.send("data").run(msg_cb)
|
23
37
|
end
|
24
38
|
|
25
39
|
expect(fiber.resume).to eq("OK")
|
@@ -44,15 +58,49 @@ module Neovim
|
|
44
58
|
include_context "socket behavior"
|
45
59
|
end
|
46
60
|
|
61
|
+
context "stdio" do
|
62
|
+
it "sends and receives data" do
|
63
|
+
old_stdout = STDOUT.dup
|
64
|
+
old_stdin = STDIN.dup
|
65
|
+
|
66
|
+
begin
|
67
|
+
srv_stdout, cl_stdout = IO.pipe
|
68
|
+
cl_stdin, srv_stdin = IO.pipe
|
69
|
+
|
70
|
+
STDOUT.reopen(cl_stdout)
|
71
|
+
STDIN.reopen(cl_stdin)
|
72
|
+
|
73
|
+
event_loop = EventLoop.stdio
|
74
|
+
messages = []
|
75
|
+
|
76
|
+
srv_thr = Thread.new do
|
77
|
+
messages << srv_stdout.readpartial(1024)
|
78
|
+
srv_stdin.write("OK")
|
79
|
+
end
|
80
|
+
|
81
|
+
fiber = Fiber.new do
|
82
|
+
msg_cb = Proc.new { |msg| Fiber.yield(msg) }
|
83
|
+
event_loop.send("data").run(msg_cb)
|
84
|
+
end
|
85
|
+
|
86
|
+
expect(fiber.resume).to eq("OK")
|
87
|
+
srv_thr.join
|
88
|
+
expect(messages).to eq(["data"])
|
89
|
+
ensure
|
90
|
+
STDOUT.reopen(old_stdout)
|
91
|
+
STDIN.reopen(old_stdin)
|
92
|
+
end
|
93
|
+
end
|
94
|
+
end
|
95
|
+
|
47
96
|
context "child" do
|
48
97
|
it "sends and receives data" do
|
49
98
|
event_loop = EventLoop.child(["-n", "-u", "NONE"])
|
50
99
|
message = MessagePack.pack([0, 0, :vim_strwidth, ["hi"]])
|
51
100
|
|
52
101
|
fiber = Fiber.new do
|
53
|
-
|
54
|
-
|
55
|
-
end
|
102
|
+
msg_cb = Proc.new { |msg| Fiber.yield(msg) }
|
103
|
+
event_loop.send(message).run(msg_cb)
|
56
104
|
end
|
57
105
|
|
58
106
|
expect(fiber.resume).to eq(MessagePack.pack([1, 0, nil, 2]))
|