neovim 0.6.2 → 0.7.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.
Files changed (44) hide show
  1. checksums.yaml +5 -5
  2. data/.gitignore +1 -1
  3. data/.travis.yml +2 -3
  4. data/CHANGELOG.md +29 -0
  5. data/Gemfile +0 -11
  6. data/README.md +3 -3
  7. data/Rakefile +1 -1
  8. data/appveyor.yml +9 -1
  9. data/lib/neovim.rb +3 -3
  10. data/lib/neovim/client.rb +2 -3
  11. data/lib/neovim/connection.rb +69 -0
  12. data/lib/neovim/event_loop.rb +34 -34
  13. data/lib/neovim/host.rb +47 -51
  14. data/lib/neovim/host/loader.rb +1 -4
  15. data/lib/neovim/logging.rb +8 -8
  16. data/lib/neovim/message.rb +70 -0
  17. data/lib/neovim/plugin.rb +0 -3
  18. data/lib/neovim/plugin/handler.rb +6 -6
  19. data/lib/neovim/remote_object.rb +1 -1
  20. data/lib/neovim/ruby_provider.rb +25 -14
  21. data/lib/neovim/session.rb +36 -43
  22. data/lib/neovim/version.rb +1 -1
  23. data/neovim.gemspec +4 -0
  24. data/spec/acceptance/runtime/rplugin/ruby/autocmds.rb +3 -3
  25. data/spec/acceptance/runtime/rplugin/ruby/commands.rb +15 -15
  26. data/spec/acceptance/runtime/rplugin/ruby/functions.rb +5 -5
  27. data/spec/acceptance_spec.rb +19 -16
  28. data/spec/helper.rb +15 -0
  29. data/spec/neovim/connection_spec.rb +79 -0
  30. data/spec/neovim/event_loop_spec.rb +36 -50
  31. data/spec/neovim/host/loader_spec.rb +16 -9
  32. data/spec/neovim/host_spec.rb +82 -92
  33. data/spec/neovim/logging_spec.rb +6 -6
  34. data/spec/neovim/message_spec.rb +119 -0
  35. data/spec/neovim/plugin_spec.rb +31 -31
  36. data/spec/neovim/session_spec.rb +1 -1
  37. metadata +38 -15
  38. data/lib/neovim/event_loop/connection.rb +0 -78
  39. data/lib/neovim/event_loop/message_builder.rb +0 -127
  40. data/lib/neovim/event_loop/serializer.rb +0 -37
  41. data/spec/acceptance/runtime/rplugin.vim +0 -37
  42. data/spec/neovim/event_loop/connection_spec.rb +0 -89
  43. data/spec/neovim/event_loop/message_builder_spec.rb +0 -105
  44. data/spec/neovim/event_loop/serializer_spec.rb +0 -63
@@ -9,18 +9,18 @@ module Neovim
9
9
 
10
10
  let(:host_rd) { push_pipe[0] }
11
11
  let(:host_wr) { pull_pipe[1] }
12
- let(:nvim_rd) { pull_pipe[0] }
13
- let(:nvim_wr) { push_pipe[1] }
12
+ let(:nvim_rd) { MessagePack::Unpacker.new(pull_pipe[0]) }
13
+ let(:nvim_wr) { MessagePack::Packer.new(push_pipe[1]) }
14
14
 
15
15
  let(:plugin_path) do
16
16
  Support.file_path("my_plugin").tap do |path|
17
17
  File.write(path, <<-PLUGIN)
18
18
  Neovim.plugin do |plug|
19
- plug.command(:StrWidth, :nargs => 1, :sync => true) do |client, arg|
20
- arg.bytesize
19
+ plug.command(:Echo, nargs: 1, sync: true) do |client, arg|
20
+ arg
21
21
  end
22
22
 
23
- plug.command(:Boom, :sync => true) do |client|
23
+ plug.command(:Boom, sync: true) do |client|
24
24
  raise "BOOM"
25
25
  end
26
26
 
@@ -33,7 +33,7 @@ module Neovim
33
33
  end
34
34
 
35
35
  let!(:host_thread) do
36
- connection = EventLoop::Connection.new(host_rd, host_wr)
36
+ connection = Connection.new(host_rd, host_wr)
37
37
  event_loop = EventLoop.new(connection)
38
38
 
39
39
  Thread.new do
@@ -41,106 +41,96 @@ module Neovim
41
41
  end
42
42
  end
43
43
 
44
- before do
45
- _, reqid, method = MessagePack.unpack(nvim_rd.readpartial(1024))
46
- expect(method).to eq("nvim_get_api_info")
47
-
48
- session = Session.new(EventLoop.child(Support.child_argv))
49
- api_info = session.request(:nvim_get_api_info)
50
- session.shutdown
51
-
52
- nvim_wr.write(MessagePack.pack([1, reqid, nil, api_info]))
53
- nvim_wr.flush
54
- end
55
-
56
44
  after do
57
- host_thread.kill
45
+ host_thread.kill while host_thread.alive?
58
46
  host_thread.join
59
47
  end
60
48
 
61
- it "responds 'ok' to the 'poll' request" do
62
- message = MessagePack.pack([0, 0, :poll, []])
63
- nvim_wr.write(message)
64
- nvim_wr.flush
49
+ context "poll" do
50
+ it "initializes a client and responds 'ok'" do
51
+ nvim_wr.write([0, 1, :poll, []]).flush
52
+ type, reqid, method = nvim_rd.read
65
53
 
66
- response = MessagePack.unpack(nvim_rd.readpartial(1024))
67
- expect(response).to eq([1, 0, nil, "ok"])
68
- end
54
+ expect(type).to eq(0)
55
+ expect(reqid).to eq(2)
56
+ expect(method).to eq("nvim_get_api_info")
69
57
 
70
- it "responds with specs to the 'specs' request" do
71
- message = MessagePack.pack([0, 0, :specs, [plugin_path]])
72
- nvim_wr.write(message)
73
- nvim_wr.flush
74
-
75
- response = MessagePack.unpack(nvim_rd.readpartial(1024))
76
- expect(response).to eq(
77
- [
78
- 1,
79
- 0,
80
- nil,
81
- [
82
- {
83
- "type" => "command",
84
- "name" => "StrWidth",
85
- "sync" => true,
86
- "opts" => {"nargs" => 1},
87
- },
88
- {
89
- "type" => "command",
90
- "name" => "Boom",
91
- "sync" => true,
92
- "opts" => {},
93
- },
94
- {
95
- "type" => "command",
96
- "name" => "BoomAsync",
97
- "sync" => false,
98
- "opts" => {},
99
- },
100
- ],
101
- ],
102
- )
58
+ api_info = [0, {"types" => {}, "functions" => {}}]
59
+ nvim_wr.write([1, reqid, nil, api_info]).flush
60
+ expect(nvim_rd.read).to eq([1, 1, nil, "ok"])
61
+ end
103
62
  end
104
63
 
105
- it "delegates to plugin handlers" do
106
- message = MessagePack.pack([0, 0, "#{plugin_path}:command:StrWidth", ["hi"]])
107
- nvim_wr.write(message)
108
- nvim_wr.flush
64
+ context "after poll" do
65
+ before do
66
+ nvim_wr.write([0, 1, :poll, []]).flush
67
+ _, reqid, _ = nvim_rd.read
109
68
 
110
- response = MessagePack.unpack(nvim_rd.readpartial(1024))
111
- expect(response).to eq([1, 0, nil, 2])
112
- end
69
+ session = Session.new(EventLoop.child(Support.child_argv))
70
+ api_info = session.request(:nvim_get_api_info)
71
+ session.shutdown
113
72
 
114
- it "handles exceptions in sync plugin handlers" do
115
- message = MessagePack.pack([0, 0, "#{plugin_path}:command:Boom", ["hi"]])
116
- nvim_wr.write(message)
117
- nvim_wr.flush
73
+ nvim_wr.write([1, reqid, nil, api_info]).flush
74
+ nvim_rd.read
75
+ end
118
76
 
119
- response = MessagePack.unpack(nvim_rd.readpartial(1024))
120
- expect(response).to eq([1, 0, "BOOM", nil])
121
- end
77
+ it "responds with specs to the 'specs' request" do
78
+ nvim_wr.write([0, 2, :specs, [plugin_path]]).flush
122
79
 
123
- it "handles exceptions in async plugin handlers" do
124
- message = MessagePack.pack([2, "#{plugin_path}:command:BoomAsync", ["hi"]])
125
- nvim_wr.write(message)
126
- nvim_wr.flush
127
-
128
- message = MessagePack.unpack(nvim_rd.readpartial(1024))
129
- expect(message).to match_array(
130
- [
131
- 0, duck_type(:to_int), "nvim_err_writeln",
132
- [/my_plugin:command:BoomAsync: \(RuntimeError\) BOOM ASYNC/]
133
- ]
134
- )
135
- end
80
+ expect(nvim_rd.read).to eq(
81
+ [
82
+ 1,
83
+ 2,
84
+ nil,
85
+ [
86
+ {
87
+ "type" => "command",
88
+ "name" => "Echo",
89
+ "sync" => true,
90
+ "opts" => {"nargs" => 1},
91
+ },
92
+ {
93
+ "type" => "command",
94
+ "name" => "Boom",
95
+ "sync" => true,
96
+ "opts" => {},
97
+ },
98
+ {
99
+ "type" => "command",
100
+ "name" => "BoomAsync",
101
+ "sync" => false,
102
+ "opts" => {},
103
+ },
104
+ ],
105
+ ],
106
+ )
107
+ end
136
108
 
137
- it "handles unknown requests" do
138
- message = MessagePack.pack([0, 0, "foobar", []])
139
- nvim_wr.write(message)
140
- nvim_wr.flush
109
+ it "delegates to plugin handlers" do
110
+ nvim_wr.write([0, 0, "#{plugin_path}:command:Echo", ["hi"]]).flush
111
+ expect(nvim_rd.read).to eq([1, 0, nil, "hi"])
112
+ end
113
+
114
+ it "handles exceptions in sync plugin handlers" do
115
+ nvim_wr.write([0, 0, "#{plugin_path}:command:Boom", ["hi"]]).flush
116
+ expect(nvim_rd.read).to eq([1, 0, "BOOM", nil])
117
+ end
141
118
 
142
- response = MessagePack.unpack(nvim_rd.readpartial(1024))
143
- expect(response).to eq([1, 0, "Unknown request foobar", nil])
119
+ it "handles exceptions in async plugin handlers" do
120
+ nvim_wr.write([2, "#{plugin_path}:command:BoomAsync", ["hi"]]).flush
121
+
122
+ expect(nvim_rd.read).to match_array(
123
+ [
124
+ 0, duck_type(:to_int), "nvim_err_writeln",
125
+ [/my_plugin:command:BoomAsync: \(RuntimeError\) BOOM ASYNC/]
126
+ ]
127
+ )
128
+ end
129
+
130
+ it "handles unknown requests" do
131
+ nvim_wr.write([0, 0, "foobar", []]).flush
132
+ expect(nvim_rd.read).to eq([1, 0, "Unknown request foobar", nil])
133
+ end
144
134
  end
145
135
  end
146
136
  end
@@ -16,21 +16,21 @@ module Neovim
16
16
 
17
17
  describe ".logger" do
18
18
  it "fetches the output from $NVIM_RUBY_LOG_FILE" do
19
- logger = instance_double(Logger, :level= => nil, :formatter= => nil)
19
+ logger = instance_double(Logger, "level=": nil, "formatter=": nil)
20
20
  expect(Logger).to receive(:new).with("/tmp/nvim.log").and_return(logger)
21
21
  Logging.logger("NVIM_RUBY_LOG_FILE" => "/tmp/nvim.log")
22
22
  expect(Logging.logger).to be(logger)
23
23
  end
24
24
 
25
25
  it "defaults the output to STDERR" do
26
- logger = instance_double(Logger, :level= => nil, :formatter= => nil)
26
+ logger = instance_double(Logger, "level=": nil, "formatter=": nil)
27
27
  expect(Logger).to receive(:new).with(STDERR).and_return(logger)
28
28
  Logging.logger({})
29
29
  expect(Logging.logger).to be(logger)
30
30
  end
31
31
 
32
32
  it "fetches the level from $NVIM_RUBY_LOG_LEVEL as a string" do
33
- logger = instance_double(Logger, :formatter= => nil)
33
+ logger = instance_double(Logger, "formatter=": nil)
34
34
  expect(Logger).to receive(:new).and_return(logger)
35
35
  expect(logger).to receive(:level=).with(Logger::DEBUG)
36
36
  Logging.logger("NVIM_RUBY_LOG_LEVEL" => "DEBUG")
@@ -38,7 +38,7 @@ module Neovim
38
38
  end
39
39
 
40
40
  it "fetches the level from $NVIM_RUBY_LOG_LEVEL as an integer" do
41
- logger = instance_double(Logger, :formatter= => nil)
41
+ logger = instance_double(Logger, "formatter=": nil)
42
42
  expect(Logger).to receive(:new).and_return(logger)
43
43
  expect(logger).to receive(:level=).with(0)
44
44
  Logging.logger("NVIM_RUBY_LOG_LEVEL" => "0")
@@ -46,7 +46,7 @@ module Neovim
46
46
  end
47
47
 
48
48
  it "defaults the level to WARN" do
49
- logger = instance_double(Logger, :formatter= => nil)
49
+ logger = instance_double(Logger, "formatter=": nil)
50
50
  expect(Logger).to receive(:new).and_return(logger)
51
51
  expect(logger).to receive(:level=).with(Logger::WARN)
52
52
  Logging.logger({})
@@ -81,7 +81,7 @@ module Neovim
81
81
 
82
82
  describe "#log" do
83
83
  it "logs JSON at the specified level" do
84
- obj.public_log(:info, :foo => "bar")
84
+ obj.public_log(:info, foo: "bar")
85
85
  logged = MultiJson.decode(log.string)
86
86
 
87
87
  expect(logged).to match(
@@ -0,0 +1,119 @@
1
+ require "helper"
2
+
3
+ module Neovim
4
+ RSpec.describe Message do
5
+ describe ".request" do
6
+ it "builds a request" do
7
+ request = Message.request(1, :method, [1, 2])
8
+
9
+ expect(request).to be_a(Message::Request)
10
+ expect(request.sync?).to eq(true)
11
+ expect(request.id).to eq(1)
12
+ expect(request.method_name).to eq(:method)
13
+ expect(request.arguments).to eq([1, 2])
14
+ end
15
+ end
16
+
17
+ describe ".response" do
18
+ it "builds a response" do
19
+ response = Message.response(1, "error", "value")
20
+
21
+ expect(response).to be_a(Message::Response)
22
+ expect(response.request_id).to eq(1)
23
+ expect(response.error).to eq("error")
24
+ expect(response.value).to eq("value")
25
+ end
26
+ end
27
+
28
+ describe ".notification" do
29
+ it "builds a notification" do
30
+ notification = Message.notification(:method, [1, 2])
31
+
32
+ expect(notification).to be_a(Message::Notification)
33
+ expect(notification.sync?).to eq(false)
34
+ expect(notification.method_name).to eq(:method)
35
+ expect(notification.arguments).to eq([1, 2])
36
+ end
37
+ end
38
+
39
+ describe ".from_array" do
40
+ it "returns a request" do
41
+ request = Message.from_array([0, 1, :method, [1, 2]])
42
+
43
+ expect(request).to be_a(Message::Request)
44
+ expect(request.id).to eq(1)
45
+ expect(request.method_name).to eq(:method)
46
+ expect(request.arguments).to eq([1, 2])
47
+ end
48
+
49
+ it "returns a response" do
50
+ response = Message.from_array([1, 1, [1, "error"], "value"])
51
+
52
+ expect(response).to be_a(Message::Response)
53
+ expect(response.request_id).to eq(1)
54
+ expect(response.error).to eq("error")
55
+ expect(response.value).to eq("value")
56
+ end
57
+
58
+ it "returns a notification" do
59
+ notification = Message.from_array([2, :method, [1, 2]])
60
+
61
+ expect(notification).to be_a(Message::Notification)
62
+ expect(notification.method_name).to eq(:method)
63
+ expect(notification.arguments).to eq([1, 2])
64
+ end
65
+ end
66
+
67
+ describe Message::Request do
68
+ subject { described_class.new(1, :method, [1, 2]) }
69
+
70
+ specify "#to_a" do
71
+ expect(subject.to_a).to eq([0, 1, :method, [1, 2]])
72
+ end
73
+
74
+ describe "#received" do
75
+ it "yields itself to the block" do
76
+ request = Message::Request.new(1, :method, [1, 2])
77
+
78
+ expect do |block|
79
+ request.received({}, &block)
80
+ end.to yield_with_args(request)
81
+ end
82
+ end
83
+ end
84
+
85
+ describe Message::Response do
86
+ subject { described_class.new(2, "error", "result") }
87
+
88
+ specify "#to_a" do
89
+ expect(subject.to_a).to eq([1, 2, "error", "result"])
90
+ end
91
+
92
+ describe "#received" do
93
+ it "yields itself to the response handler" do
94
+ response = Message::Response.new(1, nil, "value")
95
+
96
+ expect do |block|
97
+ response.received(1 => block.to_proc)
98
+ end.to yield_with_args(response)
99
+ end
100
+ end
101
+ end
102
+
103
+ describe Message::Notification do
104
+ subject { described_class.new(:method, [1, 2]) }
105
+
106
+ specify "#to_a" do
107
+ expect(subject.to_a).to eq([2, :method, [1, 2]])
108
+ end
109
+
110
+ describe "#received" do
111
+ it "yields itself to the block" do
112
+ expect do |block|
113
+ subject.received({}, &block)
114
+ end.to yield_with_args(subject)
115
+ end
116
+ end
117
+ end
118
+ end
119
+ end
@@ -5,15 +5,15 @@ module Neovim
5
5
  RSpec.describe Plugin do
6
6
  describe ".from_config_block" do
7
7
  it "registers a command" do
8
- cmd_block = Proc.new {}
8
+ cmd_block = -> {}
9
9
 
10
10
  plugin = Plugin.from_config_block("source") do |plug|
11
11
  plug.command(
12
12
  "Foo",
13
- :nargs => 1,
14
- :range => true,
15
- :bang => true,
16
- :register => true,
13
+ nargs: 1,
14
+ range: true,
15
+ bang: true,
16
+ register: true,
17
17
  &cmd_block
18
18
  )
19
19
  end
@@ -26,23 +26,23 @@ module Neovim
26
26
  expect(handler.block).to eq(cmd_block)
27
27
  expect(handler.qualified_name).to eq("source:command:Foo")
28
28
  expect(handler.to_spec).to eq(
29
- :type => :command,
30
- :name => "Foo",
31
- :sync => false,
32
- :opts => {
33
- :nargs => 1,
34
- :range => "",
35
- :bang => "",
36
- :register => "",
29
+ type: :command,
30
+ name: "Foo",
31
+ sync: false,
32
+ opts: {
33
+ nargs: 1,
34
+ range: "",
35
+ bang: "",
36
+ register: "",
37
37
  },
38
38
  )
39
39
  end
40
40
 
41
41
  it "registers an autocmd" do
42
- au_block = Proc.new {}
42
+ au_block = -> {}
43
43
 
44
44
  plugin = Plugin.from_config_block("source") do |plug|
45
- plug.autocmd("BufEnter", :pattern => "*.rb", &au_block)
45
+ plug.autocmd("BufEnter", pattern: "*.rb", &au_block)
46
46
  end
47
47
 
48
48
  expect(plugin.handlers.size).to be(1)
@@ -53,18 +53,18 @@ module Neovim
53
53
  expect(handler.block).to eq(au_block)
54
54
  expect(handler.qualified_name).to eq("source:autocmd:BufEnter:*.rb")
55
55
  expect(handler.to_spec).to eq(
56
- :type => :autocmd,
57
- :name => "BufEnter",
58
- :sync => false,
59
- :opts => {:pattern => "*.rb"},
56
+ type: :autocmd,
57
+ name: "BufEnter",
58
+ sync: false,
59
+ opts: {pattern: "*.rb"},
60
60
  )
61
61
  end
62
62
 
63
63
  it "registers a function" do
64
- fun_block = Proc.new {}
64
+ fun_block = -> {}
65
65
 
66
66
  plugin = Plugin.from_config_block("source") do |plug|
67
- plug.function("Foo", :range => true, :nargs => 1, &fun_block)
67
+ plug.function("Foo", range: true, nargs: 1, &fun_block)
68
68
  end
69
69
 
70
70
  expect(plugin.handlers.size).to be(1)
@@ -75,10 +75,10 @@ module Neovim
75
75
  expect(handler.block).to eq(fun_block)
76
76
  expect(handler.qualified_name).to eq("source:function:Foo")
77
77
  expect(handler.to_spec).to eq(
78
- :type => :function,
79
- :name => "Foo",
80
- :sync => false,
81
- :opts => {:range => "", :nargs => 1},
78
+ type: :function,
79
+ name: "Foo",
80
+ sync: false,
81
+ opts: {range: "", nargs: 1},
82
82
  )
83
83
  end
84
84
 
@@ -101,7 +101,7 @@ module Neovim
101
101
  end
102
102
 
103
103
  it "registers a top level RPC" do
104
- cmd_block = Proc.new {}
104
+ cmd_block = -> {}
105
105
 
106
106
  plugin = Plugin.from_config_block("source") do |plug|
107
107
  plug.__send__(:rpc, "Foo", &cmd_block)
@@ -120,16 +120,16 @@ module Neovim
120
120
  describe "#specs" do
121
121
  it "returns specs for plugin handlers" do
122
122
  plugin = Plugin.from_config_block("source") do |plug|
123
- plug.command("Foo", :sync => true, :nargs => 2)
123
+ plug.command("Foo", sync: true, nargs: 2)
124
124
  end
125
125
 
126
126
  expect(plugin.specs).to eq(
127
127
  [
128
128
  {
129
- :type => :command,
130
- :name => "Foo",
131
- :sync => true,
132
- :opts=> {:nargs => 2}
129
+ type: :command,
130
+ name: "Foo",
131
+ sync: true,
132
+ opts: {nargs: 2}
133
133
  }
134
134
  ]
135
135
  )