neovim 0.3.0 → 0.3.1
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 +8 -0
- data/Gemfile +1 -0
- data/README.md +6 -2
- data/Rakefile +4 -72
- data/bin/neovim-ruby-host +3 -2
- data/lib/neovim.rb +4 -16
- data/lib/neovim/buffer.rb +21 -0
- data/lib/neovim/client.rb +35 -0
- data/lib/neovim/host.rb +6 -4
- data/lib/neovim/host/loader.rb +2 -0
- data/lib/neovim/line_range.rb +1 -1
- data/lib/neovim/logging.rb +8 -7
- data/lib/neovim/plugin/dsl.rb +1 -1
- data/lib/neovim/ruby_provider.rb +7 -10
- data/lib/neovim/ruby_provider/buffer_ext.rb +3 -3
- data/lib/neovim/ruby_provider/vim.rb +6 -1
- data/lib/neovim/ruby_provider/window_ext.rb +3 -3
- data/lib/neovim/session.rb +2 -2
- data/lib/neovim/session/api.rb +7 -1
- data/lib/neovim/session/event_loop.rb +4 -12
- data/lib/neovim/session/serializer.rb +2 -2
- data/lib/neovim/tabpage.rb +6 -0
- data/lib/neovim/version.rb +1 -1
- data/lib/neovim/window.rb +19 -1
- data/script/generate_docs +71 -0
- data/{bin → script}/j2mp +0 -0
- data/{bin → script}/mp2j +0 -0
- data/spec/acceptance/neovim-ruby-host_spec.rb +1 -6
- data/spec/acceptance/ruby_provider_spec.rb +17 -33
- data/spec/helper.rb +42 -37
- data/spec/neovim/buffer_spec.rb +1 -1
- data/spec/neovim/client_spec.rb +1 -1
- data/spec/neovim/current_spec.rb +1 -1
- data/spec/neovim/host/loader_spec.rb +2 -0
- data/spec/neovim/host_spec.rb +25 -5
- data/spec/neovim/line_range_spec.rb +2 -2
- data/spec/neovim/logging_spec.rb +56 -0
- data/spec/neovim/plugin_spec.rb +9 -0
- data/spec/neovim/remote_object_spec.rb +5 -1
- data/spec/neovim/ruby_provider/buffer_ext_spec.rb +5 -5
- data/spec/neovim/ruby_provider/vim_spec.rb +32 -0
- data/spec/neovim/ruby_provider/window_ext_spec.rb +22 -8
- data/spec/neovim/session/api_spec.rb +24 -5
- data/spec/neovim/session/event_loop_spec.rb +54 -1
- data/spec/neovim/session/notification_spec.rb +20 -0
- data/spec/neovim/session/request_spec.rb +36 -0
- data/spec/neovim/session/rpc_spec.rb +12 -0
- data/spec/neovim/session/serializer_spec.rb +14 -0
- data/spec/neovim/session_spec.rb +4 -4
- data/spec/neovim/window_spec.rb +17 -1
- data/spec/neovim_spec.rb +4 -20
- metadata +13 -4
@@ -2,7 +2,7 @@ require "helper"
|
|
2
2
|
|
3
3
|
module Neovim
|
4
4
|
RSpec.describe RemoteObject do
|
5
|
-
let(:client) { Neovim.attach_child(
|
5
|
+
let(:client) { Neovim.attach_child(Support.child_argv) }
|
6
6
|
after { client.shutdown }
|
7
7
|
|
8
8
|
context Window do
|
@@ -26,6 +26,10 @@ module Neovim
|
|
26
26
|
it "enables window_* function calls" do
|
27
27
|
expect(window.get_cursor).to eq([1, 0])
|
28
28
|
end
|
29
|
+
|
30
|
+
it "falls back to super" do
|
31
|
+
expect { window.foobar }.to raise_error(NoMethodError)
|
32
|
+
end
|
29
33
|
end
|
30
34
|
|
31
35
|
describe "#methods" do
|
@@ -4,21 +4,21 @@ require "neovim/ruby_provider/buffer_ext"
|
|
4
4
|
module Neovim
|
5
5
|
RSpec.describe Buffer do
|
6
6
|
let!(:nvim) do
|
7
|
-
Neovim.attach_child(
|
8
|
-
stub_const("::
|
7
|
+
Neovim.attach_child(Support.child_argv).tap do |nvim|
|
8
|
+
stub_const("::Vim", nvim)
|
9
9
|
end
|
10
10
|
end
|
11
11
|
|
12
12
|
after { nvim.shutdown }
|
13
13
|
|
14
14
|
describe ".current" do
|
15
|
-
it "returns the current buffer from the global
|
15
|
+
it "returns the current buffer from the global Vim client" do
|
16
16
|
expect(Buffer.current).to eq(nvim.get_current_buffer)
|
17
17
|
end
|
18
18
|
end
|
19
19
|
|
20
20
|
describe ".count" do
|
21
|
-
it "returns the current buffer count from the global
|
21
|
+
it "returns the current buffer count from the global Vim client" do
|
22
22
|
expect {
|
23
23
|
nvim.command("new")
|
24
24
|
}.to change { Buffer.count }.by(1)
|
@@ -26,7 +26,7 @@ module Neovim
|
|
26
26
|
end
|
27
27
|
|
28
28
|
describe ".[]" do
|
29
|
-
it "returns the buffer from the global
|
29
|
+
it "returns the buffer from the global Vim client at the given index" do
|
30
30
|
expect(Buffer[0]).to eq(nvim.get_current_buffer)
|
31
31
|
nvim.command("new")
|
32
32
|
expect(Buffer[1]).to eq(nvim.get_current_buffer)
|
@@ -0,0 +1,32 @@
|
|
1
|
+
require "helper"
|
2
|
+
require "neovim/ruby_provider/vim"
|
3
|
+
|
4
|
+
RSpec.describe Vim do
|
5
|
+
describe Vim::Buffer do
|
6
|
+
it "refers to Neovim::Buffer" do
|
7
|
+
expect(Vim::Buffer).to be(Neovim::Buffer)
|
8
|
+
end
|
9
|
+
end
|
10
|
+
|
11
|
+
describe Vim::Window do
|
12
|
+
it "refers to Neovim::Window" do
|
13
|
+
expect(Vim::Window).to be(Neovim::Window)
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
describe VIM do
|
18
|
+
it "is an alias for the Vim module" do
|
19
|
+
expect(VIM).to be(Vim)
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
describe "#method_missing" do
|
24
|
+
it "delegates method calls to @__client" do
|
25
|
+
client = double(:client)
|
26
|
+
expect(client).to receive(:foo).with(1, 2)
|
27
|
+
|
28
|
+
Vim.__client = client
|
29
|
+
Vim.foo(1, 2)
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
@@ -4,32 +4,46 @@ require "neovim/ruby_provider/window_ext"
|
|
4
4
|
module Neovim
|
5
5
|
RSpec.describe Window do
|
6
6
|
let!(:nvim) do
|
7
|
-
Neovim.attach_child(
|
8
|
-
stub_const("::
|
7
|
+
Neovim.attach_child(Support.child_argv).tap do |nvim|
|
8
|
+
stub_const("::Vim", nvim)
|
9
9
|
end
|
10
10
|
end
|
11
11
|
|
12
12
|
after { nvim.shutdown }
|
13
13
|
|
14
14
|
describe ".current" do
|
15
|
-
it "returns the current window from the global
|
15
|
+
it "returns the current window from the global Vim client" do
|
16
16
|
expect(Window.current).to eq(nvim.get_current_window)
|
17
17
|
end
|
18
18
|
end
|
19
19
|
|
20
20
|
describe ".count" do
|
21
|
-
it "returns the current window count from the global
|
21
|
+
it "returns the current window count from the global Vim client" do
|
22
22
|
expect {
|
23
23
|
nvim.command("new")
|
24
24
|
}.to change { Window.count }.by(1)
|
25
25
|
end
|
26
|
+
|
27
|
+
it "only includes windows within a tabpage" do
|
28
|
+
expect {
|
29
|
+
nvim.command("tabnew")
|
30
|
+
}.not_to change { Window.count }.from(1)
|
31
|
+
end
|
26
32
|
end
|
27
33
|
|
28
34
|
describe ".[]" do
|
29
|
-
it "returns the window
|
30
|
-
expect
|
31
|
-
|
32
|
-
|
35
|
+
it "returns the window at the given index" do
|
36
|
+
expect {
|
37
|
+
nvim.command("new")
|
38
|
+
}.to change { Window[1] }.from(nil).to(kind_of(Window))
|
39
|
+
end
|
40
|
+
|
41
|
+
it "only includes windows within a tabpage" do
|
42
|
+
nvim.command("new")
|
43
|
+
|
44
|
+
expect {
|
45
|
+
nvim.command("tabnew")
|
46
|
+
}.to change { Window[1] }.from(kind_of(Window)).to(nil)
|
33
47
|
end
|
34
48
|
end
|
35
49
|
end
|
@@ -13,17 +13,36 @@ module Neovim
|
|
13
13
|
end
|
14
14
|
|
15
15
|
describe "#function" do
|
16
|
-
it "returns a
|
16
|
+
it "returns a sync function object" do
|
17
17
|
api = API.new(
|
18
18
|
[nil, {"functions" => [
|
19
|
-
{"name" => "
|
19
|
+
{"name" => "vim_sync", "async" => false}
|
20
20
|
]}]
|
21
21
|
)
|
22
22
|
|
23
|
-
function = api.function("
|
24
|
-
expect(function).to
|
25
|
-
expect(function.name).to eq("vim_strwidth")
|
23
|
+
function = api.function("vim_sync")
|
24
|
+
expect(function.name).to eq("vim_sync")
|
26
25
|
expect(function.async).to be(false)
|
26
|
+
|
27
|
+
session = instance_double(Session)
|
28
|
+
expect(session).to receive(:request).with("vim_sync", "msg")
|
29
|
+
function.call(session, "msg")
|
30
|
+
end
|
31
|
+
|
32
|
+
it "returns an async function object" do
|
33
|
+
api = API.new(
|
34
|
+
[nil, {"functions" => [
|
35
|
+
{"name" => "vim_async", "async" => true}
|
36
|
+
]}]
|
37
|
+
)
|
38
|
+
|
39
|
+
function = api.function("vim_async")
|
40
|
+
expect(function.name).to eq("vim_async")
|
41
|
+
expect(function.async).to be(true)
|
42
|
+
|
43
|
+
session = instance_double(Session)
|
44
|
+
expect(session).to receive(:notify).with("vim_async", "msg")
|
45
|
+
function.call(session, "msg")
|
27
46
|
end
|
28
47
|
end
|
29
48
|
|
@@ -82,7 +82,7 @@ module Neovim
|
|
82
82
|
|
83
83
|
context "child" do
|
84
84
|
it "sends and receives data" do
|
85
|
-
event_loop = EventLoop.child(
|
85
|
+
event_loop = EventLoop.child(Support.child_argv)
|
86
86
|
input = MessagePack.pack([0, 0, :vim_strwidth, ["hi"]])
|
87
87
|
|
88
88
|
response = nil
|
@@ -94,6 +94,59 @@ module Neovim
|
|
94
94
|
expect(response).to eq(MessagePack.pack([1, 0, nil, 2]))
|
95
95
|
end
|
96
96
|
end
|
97
|
+
|
98
|
+
describe "#run" do
|
99
|
+
it "handles EOF" do
|
100
|
+
rd, wr = IO.pipe
|
101
|
+
wr.close
|
102
|
+
event_loop = EventLoop.new(rd, wr)
|
103
|
+
expect(event_loop).to receive(:info).with(/EOFError/)
|
104
|
+
|
105
|
+
event_loop.run
|
106
|
+
end
|
107
|
+
|
108
|
+
it "handles other errors" do
|
109
|
+
rd, wr = IO.pipe
|
110
|
+
rd.close
|
111
|
+
event_loop = EventLoop.new(rd, wr)
|
112
|
+
expect(event_loop).to receive(:fatal).with(/IOError/)
|
113
|
+
|
114
|
+
event_loop.run
|
115
|
+
end
|
116
|
+
end
|
117
|
+
|
118
|
+
describe "#write" do
|
119
|
+
it "retries when writes would block" do
|
120
|
+
rd, wr = IO.pipe
|
121
|
+
event_loop = EventLoop.new(rd, wr)
|
122
|
+
err_class = Class.new(RuntimeError) { include IO::WaitWritable }
|
123
|
+
|
124
|
+
expect(wr).to receive(:write_nonblock).and_raise(err_class)
|
125
|
+
expect(wr).to receive(:write_nonblock).and_call_original
|
126
|
+
|
127
|
+
event_loop.write("a")
|
128
|
+
expect(rd.readpartial(1)).to eq("a")
|
129
|
+
end
|
130
|
+
end
|
131
|
+
|
132
|
+
describe "#shutdown" do
|
133
|
+
it "closes IO handles" do
|
134
|
+
rd, wr = IO.pipe
|
135
|
+
EventLoop.new(rd, wr).shutdown
|
136
|
+
|
137
|
+
expect(rd).to be_closed
|
138
|
+
expect(wr).to be_closed
|
139
|
+
end
|
140
|
+
|
141
|
+
it "kills spawned processes" do
|
142
|
+
io = IO.popen("cat", "rb+")
|
143
|
+
pid = io.pid
|
144
|
+
expect(pid).to respond_to(:to_int)
|
145
|
+
|
146
|
+
EventLoop.new(io).shutdown
|
147
|
+
expect { Process.kill(0, pid) }.to raise_error(Errno::ESRCH)
|
148
|
+
end
|
149
|
+
end
|
97
150
|
end
|
98
151
|
end
|
99
152
|
end
|
@@ -0,0 +1,20 @@
|
|
1
|
+
require "helper"
|
2
|
+
|
3
|
+
module Neovim
|
4
|
+
class Session
|
5
|
+
RSpec.describe Notification do
|
6
|
+
let(:notification) { Notification.new(:method, ["arg"]) }
|
7
|
+
|
8
|
+
it "has readers" do
|
9
|
+
expect(notification.method_name).to eq("method")
|
10
|
+
expect(notification.arguments).to eq(["arg"])
|
11
|
+
end
|
12
|
+
|
13
|
+
describe "#sync?" do
|
14
|
+
it "is false" do
|
15
|
+
expect(notification.sync?).to be(false)
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
@@ -0,0 +1,36 @@
|
|
1
|
+
require "helper"
|
2
|
+
|
3
|
+
module Neovim
|
4
|
+
class Session
|
5
|
+
RSpec.describe Request do
|
6
|
+
let(:serializer) { double(:serializer) }
|
7
|
+
let(:reqid) { 1 }
|
8
|
+
let(:request) { Request.new(:method, ["arg"], serializer, reqid) }
|
9
|
+
|
10
|
+
it "has readers" do
|
11
|
+
expect(request.method_name).to eq("method")
|
12
|
+
expect(request.arguments).to eq(["arg"])
|
13
|
+
end
|
14
|
+
|
15
|
+
describe "#sync?" do
|
16
|
+
it "is true" do
|
17
|
+
expect(request.sync?).to be(true)
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
describe "#respond" do
|
22
|
+
it "writes an RPC response to serializer" do
|
23
|
+
expect(serializer).to receive(:write).with([1, reqid, nil, "val"])
|
24
|
+
request.respond("val")
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
describe "#error" do
|
29
|
+
it "writes an RPC error response to serializer" do
|
30
|
+
expect(serializer).to receive(:write).with([1, reqid, "err", nil])
|
31
|
+
request.error("err")
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
@@ -103,6 +103,18 @@ module Neovim
|
|
103
103
|
|
104
104
|
include_context "rpc behavior"
|
105
105
|
end
|
106
|
+
|
107
|
+
describe "#run" do
|
108
|
+
it "logs exceptions" do
|
109
|
+
serializer = instance_double(Serializer)
|
110
|
+
rpc = RPC.new(serializer)
|
111
|
+
|
112
|
+
expect(serializer).to receive(:run).and_raise("BOOM")
|
113
|
+
expect(rpc).to receive(:fatal).with(/BOOM/)
|
114
|
+
|
115
|
+
rpc.run
|
116
|
+
end
|
117
|
+
end
|
106
118
|
end
|
107
119
|
end
|
108
120
|
end
|
@@ -43,6 +43,20 @@ module Neovim
|
|
43
43
|
|
44
44
|
include_context "serializer behavior"
|
45
45
|
end
|
46
|
+
|
47
|
+
describe "#run" do
|
48
|
+
it "logs exceptions" do
|
49
|
+
unpacker = instance_double(MessagePack::Unpacker)
|
50
|
+
event_loop = instance_double(EventLoop)
|
51
|
+
serializer = Serializer.new(event_loop, unpacker)
|
52
|
+
|
53
|
+
expect(event_loop).to receive(:run).and_yield("data")
|
54
|
+
expect(unpacker).to receive(:feed_each).with("data").and_raise("BOOM")
|
55
|
+
expect(serializer).to receive(:fatal).with(/BOOM/)
|
56
|
+
|
57
|
+
serializer.run
|
58
|
+
end
|
59
|
+
end
|
46
60
|
end
|
47
61
|
end
|
48
62
|
end
|
data/spec/neovim/session_spec.rb
CHANGED
@@ -95,11 +95,11 @@ module Neovim
|
|
95
95
|
end
|
96
96
|
|
97
97
|
context "tcp" do
|
98
|
-
let!(:nvim_port) { Support.
|
98
|
+
let!(:nvim_port) { Support.tcp_port }
|
99
99
|
let!(:nvim_pid) do
|
100
100
|
pid = Process.spawn(
|
101
101
|
{"NVIM_LISTEN_ADDRESS" => "0.0.0.0:#{nvim_port}"},
|
102
|
-
"
|
102
|
+
Support.child_argv.join(" "),
|
103
103
|
[:out, :err] => "/dev/null"
|
104
104
|
)
|
105
105
|
|
@@ -126,7 +126,7 @@ module Neovim
|
|
126
126
|
let!(:nvim_pid) do
|
127
127
|
pid = Process.spawn(
|
128
128
|
{"NVIM_LISTEN_ADDRESS" => socket_path},
|
129
|
-
"
|
129
|
+
Support.child_argv.join(" "),
|
130
130
|
[:out, :err] => "/dev/null"
|
131
131
|
)
|
132
132
|
|
@@ -149,7 +149,7 @@ module Neovim
|
|
149
149
|
end
|
150
150
|
|
151
151
|
context "child" do
|
152
|
-
let!(:session) { Session.child(
|
152
|
+
let!(:session) { Session.child(Support.child_argv) }
|
153
153
|
include_context "session behavior"
|
154
154
|
after { session.shutdown }
|
155
155
|
end
|
data/spec/neovim/window_spec.rb
CHANGED
@@ -2,7 +2,7 @@ require "helper"
|
|
2
2
|
|
3
3
|
module Neovim
|
4
4
|
RSpec.describe Window do
|
5
|
-
let(:client) { Neovim.attach_child(
|
5
|
+
let(:client) { Neovim.attach_child(Support.child_argv) }
|
6
6
|
let(:window) { client.current.window }
|
7
7
|
after { client.shutdown }
|
8
8
|
|
@@ -69,6 +69,22 @@ module Neovim
|
|
69
69
|
client.command("normal ix")
|
70
70
|
}.to change { client.current.line }.to("oxne")
|
71
71
|
end
|
72
|
+
|
73
|
+
it "supports out of range indexes" do
|
74
|
+
window.buffer.lines = ["x", "xx"]
|
75
|
+
|
76
|
+
expect {
|
77
|
+
window.cursor = [10, 10]
|
78
|
+
}.to change { window.cursor }.to([2, 1])
|
79
|
+
|
80
|
+
expect {
|
81
|
+
window.cursor = [0, -1]
|
82
|
+
}.to change { window.cursor }.to([1, 0])
|
83
|
+
end
|
84
|
+
|
85
|
+
it "returns the cursor array" do
|
86
|
+
expect(window.cursor = [10, 10]).to eq([10, 10])
|
87
|
+
end
|
72
88
|
end
|
73
89
|
end
|
74
90
|
end
|
data/spec/neovim_spec.rb
CHANGED
@@ -1,13 +1,11 @@
|
|
1
1
|
require "helper"
|
2
2
|
|
3
3
|
RSpec.describe Neovim do
|
4
|
-
let(:nvim_argv) { %w(nvim --headless -u NONE -i NONE -n) }
|
5
|
-
|
6
4
|
describe ".attach_tcp" do
|
7
5
|
it "attaches to a TCP socket" do
|
8
|
-
port = Support.
|
6
|
+
port = Support.tcp_port
|
9
7
|
env = {"NVIM_LISTEN_ADDRESS" => "0.0.0.0:#{port}"}
|
10
|
-
pid = Process.spawn(env, *
|
8
|
+
pid = Process.spawn(env, *Support.child_argv, [:out, :err] => "/dev/null")
|
11
9
|
|
12
10
|
begin
|
13
11
|
client = Neovim.attach_tcp("0.0.0.0", port)
|
@@ -28,7 +26,7 @@ RSpec.describe Neovim do
|
|
28
26
|
it "attaches to a UNIX socket" do
|
29
27
|
socket_path = Support.socket_path
|
30
28
|
env = {"NVIM_LISTEN_ADDRESS" => socket_path}
|
31
|
-
pid = Process.spawn(env, *
|
29
|
+
pid = Process.spawn(env, *Support.child_argv, [:out, :err] => "/dev/null")
|
32
30
|
|
33
31
|
begin
|
34
32
|
client = Neovim.attach_unix(socket_path)
|
@@ -48,25 +46,11 @@ RSpec.describe Neovim do
|
|
48
46
|
describe ".attach_child" do
|
49
47
|
it "spawns and attaches to a child process" do
|
50
48
|
begin
|
51
|
-
client = Neovim.attach_child(
|
49
|
+
client = Neovim.attach_child(Support.child_argv)
|
52
50
|
expect(client.strwidth("hi")).to eq(2)
|
53
51
|
ensure
|
54
52
|
client.shutdown
|
55
53
|
end
|
56
54
|
end
|
57
55
|
end
|
58
|
-
|
59
|
-
describe ".start_host" do
|
60
|
-
it "loads and runs a Host" do
|
61
|
-
paths = ["/foo", "/bar"]
|
62
|
-
host = double(:host)
|
63
|
-
|
64
|
-
expect(Neovim::Host).to receive(:load_from_files).
|
65
|
-
with(paths).
|
66
|
-
and_return(host)
|
67
|
-
|
68
|
-
expect(host).to receive(:run)
|
69
|
-
Neovim.start_host(paths)
|
70
|
-
end
|
71
|
-
end
|
72
56
|
end
|