neovim 0.6.2 → 0.7.0

Sign up to get free protection for your applications and to get access to all the features.
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
  )