neovim 0.6.2 → 0.7.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +5 -5
- data/.gitignore +1 -1
- data/.travis.yml +2 -3
- data/CHANGELOG.md +29 -0
- data/Gemfile +0 -11
- data/README.md +3 -3
- data/Rakefile +1 -1
- data/appveyor.yml +9 -1
- data/lib/neovim.rb +3 -3
- data/lib/neovim/client.rb +2 -3
- data/lib/neovim/connection.rb +69 -0
- data/lib/neovim/event_loop.rb +34 -34
- data/lib/neovim/host.rb +47 -51
- data/lib/neovim/host/loader.rb +1 -4
- data/lib/neovim/logging.rb +8 -8
- data/lib/neovim/message.rb +70 -0
- data/lib/neovim/plugin.rb +0 -3
- data/lib/neovim/plugin/handler.rb +6 -6
- data/lib/neovim/remote_object.rb +1 -1
- data/lib/neovim/ruby_provider.rb +25 -14
- data/lib/neovim/session.rb +36 -43
- data/lib/neovim/version.rb +1 -1
- data/neovim.gemspec +4 -0
- data/spec/acceptance/runtime/rplugin/ruby/autocmds.rb +3 -3
- data/spec/acceptance/runtime/rplugin/ruby/commands.rb +15 -15
- data/spec/acceptance/runtime/rplugin/ruby/functions.rb +5 -5
- data/spec/acceptance_spec.rb +19 -16
- data/spec/helper.rb +15 -0
- data/spec/neovim/connection_spec.rb +79 -0
- data/spec/neovim/event_loop_spec.rb +36 -50
- data/spec/neovim/host/loader_spec.rb +16 -9
- data/spec/neovim/host_spec.rb +82 -92
- data/spec/neovim/logging_spec.rb +6 -6
- data/spec/neovim/message_spec.rb +119 -0
- data/spec/neovim/plugin_spec.rb +31 -31
- data/spec/neovim/session_spec.rb +1 -1
- metadata +38 -15
- data/lib/neovim/event_loop/connection.rb +0 -78
- data/lib/neovim/event_loop/message_builder.rb +0 -127
- data/lib/neovim/event_loop/serializer.rb +0 -37
- data/spec/acceptance/runtime/rplugin.vim +0 -37
- data/spec/neovim/event_loop/connection_spec.rb +0 -89
- data/spec/neovim/event_loop/message_builder_spec.rb +0 -105
- data/spec/neovim/event_loop/serializer_spec.rb +0 -63
data/lib/neovim/version.rb
CHANGED
data/neovim.gemspec
CHANGED
@@ -17,11 +17,15 @@ Gem::Specification.new do |spec|
|
|
17
17
|
spec.test_files = spec.files.grep(%r{^spec/})
|
18
18
|
spec.require_paths = ["lib"]
|
19
19
|
|
20
|
+
spec.required_ruby_version = Gem::Requirement.new(">= 2.2.0")
|
21
|
+
|
20
22
|
spec.add_dependency "msgpack", "~> 1.1"
|
21
23
|
spec.add_dependency "multi_json", "~> 1.0"
|
22
24
|
|
23
25
|
spec.add_development_dependency "bundler"
|
24
26
|
spec.add_development_dependency "rake"
|
25
27
|
spec.add_development_dependency "pry"
|
28
|
+
spec.add_development_dependency "pry-byebug"
|
29
|
+
spec.add_development_dependency "coveralls"
|
26
30
|
spec.add_development_dependency "rspec", "~> 3.0"
|
27
31
|
end
|
@@ -1,9 +1,9 @@
|
|
1
1
|
Neovim.plugin do |plug|
|
2
|
-
plug.autocmd(:BufEnter, :
|
2
|
+
plug.autocmd(:BufEnter, pattern: "*.rb") do |nvim|
|
3
3
|
nvim.get_current_buf.set_var("rplugin_autocmd_BufEnter", true)
|
4
4
|
end
|
5
5
|
|
6
|
-
plug.autocmd(:BufEnter, :
|
7
|
-
nvim.set_var("rplugin_autocmd_BufEnter_eval", to_eval.merge(:
|
6
|
+
plug.autocmd(:BufEnter, pattern: "*.c", eval: "g:to_eval") do |nvim, to_eval|
|
7
|
+
nvim.set_var("rplugin_autocmd_BufEnter_eval", to_eval.merge(b: 43))
|
8
8
|
end
|
9
9
|
end
|
@@ -3,61 +3,61 @@ Neovim.plugin do |plug|
|
|
3
3
|
nvim.set_var("rplugin_command_nargs_0", true)
|
4
4
|
end
|
5
5
|
|
6
|
-
plug.command(:RPluginCommandNargs1, :
|
6
|
+
plug.command(:RPluginCommandNargs1, nargs: 1) do |nvim, arg|
|
7
7
|
nvim.set_var("rplugin_command_nargs_1", arg)
|
8
8
|
end
|
9
9
|
|
10
|
-
plug.command(:RPluginCommandNargsN, :
|
10
|
+
plug.command(:RPluginCommandNargsN, nargs: "*") do |nvim, *args|
|
11
11
|
nvim.set_var("rplugin_command_nargs_n", args)
|
12
12
|
end
|
13
13
|
|
14
|
-
plug.command(:RPluginCommandNargsQ, :
|
14
|
+
plug.command(:RPluginCommandNargsQ, nargs: "?") do |nvim, arg|
|
15
15
|
nvim.set_var("rplugin_command_nargs_q", arg)
|
16
16
|
end
|
17
17
|
|
18
|
-
plug.command(:RPluginCommandNargsP, :
|
18
|
+
plug.command(:RPluginCommandNargsP, nargs: "+") do |nvim, *args|
|
19
19
|
nvim.set_var("rplugin_command_nargs_p", args)
|
20
20
|
end
|
21
21
|
|
22
|
-
plug.command(:RPluginCommandRange, :
|
22
|
+
plug.command(:RPluginCommandRange, range: true) do |nvim, *range|
|
23
23
|
nvim.set_var("rplugin_command_range", range)
|
24
24
|
end
|
25
25
|
|
26
|
-
plug.command(:RPluginCommandRangeP, :
|
26
|
+
plug.command(:RPluginCommandRangeP, range: "%") do |nvim, *range|
|
27
27
|
nvim.set_var("rplugin_command_range_p", range)
|
28
28
|
end
|
29
29
|
|
30
|
-
plug.command(:RPluginCommandRangeN, :
|
30
|
+
plug.command(:RPluginCommandRangeN, range: 1) do |nvim, *range|
|
31
31
|
nvim.set_var("rplugin_command_range_n", range)
|
32
32
|
end
|
33
33
|
|
34
|
-
plug.command(:RPluginCommandCountN, :
|
34
|
+
plug.command(:RPluginCommandCountN, count: 1) do |nvim, *count|
|
35
35
|
nvim.set_var("rplugin_command_count_n", count)
|
36
36
|
end
|
37
37
|
|
38
|
-
plug.command(:RPluginCommandBang, :
|
38
|
+
plug.command(:RPluginCommandBang, bang: true) do |nvim, bang|
|
39
39
|
nvim.set_var("rplugin_command_bang", bang)
|
40
40
|
end
|
41
41
|
|
42
|
-
plug.command(:RPluginCommandRegister, :
|
42
|
+
plug.command(:RPluginCommandRegister, register: true) do |nvim, reg|
|
43
43
|
nvim.set_var("rplugin_command_register", reg)
|
44
44
|
end
|
45
45
|
|
46
|
-
plug.command(:RPluginCommandCompletion, :
|
46
|
+
plug.command(:RPluginCommandCompletion, complete: "buffer") do |nvim|
|
47
47
|
attrs = nvim.command_output("silent command RPluginCommandCompletion")
|
48
48
|
compl = attrs.split($/).last.split[2]
|
49
49
|
nvim.set_var("rplugin_command_completion", compl)
|
50
50
|
end
|
51
51
|
|
52
|
-
plug.command(:RPluginCommandEval, :
|
53
|
-
nvim.set_var("rplugin_command_eval", to_eval.merge(:
|
52
|
+
plug.command(:RPluginCommandEval, eval: "g:to_eval") do |nvim, to_eval|
|
53
|
+
nvim.set_var("rplugin_command_eval", to_eval.merge(b: 43))
|
54
54
|
end
|
55
55
|
|
56
|
-
plug.command(:RPluginCommandSync, :
|
56
|
+
plug.command(:RPluginCommandSync, sync: true) do |nvim|
|
57
57
|
nvim.set_var("rplugin_command_sync", true)
|
58
58
|
end
|
59
59
|
|
60
|
-
plug.command(:RPluginCommandRecursive, :
|
60
|
+
plug.command(:RPluginCommandRecursive, sync: true, nargs: 1) do |nvim, n|
|
61
61
|
if Integer(n) >= 10
|
62
62
|
nvim.set_var("rplugin_command_recursive", n)
|
63
63
|
else
|
@@ -3,19 +3,19 @@ Neovim.plugin do |plug|
|
|
3
3
|
nvim.set_var("rplugin_function_args", args)
|
4
4
|
end
|
5
5
|
|
6
|
-
plug.function(:RPluginFunctionRange, :
|
6
|
+
plug.function(:RPluginFunctionRange, range: true) do |nvim, *range|
|
7
7
|
nvim.set_var("rplugin_function_range", range)
|
8
8
|
end
|
9
9
|
|
10
|
-
plug.function(:RPluginFunctionEval, :
|
11
|
-
nvim.set_var("rplugin_function_eval", to_eval.merge(:
|
10
|
+
plug.function(:RPluginFunctionEval, eval: "g:to_eval") do |nvim, to_eval|
|
11
|
+
nvim.set_var("rplugin_function_eval", to_eval.merge(b: 43))
|
12
12
|
end
|
13
13
|
|
14
|
-
plug.function(:RPluginFunctionSync, :
|
14
|
+
plug.function(:RPluginFunctionSync, sync: true) do |nvim|
|
15
15
|
true
|
16
16
|
end
|
17
17
|
|
18
|
-
plug.function(:RPluginFunctionRecursive, :
|
18
|
+
plug.function(:RPluginFunctionRecursive, sync: true, nargs: 1) do |nvim, n|
|
19
19
|
if n >= 10
|
20
20
|
n
|
21
21
|
else
|
data/spec/acceptance_spec.rb
CHANGED
@@ -3,10 +3,11 @@ ENV.delete("VIMRUNTIME")
|
|
3
3
|
|
4
4
|
require "json"
|
5
5
|
require "net/http"
|
6
|
+
require "openssl"
|
6
7
|
require "open-uri"
|
7
8
|
require "tempfile"
|
8
9
|
|
9
|
-
RSpec.describe "Acceptance", :
|
10
|
+
RSpec.describe "Acceptance", timeout: 10 do
|
10
11
|
let(:root) { File.expand_path("../acceptance", __FILE__) }
|
11
12
|
let(:init) { File.join(root, "runtime/init.vim") }
|
12
13
|
let(:manifest) { File.join(root, "runtime/rplugin.vim") }
|
@@ -19,7 +20,7 @@ RSpec.describe "Acceptance", :timeout => 10 do
|
|
19
20
|
["ruby", "rubyfile", "rubydo"].each do |feature|
|
20
21
|
specify ":#{feature}" do
|
21
22
|
run_vader("#{feature}_spec.vim") do |status, output|
|
22
|
-
expect(status).to be_success,
|
23
|
+
expect(status).to be_success, -> { output.read }
|
23
24
|
end
|
24
25
|
end
|
25
26
|
end
|
@@ -36,7 +37,7 @@ RSpec.describe "Acceptance", :timeout => 10 do
|
|
36
37
|
["command", "function", "autocmd"].each do |feature|
|
37
38
|
specify "##{feature}" do
|
38
39
|
run_vader("rplugin_#{feature}_spec.vim") do |status, output|
|
39
|
-
expect(status).to be_success,
|
40
|
+
expect(status).to be_success, -> { output.read }
|
40
41
|
end
|
41
42
|
end
|
42
43
|
end
|
@@ -44,23 +45,25 @@ RSpec.describe "Acceptance", :timeout => 10 do
|
|
44
45
|
|
45
46
|
describe "Generated documentation" do
|
46
47
|
it "is up to date" do
|
48
|
+
url = "https://api.github.com/repos/neovim/neovim/releases/latest"
|
49
|
+
|
47
50
|
begin
|
48
|
-
url = "https://api.github.com/repos/neovim/neovim/releases/latest"
|
49
51
|
response = open(url) { |json| JSON.load(json) }
|
50
|
-
|
51
|
-
|
52
|
-
client_file = File.read(
|
53
|
-
File.expand_path("../../lib/neovim/client.rb", __FILE__)
|
54
|
-
)
|
55
|
-
docs_version = client_file[
|
56
|
-
/The methods documented here were generated using NVIM v?(.+)$/,
|
57
|
-
1
|
58
|
-
]
|
59
|
-
|
60
|
-
expect(docs_version).to eq(release_version)
|
61
|
-
rescue SocketError, OpenURI::HTTPError => e
|
52
|
+
rescue SocketError, OpenURI::HTTPError, OpenSSL::SSL::SSLError => e
|
62
53
|
skip "Skipping: #{e}"
|
63
54
|
end
|
55
|
+
|
56
|
+
release_version = response["name"][/NVIM v?(.+)$/, 1]
|
57
|
+
|
58
|
+
client_file = File.read(
|
59
|
+
File.expand_path("../../lib/neovim/client.rb", __FILE__)
|
60
|
+
)
|
61
|
+
docs_version = client_file[
|
62
|
+
/The methods documented here were generated using NVIM v?(.+)$/,
|
63
|
+
1
|
64
|
+
]
|
65
|
+
|
66
|
+
expect(docs_version).to eq(release_version)
|
64
67
|
end
|
65
68
|
end
|
66
69
|
|
data/spec/helper.rb
CHANGED
@@ -25,6 +25,21 @@ RSpec.configure do |config|
|
|
25
25
|
config.order = :random
|
26
26
|
config.color = true
|
27
27
|
|
28
|
+
config.around(:example, :silence_thread_exceptions) do |spec|
|
29
|
+
if Thread.respond_to?(:report_on_exception)
|
30
|
+
original = Thread.report_on_exception
|
31
|
+
|
32
|
+
begin
|
33
|
+
Thread.report_on_exception = false
|
34
|
+
spec.run
|
35
|
+
ensure
|
36
|
+
Thread.report_on_exception = original
|
37
|
+
end
|
38
|
+
else
|
39
|
+
spec.run
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
28
43
|
config.around(:example) do |spec|
|
29
44
|
Support.setup_workspace
|
30
45
|
timeout = spec.metadata.fetch(:timeout, 3)
|
@@ -0,0 +1,79 @@
|
|
1
|
+
require "helper"
|
2
|
+
|
3
|
+
module Neovim
|
4
|
+
RSpec.describe Connection do
|
5
|
+
let(:nil_io) { StringIO.new }
|
6
|
+
|
7
|
+
describe "#write" do
|
8
|
+
it "writes msgpack to the underlying file descriptor" do
|
9
|
+
rd, wr = IO.pipe
|
10
|
+
connection = Connection.new(nil_io, wr)
|
11
|
+
connection.write("some data")
|
12
|
+
wr.close
|
13
|
+
|
14
|
+
expect(MessagePack.unpack(rd.read)).to eq("some data")
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
describe "#read" do
|
19
|
+
it "reads msgpack from the underlying file descriptor" do
|
20
|
+
rd, wr = IO.pipe
|
21
|
+
wr.write(MessagePack.pack("some data"))
|
22
|
+
wr.close
|
23
|
+
|
24
|
+
connection = Connection.new(rd, nil_io)
|
25
|
+
expect(connection.read).to eq("some data")
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
describe "#register_type" do
|
30
|
+
it "registers a msgpack ext type" do
|
31
|
+
ext_class = Struct.new(:id) do
|
32
|
+
def self.from_msgpack_ext(data)
|
33
|
+
new(data.unpack('N')[0])
|
34
|
+
end
|
35
|
+
|
36
|
+
def to_msgpack_ext
|
37
|
+
[self.id].pack('C')
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
client_rd, server_wr = IO.pipe
|
42
|
+
server_rd, client_wr = IO.pipe
|
43
|
+
|
44
|
+
connection = Connection.new(client_rd, client_wr)
|
45
|
+
|
46
|
+
connection.register_type(42) do |id|
|
47
|
+
ext_class.new(id)
|
48
|
+
end
|
49
|
+
|
50
|
+
factory = MessagePack::Factory.new
|
51
|
+
factory.register_type(42, ext_class)
|
52
|
+
obj = ext_class.new(1)
|
53
|
+
factory.packer(server_wr).write(obj).flush
|
54
|
+
|
55
|
+
expect(connection.read).to eq(obj)
|
56
|
+
end
|
57
|
+
end
|
58
|
+
|
59
|
+
|
60
|
+
describe "#close" do
|
61
|
+
it "closes IO handles" do
|
62
|
+
rd, wr = ::IO.pipe
|
63
|
+
Connection.new(rd, wr).close
|
64
|
+
|
65
|
+
expect(rd).to be_closed
|
66
|
+
expect(wr).to be_closed
|
67
|
+
end
|
68
|
+
|
69
|
+
it "kills spawned processes" do
|
70
|
+
io = ::IO.popen("cat", "rb+")
|
71
|
+
pid = io.pid
|
72
|
+
expect(pid).to respond_to(:to_int)
|
73
|
+
|
74
|
+
Connection.new(io, nil_io).close
|
75
|
+
expect { Process.kill(0, pid) }.to raise_error(Errno::ESRCH)
|
76
|
+
end
|
77
|
+
end
|
78
|
+
end
|
79
|
+
end
|
@@ -10,71 +10,57 @@ module Neovim
|
|
10
10
|
let(:server_rd) { pull_pipe[0] }
|
11
11
|
let(:server_wr) { push_pipe[1] }
|
12
12
|
|
13
|
-
let(:connection) {
|
13
|
+
let(:connection) { Connection.new(client_rd, client_wr) }
|
14
14
|
let(:event_loop) { EventLoop.new(connection) }
|
15
15
|
|
16
|
-
describe "#
|
17
|
-
it "
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
request = nil
|
22
|
-
event_loop.run do |req|
|
23
|
-
request = req
|
24
|
-
event_loop.stop
|
25
|
-
end
|
26
|
-
expect(request.method_name).to eq("foo_method")
|
16
|
+
describe "#request" do
|
17
|
+
it "writes a msgpack request" do
|
18
|
+
event_loop.request(1, :method, 1, 2)
|
19
|
+
message = server_rd.readpartial(1024)
|
20
|
+
expect(message).to eq(MessagePack.pack([0, 1, "method", [1, 2]]))
|
27
21
|
end
|
22
|
+
end
|
28
23
|
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
event_loop.stop
|
35
|
-
end
|
36
|
-
|
37
|
-
server_wr.write(MessagePack.pack([1, 1, nil, :value]))
|
38
|
-
server_wr.flush
|
39
|
-
|
40
|
-
event_loop.run
|
41
|
-
expect(response.value!).to eq("value")
|
24
|
+
describe "#respond" do
|
25
|
+
it "writes a msgpack response" do
|
26
|
+
event_loop.respond(2, "value", "error")
|
27
|
+
message = server_rd.readpartial(1024)
|
28
|
+
expect(message).to eq(MessagePack.pack([1, 2, "error", "value"]))
|
42
29
|
end
|
30
|
+
end
|
43
31
|
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
event_loop.run { event_loop.stop }
|
51
|
-
expect(server_rd.readpartial(1024)).to eq(
|
52
|
-
MessagePack.pack([1, 1, nil, :foo_response])
|
53
|
-
)
|
32
|
+
describe "#notify" do
|
33
|
+
it "writes a msgpack notification" do
|
34
|
+
event_loop.notify(:method, 1, 2)
|
35
|
+
message = server_rd.readpartial(1024)
|
36
|
+
expect(message).to eq(MessagePack.pack([2, "method", [1, 2]]))
|
54
37
|
end
|
38
|
+
end
|
55
39
|
|
56
|
-
|
57
|
-
|
40
|
+
describe "#run" do
|
41
|
+
it "yields received messages to the block" do
|
42
|
+
server_wr.write(MessagePack.pack([0, 1, :foo_method, []]))
|
58
43
|
server_wr.flush
|
59
44
|
|
60
|
-
|
61
|
-
event_loop.run do |
|
62
|
-
|
45
|
+
message = nil
|
46
|
+
event_loop.run do |req|
|
47
|
+
message = req
|
63
48
|
event_loop.stop
|
64
49
|
end
|
65
|
-
expect(notification.method_name).to eq("foo_notification")
|
66
|
-
end
|
67
50
|
|
68
|
-
|
69
|
-
|
51
|
+
expect(message.sync?).to eq(true)
|
52
|
+
expect(message.method_name).to eq("foo_method")
|
53
|
+
end
|
70
54
|
|
71
|
-
|
72
|
-
|
55
|
+
it "shuts down after receiving EOFError" do
|
56
|
+
run_thread = Thread.new do
|
57
|
+
event_loop.run
|
58
|
+
end
|
73
59
|
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
)
|
60
|
+
server_wr.close
|
61
|
+
run_thread.join
|
62
|
+
expect(client_rd).to be_closed
|
63
|
+
expect(client_wr).to be_closed
|
78
64
|
end
|
79
65
|
end
|
80
66
|
end
|
@@ -6,7 +6,7 @@ module Neovim
|
|
6
6
|
RSpec.describe Loader do
|
7
7
|
describe "#load" do
|
8
8
|
let(:plugin_path) { Support.file_path("plug.rb") }
|
9
|
-
let(:host) { instance_double(Host, :
|
9
|
+
let(:host) { instance_double(Host, plugins: []) }
|
10
10
|
let(:loader) { Loader.new(host) }
|
11
11
|
|
12
12
|
before do
|
@@ -14,26 +14,33 @@ module Neovim
|
|
14
14
|
end
|
15
15
|
|
16
16
|
it "registers plugins defined in the provided files" do
|
17
|
-
expect
|
18
|
-
|
17
|
+
expect do
|
18
|
+
loader.load([plugin_path])
|
19
|
+
end.to change { host.plugins.size }.by(1)
|
19
20
|
end
|
20
21
|
|
21
22
|
it "registers multiple plugins defined in the provided files" do
|
22
23
|
File.write(plugin_path, "Neovim.plugin; Neovim.plugin")
|
23
|
-
|
24
|
-
|
24
|
+
|
25
|
+
expect do
|
26
|
+
loader.load([plugin_path])
|
27
|
+
end.to change { host.plugins.size }.by(2)
|
25
28
|
end
|
26
29
|
|
27
30
|
it "doesn't register plugins when none are defined" do
|
28
31
|
File.write(plugin_path, "class FooClass; end")
|
29
|
-
|
30
|
-
|
32
|
+
|
33
|
+
expect do
|
34
|
+
loader.load([plugin_path])
|
35
|
+
end.not_to change { host.plugins.size }
|
31
36
|
end
|
32
37
|
|
33
38
|
it "doesn't leak constants defined in plugins" do
|
34
39
|
File.write(plugin_path, "class FooClass; end")
|
35
|
-
|
36
|
-
expect
|
40
|
+
|
41
|
+
expect do
|
42
|
+
loader.load([plugin_path])
|
43
|
+
end.not_to change { Kernel.const_defined?(:FooClass) }.from(false)
|
37
44
|
end
|
38
45
|
|
39
46
|
it "doesn't leak the overidden Neovim.plugin method" do
|