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.
@@ -23,17 +23,14 @@ module Neovim
23
23
  self
24
24
  end
25
25
 
26
- def run(&message_cb)
27
- @event_loop.run do |data|
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
- def stop
35
- @event_loop.stop
36
- self
33
+ @event_loop.run(data_cb, setup_cb)
37
34
  end
38
35
  end
39
36
  end
@@ -3,8 +3,12 @@ module Neovim
3
3
  attr_reader :method_name, :arguments
4
4
 
5
5
  def initialize(method_name, args)
6
- @method_name = method_name.to_sym
6
+ @method_name = method_name.to_s
7
7
  @arguments = args
8
8
  end
9
+
10
+ def sync?
11
+ false
12
+ end
9
13
  end
10
14
  end
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 :specs
9
+ attr_accessor :handlers
10
+ attr_reader :source
10
11
 
11
- def initialize
12
- @specs = []
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, _options={}, &block)
21
- options = _options.dup
22
- options[:range] = "" if options[:range] == true
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
- @plugin.specs.push(
26
- :type => :command,
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 function(name, _options, &block)
35
- options = _options.dup
36
- options[:range] = "" if options[:range] == true
37
- options[:range] = ::Kernel.String(options[:range])
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
- @plugin.specs.push(
40
- :type => :function,
41
- :name => name.to_sym,
42
- :sync => !!options.delete(:sync),
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 autocmd(name, _options={}, &block)
49
- options = _options.dup
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
- @plugin.specs.push(
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
@@ -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.to_sym
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
@@ -1,3 +1,3 @@
1
1
  module Neovim
2
- VERSION = Gem::Version.new("0.0.3")
2
+ VERSION = Gem::Version.new("0.0.4")
3
3
  end
@@ -2,10 +2,11 @@ require "helper"
2
2
  require "tmpdir"
3
3
 
4
4
  RSpec.describe "neovim-ruby-host" do
5
- specify do
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.write("./plugin1.rb", <<-RUBY)
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.write("./plugin2.rb", <<-RUBY)
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(%{let host = rpcstart("#{host_exe}", ["./plugin1.rb", "./plugin2.rb"])})
29
+ nvim.command("let host = rpcstart('#{host_exe}', ['#{plugin1_path}', '#{plugin2_path}'])")
29
30
 
30
- # Send a "poll" request
31
- expect(nvim.eval(%{rpcrequest(host, "poll")})).to eq("ok")
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
- # Make a request to the synchronous SyncAdd method and store the result
34
- nvim.command(%{let result = rpcrequest(host, "SyncAdd", 1, 2)})
35
-
36
- # Write the result to the buffer
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.command(%{call rpcnotify(host, "Unknown")})
40
+ nvim.eval("rpcnotify(host, 'Unknown')")
46
41
  }.not_to raise_error
47
42
 
48
- # Make an unknown request
49
43
  expect {
50
- nvim.command(%{call rpcrequest(host, "Unknown")})
51
- }.to raise_error(ArgumentError, /unknown request/i)
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
@@ -8,6 +8,8 @@ if ENV["REPORT_COVERAGE"]
8
8
  Coveralls.wear!
9
9
  end
10
10
 
11
+ Thread.abort_on_exception = true
12
+
11
13
  ENV["NVIM_EXECUTABLE"] = File.expand_path("../../vendor/neovim/build/bin/nvim", __FILE__)
12
14
 
13
15
  RSpec.configure do |config|
@@ -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(:func)
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(:func)
60
+ expect(notification.method_name).to eq("func")
61
61
  expect(notification.arguments).to eq([1, 2, 3])
62
62
  end
63
63
 
@@ -6,53 +6,15 @@ module Neovim
6
6
  let(:buffer) { client.current.buffer }
7
7
 
8
8
  describe "#lines" do
9
- before do
10
- client.command("normal i1")
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
@@ -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
- event_loop.send("data").run do |msg|
21
- Fiber.yield(msg)
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
- event_loop.send(message).run do |msg|
54
- Fiber.yield(msg)
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]))