neovim 0.0.5 → 0.0.6
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/.travis.yml +5 -2
- data/CHANGELOG.md +11 -0
- data/README.md +15 -4
- data/Rakefile +64 -4
- data/bin/j2mp +8 -0
- data/bin/mp2j +8 -0
- data/lib/neovim.rb +100 -17
- data/lib/neovim/api.rb +84 -0
- data/lib/neovim/async_session.rb +74 -21
- data/lib/neovim/buffer.rb +111 -4
- data/lib/neovim/client.rb +175 -4
- data/lib/neovim/current.rb +19 -8
- data/lib/neovim/event_loop.rb +55 -10
- data/lib/neovim/host.rb +21 -8
- data/lib/neovim/line_range.rb +55 -15
- data/lib/neovim/logging.rb +4 -0
- data/lib/neovim/manifest.rb +11 -3
- data/lib/neovim/msgpack_stream.rb +53 -19
- data/lib/neovim/notification.rb +2 -0
- data/lib/neovim/plugin.rb +12 -87
- data/lib/neovim/plugin/dsl.rb +81 -0
- data/lib/neovim/plugin/handler.rb +43 -0
- data/lib/neovim/remote_object.rb +64 -0
- data/lib/neovim/request.rb +4 -2
- data/lib/neovim/session.rb +167 -16
- data/lib/neovim/tabpage.rb +24 -2
- data/lib/neovim/version.rb +1 -1
- data/lib/neovim/window.rb +92 -2
- data/neovim.gemspec +1 -1
- data/spec/acceptance/neovim-ruby-host_spec.rb +16 -8
- data/spec/helper.rb +11 -3
- data/spec/neovim/api_spec.rb +40 -0
- data/spec/neovim/async_session_spec.rb +19 -25
- data/spec/neovim/current_spec.rb +64 -4
- data/spec/neovim/event_loop_spec.rb +18 -27
- data/spec/neovim/host_spec.rb +20 -1
- data/spec/neovim/manifest_spec.rb +0 -2
- data/spec/neovim/msgpack_stream_spec.rb +5 -6
- data/spec/neovim/{object_spec.rb → remote_object_spec.rb} +1 -4
- data/spec/neovim/session_spec.rb +18 -26
- data/spec/neovim_spec.rb +2 -3
- data/spec/support.rb +5 -5
- metadata +13 -6
- data/lib/neovim/api_info.rb +0 -27
- data/lib/neovim/object.rb +0 -40
data/lib/neovim/buffer.rb
CHANGED
@@ -1,23 +1,130 @@
|
|
1
|
-
require "neovim/
|
1
|
+
require "neovim/remote_object"
|
2
2
|
require "neovim/line_range"
|
3
3
|
|
4
4
|
module Neovim
|
5
|
-
|
5
|
+
# Class representing an +nvim+ buffer.
|
6
|
+
class Buffer < RemoteObject
|
7
|
+
# A +LineRange+ object representing the buffer's lines.
|
8
|
+
#
|
9
|
+
# @return [LineRange]
|
10
|
+
# @see LineRange
|
6
11
|
def lines
|
7
12
|
@lines ||= LineRange.new(self, 0, -1)
|
8
13
|
end
|
9
14
|
|
10
|
-
|
11
|
-
|
15
|
+
# Replace all the lines of the buffer.
|
16
|
+
#
|
17
|
+
# @param strs [Array<String>] The replacement lines
|
18
|
+
# @return [Array<String>]
|
19
|
+
def lines=(strs)
|
20
|
+
lines[0..-1] = strs
|
12
21
|
end
|
13
22
|
|
23
|
+
# A +LineRange+ object representing the buffer's selection range.
|
24
|
+
#
|
25
|
+
# @return [LineRange]
|
26
|
+
# @see LineRange
|
14
27
|
def range
|
15
28
|
@range ||= LineRange.new(self, 0, -1)
|
16
29
|
end
|
17
30
|
|
31
|
+
# Set the buffer's current selection range.
|
32
|
+
#
|
33
|
+
# @param _range [Range] The replacement range
|
34
|
+
# @return [LineRange]
|
35
|
+
# @see LineRange
|
18
36
|
def range=(_range)
|
19
37
|
_end = _range.exclude_end? ? _range.end - 1 : _range.end
|
20
38
|
@range = LineRange.new(self, _range.begin, _end)
|
21
39
|
end
|
40
|
+
|
41
|
+
# The following methods are dynamically generated.
|
42
|
+
=begin
|
43
|
+
@method line_count
|
44
|
+
@return [Fixnum]
|
45
|
+
|
46
|
+
@method get_line(index)
|
47
|
+
@param [Fixnum] index
|
48
|
+
@return [String]
|
49
|
+
|
50
|
+
@method set_line(index, line)
|
51
|
+
@param [Fixnum] index
|
52
|
+
@param [String] line
|
53
|
+
@return [void]
|
54
|
+
|
55
|
+
@method del_line(index)
|
56
|
+
@param [Fixnum] index
|
57
|
+
@return [void]
|
58
|
+
|
59
|
+
@method get_line_slice(start, end, include_start, include_end)
|
60
|
+
@param [Fixnum] start
|
61
|
+
@param [Fixnum] end
|
62
|
+
@param [Boolean] include_start
|
63
|
+
@param [Boolean] include_end
|
64
|
+
@return [Array<String>]
|
65
|
+
|
66
|
+
@method set_line_slice(start, end, include_start, include_end, replacement)
|
67
|
+
@param [Fixnum] start
|
68
|
+
@param [Fixnum] end
|
69
|
+
@param [Boolean] include_start
|
70
|
+
@param [Boolean] include_end
|
71
|
+
@param [Array<String>] replacement
|
72
|
+
@return [void]
|
73
|
+
|
74
|
+
@method get_var(name)
|
75
|
+
@param [String] name
|
76
|
+
@return [Object]
|
77
|
+
|
78
|
+
@method set_var(name, value)
|
79
|
+
@param [String] name
|
80
|
+
@param [Object] value
|
81
|
+
@return [Object]
|
82
|
+
|
83
|
+
@method get_option(name)
|
84
|
+
@param [String] name
|
85
|
+
@return [Object]
|
86
|
+
|
87
|
+
@method set_option(name, value)
|
88
|
+
@param [String] name
|
89
|
+
@param [Object] value
|
90
|
+
@return [void]
|
91
|
+
|
92
|
+
@method get_number
|
93
|
+
@return [Fixnum]
|
94
|
+
|
95
|
+
@method get_name
|
96
|
+
@return [String]
|
97
|
+
|
98
|
+
@method set_name(name)
|
99
|
+
@param [String] name
|
100
|
+
@return [void]
|
101
|
+
|
102
|
+
@method is_valid
|
103
|
+
@return [Boolean]
|
104
|
+
|
105
|
+
@method insert(lnum, lines)
|
106
|
+
@param [Fixnum] lnum
|
107
|
+
@param [Array<String>] lines
|
108
|
+
@return [void]
|
109
|
+
|
110
|
+
@method get_mark(name)
|
111
|
+
@param [String] name
|
112
|
+
@return [Array<Fixnum>]
|
113
|
+
|
114
|
+
@method add_highlight(src_id, hl_group, line, col_start, col_end)
|
115
|
+
@param [Fixnum] src_id
|
116
|
+
@param [String] hl_group
|
117
|
+
@param [Fixnum] line
|
118
|
+
@param [Fixnum] col_start
|
119
|
+
@param [Fixnum] col_end
|
120
|
+
@return [Fixnum]
|
121
|
+
|
122
|
+
@method clear_highlight(src_id, line_start, line_end)
|
123
|
+
@param [Fixnum] src_id
|
124
|
+
@param [Fixnum] line_start
|
125
|
+
@param [Fixnum] line_end
|
126
|
+
@return [void]
|
127
|
+
|
128
|
+
=end
|
22
129
|
end
|
23
130
|
end
|
data/lib/neovim/client.rb
CHANGED
@@ -1,31 +1,202 @@
|
|
1
1
|
require "neovim/current"
|
2
2
|
|
3
3
|
module Neovim
|
4
|
+
# Client to a running +nvim+ instance. The interface is generated at
|
5
|
+
# runtime via the +vim_get_api_info+ RPC call. Some methods return
|
6
|
+
# +RemoteObject+ subclasses (i.e. +Buffer+, +Window+, or +Tabpage+),
|
7
|
+
# which similarly have dynamically generated interfaces.
|
8
|
+
#
|
9
|
+
# @see Buffer
|
10
|
+
# @see Window
|
11
|
+
# @see Tabpage
|
4
12
|
class Client
|
5
13
|
attr_reader :session
|
6
14
|
|
7
15
|
def initialize(session)
|
8
16
|
@session = session
|
17
|
+
@api = session.api
|
9
18
|
end
|
10
19
|
|
20
|
+
# Intercept method calls and delegate to appropriate RPC methods.
|
11
21
|
def method_missing(method_name, *args)
|
12
|
-
if
|
13
|
-
|
22
|
+
if func = @api.function("vim_#{method_name}")
|
23
|
+
func.call(session, *args)
|
14
24
|
else
|
15
25
|
super
|
16
26
|
end
|
17
27
|
end
|
18
28
|
|
29
|
+
# Extend +respond_to?+ to support RPC methods.
|
19
30
|
def respond_to?(method_name)
|
20
|
-
super ||
|
31
|
+
super || rpc_methods.include?(method_name.to_sym)
|
21
32
|
end
|
22
33
|
|
34
|
+
# Extend +methods+ to include RPC methods.
|
23
35
|
def methods
|
24
|
-
super |
|
36
|
+
super | rpc_methods
|
25
37
|
end
|
26
38
|
|
39
|
+
# Access to objects belonging to the current +nvim+ context.
|
40
|
+
#
|
41
|
+
# @return [Current]
|
42
|
+
# @example Get the current buffer
|
43
|
+
# client.current.buffer
|
44
|
+
# @example Set the current line
|
45
|
+
# client.current.line = "New line"
|
46
|
+
# @see Current
|
27
47
|
def current
|
28
48
|
Current.new(@session)
|
29
49
|
end
|
50
|
+
|
51
|
+
private
|
52
|
+
|
53
|
+
def rpc_methods
|
54
|
+
@api.functions_with_prefix("vim_").map do |func|
|
55
|
+
func.name.sub(/\Avim_/, "").to_sym
|
56
|
+
end
|
57
|
+
end
|
58
|
+
|
59
|
+
public
|
60
|
+
|
61
|
+
# The following methods are dynamically generated.
|
62
|
+
=begin
|
63
|
+
@method command(str)
|
64
|
+
@param [String] str
|
65
|
+
@return [void]
|
66
|
+
|
67
|
+
@method feedkeys(keys, mode, escape_csi)
|
68
|
+
@param [String] keys
|
69
|
+
@param [String] mode
|
70
|
+
@param [Boolean] escape_csi
|
71
|
+
@return [void]
|
72
|
+
|
73
|
+
@method input(keys)
|
74
|
+
@param [String] keys
|
75
|
+
@return [Fixnum]
|
76
|
+
|
77
|
+
@method replace_termcodes(str, from_part, do_lt, special)
|
78
|
+
@param [String] str
|
79
|
+
@param [Boolean] from_part
|
80
|
+
@param [Boolean] do_lt
|
81
|
+
@param [Boolean] special
|
82
|
+
@return [String]
|
83
|
+
|
84
|
+
@method command_output(str)
|
85
|
+
@param [String] str
|
86
|
+
@return [String]
|
87
|
+
|
88
|
+
@method eval(str)
|
89
|
+
@param [String] str
|
90
|
+
@return [Object]
|
91
|
+
|
92
|
+
@method call_function(fname, args)
|
93
|
+
@param [String] fname
|
94
|
+
@param [Array] args
|
95
|
+
@return [Object]
|
96
|
+
|
97
|
+
@method strwidth(str)
|
98
|
+
@param [String] str
|
99
|
+
@return [Fixnum]
|
100
|
+
|
101
|
+
@method list_runtime_paths
|
102
|
+
@return [Array<String>]
|
103
|
+
|
104
|
+
@method change_directory(dir)
|
105
|
+
@param [String] dir
|
106
|
+
@return [void]
|
107
|
+
|
108
|
+
@method get_current_line
|
109
|
+
@return [String]
|
110
|
+
|
111
|
+
@method set_current_line(line)
|
112
|
+
@param [String] line
|
113
|
+
@return [void]
|
114
|
+
|
115
|
+
@method del_current_line
|
116
|
+
@return [void]
|
117
|
+
|
118
|
+
@method get_var(name)
|
119
|
+
@param [String] name
|
120
|
+
@return [Object]
|
121
|
+
|
122
|
+
@method set_var(name, value)
|
123
|
+
@param [String] name
|
124
|
+
@param [Object] value
|
125
|
+
@return [Object]
|
126
|
+
|
127
|
+
@method get_vvar(name)
|
128
|
+
@param [String] name
|
129
|
+
@return [Object]
|
130
|
+
|
131
|
+
@method get_option(name)
|
132
|
+
@param [String] name
|
133
|
+
@return [Object]
|
134
|
+
|
135
|
+
@method set_option(name, value)
|
136
|
+
@param [String] name
|
137
|
+
@param [Object] value
|
138
|
+
@return [void]
|
139
|
+
|
140
|
+
@method out_write(str)
|
141
|
+
@param [String] str
|
142
|
+
@return [void]
|
143
|
+
|
144
|
+
@method err_write(str)
|
145
|
+
@param [String] str
|
146
|
+
@return [void]
|
147
|
+
|
148
|
+
@method report_error(str)
|
149
|
+
@param [String] str
|
150
|
+
@return [void]
|
151
|
+
|
152
|
+
@method get_buffers
|
153
|
+
@return [Array<Buffer>]
|
154
|
+
|
155
|
+
@method get_current_buffer
|
156
|
+
@return [Buffer]
|
157
|
+
|
158
|
+
@method set_current_buffer(buffer)
|
159
|
+
@param [Buffer] buffer
|
160
|
+
@return [void]
|
161
|
+
|
162
|
+
@method get_windows
|
163
|
+
@return [Array<Window>]
|
164
|
+
|
165
|
+
@method get_current_window
|
166
|
+
@return [Window]
|
167
|
+
|
168
|
+
@method set_current_window(window)
|
169
|
+
@param [Window] window
|
170
|
+
@return [void]
|
171
|
+
|
172
|
+
@method get_tabpages
|
173
|
+
@return [Array<Tabpage>]
|
174
|
+
|
175
|
+
@method get_current_tabpage
|
176
|
+
@return [Tabpage]
|
177
|
+
|
178
|
+
@method set_current_tabpage(tabpage)
|
179
|
+
@param [Tabpage] tabpage
|
180
|
+
@return [void]
|
181
|
+
|
182
|
+
@method subscribe(event)
|
183
|
+
@param [String] event
|
184
|
+
@return [void]
|
185
|
+
|
186
|
+
@method unsubscribe(event)
|
187
|
+
@param [String] event
|
188
|
+
@return [void]
|
189
|
+
|
190
|
+
@method name_to_color(name)
|
191
|
+
@param [String] name
|
192
|
+
@return [Fixnum]
|
193
|
+
|
194
|
+
@method get_color_map
|
195
|
+
@return [Dictionary]
|
196
|
+
|
197
|
+
@method get_api_info
|
198
|
+
@return [Array]
|
199
|
+
|
200
|
+
=end
|
30
201
|
end
|
31
202
|
end
|
data/lib/neovim/current.rb
CHANGED
@@ -3,43 +3,54 @@ require "neovim/tabpage"
|
|
3
3
|
require "neovim/window"
|
4
4
|
|
5
5
|
module Neovim
|
6
|
+
# Support for +client.current+ chaining.
|
7
|
+
# @see Client#current
|
6
8
|
class Current
|
7
9
|
def initialize(session)
|
8
10
|
@session = session
|
9
11
|
end
|
10
12
|
|
13
|
+
# @return [String]
|
11
14
|
def line
|
12
15
|
@session.request(:vim_get_current_line)
|
13
16
|
end
|
14
17
|
|
15
|
-
|
16
|
-
|
18
|
+
# @param line [String] The target line contents.
|
19
|
+
# @return [String]
|
20
|
+
def line=(line)
|
21
|
+
@session.request(:vim_set_current_line, line)
|
17
22
|
end
|
18
23
|
|
24
|
+
# @return [Buffer]
|
19
25
|
def buffer
|
20
26
|
@session.request(:vim_get_current_buffer)
|
21
27
|
end
|
22
28
|
|
23
|
-
|
24
|
-
|
29
|
+
# @param buffer [Buffer, Fixnum] The target buffer or index.
|
30
|
+
# @return [Buffer, Fixnum]
|
31
|
+
def buffer=(buffer)
|
25
32
|
@session.request(:vim_set_current_buffer, buffer)
|
26
33
|
end
|
27
34
|
|
35
|
+
# @return [Window]
|
28
36
|
def window
|
29
37
|
@session.request(:vim_get_current_window)
|
30
38
|
end
|
31
39
|
|
32
|
-
|
33
|
-
|
40
|
+
# @param window [Window, Fixnum] The target window or index.
|
41
|
+
# @return [Window, Fixnum]
|
42
|
+
def window=(window)
|
34
43
|
@session.request(:vim_set_current_window, window)
|
35
44
|
end
|
36
45
|
|
46
|
+
# @return [Tabpage]
|
37
47
|
def tabpage
|
38
48
|
@session.request(:vim_get_current_tabpage)
|
39
49
|
end
|
40
50
|
|
41
|
-
|
42
|
-
|
51
|
+
# @param tabpage [Tabpage, Fixnum] The target tabpage or index.
|
52
|
+
# @return [Tabpage, Fixnum]
|
53
|
+
def tabpage=(tabpage)
|
43
54
|
@session.request(:vim_set_current_tabpage, tabpage)
|
44
55
|
end
|
45
56
|
end
|
data/lib/neovim/event_loop.rb
CHANGED
@@ -2,38 +2,63 @@ require "neovim/logging"
|
|
2
2
|
require "socket"
|
3
3
|
|
4
4
|
module Neovim
|
5
|
+
# The lowest level interface to reading from and writing to +nvim+.
|
5
6
|
class EventLoop
|
6
7
|
include Logging
|
7
8
|
|
9
|
+
private_class_method :new
|
10
|
+
|
11
|
+
# Connect to a TCP socket.
|
12
|
+
#
|
13
|
+
# @param host [String] The hostname or IP address
|
14
|
+
# @param port [Fixnum] The port
|
15
|
+
# @return [EventLoop]
|
8
16
|
def self.tcp(host, port)
|
9
17
|
socket = TCPSocket.new(host, port)
|
10
|
-
new(socket
|
18
|
+
new(socket)
|
11
19
|
end
|
12
20
|
|
21
|
+
# Connect to a UNIX domain socket.
|
22
|
+
#
|
23
|
+
# @param path [String] The socket path
|
24
|
+
# @return [EventLoop]
|
13
25
|
def self.unix(path)
|
14
26
|
socket = UNIXSocket.new(path)
|
15
|
-
new(socket
|
27
|
+
new(socket)
|
16
28
|
end
|
17
29
|
|
30
|
+
# Spawn and connect to a child +nvim+ process.
|
31
|
+
#
|
32
|
+
# @param argv [Array] The arguments to pass to the spawned process
|
33
|
+
# @return [EventLoop]
|
18
34
|
def self.child(argv)
|
19
35
|
argv = [ENV.fetch("NVIM_EXECUTABLE", "nvim"), "--embed"] | argv
|
20
36
|
io = IO.popen(argv, "rb+")
|
21
|
-
new(io
|
37
|
+
new(io)
|
22
38
|
end
|
23
39
|
|
40
|
+
# Connect to the current process's standard streams. This is used to
|
41
|
+
# promote the current process to a Ruby plugin host.
|
42
|
+
#
|
43
|
+
# @return [EventLoop]
|
24
44
|
def self.stdio
|
25
45
|
new(STDIN, STDOUT)
|
26
46
|
end
|
27
47
|
|
28
|
-
def initialize(rd, wr)
|
48
|
+
def initialize(rd, wr=rd)
|
29
49
|
@rd, @wr = rd, wr
|
30
50
|
@running = false
|
31
51
|
end
|
32
52
|
|
33
|
-
|
53
|
+
# Write data to the underlying +IO+. This will block until all the
|
54
|
+
# data has been written.
|
55
|
+
#
|
56
|
+
# @param data [String] The data to write (typically message-packed)
|
57
|
+
# @return [self]
|
58
|
+
def write(data)
|
34
59
|
start = 0
|
35
60
|
size = data.size
|
36
|
-
debug("
|
61
|
+
debug("writing #{data.inspect}")
|
37
62
|
|
38
63
|
begin
|
39
64
|
while start < size
|
@@ -41,20 +66,24 @@ module Neovim
|
|
41
66
|
end
|
42
67
|
self
|
43
68
|
rescue IO::WaitWritable
|
44
|
-
IO.select(nil, [@wr])
|
69
|
+
IO.select(nil, [@wr], nil, 1)
|
45
70
|
retry
|
46
71
|
end
|
47
72
|
end
|
48
73
|
|
49
|
-
|
74
|
+
# Run the event loop, reading from the underlying +IO+ and yielding
|
75
|
+
# received messages to the block.
|
76
|
+
#
|
77
|
+
# @yield [String]
|
78
|
+
# @return [void]
|
79
|
+
def run
|
50
80
|
@running = true
|
51
|
-
setup_callback.call if setup_callback.respond_to?(:call)
|
52
81
|
|
53
82
|
loop do
|
54
83
|
break unless @running
|
55
84
|
message = @rd.readpartial(1024 * 16)
|
56
85
|
debug("received #{message.inspect}")
|
57
|
-
|
86
|
+
yield message if block_given?
|
58
87
|
end
|
59
88
|
rescue EOFError
|
60
89
|
warn("got EOFError")
|
@@ -62,5 +91,21 @@ module Neovim
|
|
62
91
|
fatal("got unexpected error #{e}")
|
63
92
|
debug(e.backtrace.join("\n"))
|
64
93
|
end
|
94
|
+
|
95
|
+
# Stop the event loop.
|
96
|
+
#
|
97
|
+
# @return [void]
|
98
|
+
def stop
|
99
|
+
@running = false
|
100
|
+
end
|
101
|
+
|
102
|
+
# Stop the event loop and close underlying +IO+s.
|
103
|
+
#
|
104
|
+
# @return [void]
|
105
|
+
def shutdown
|
106
|
+
stop
|
107
|
+
[@rd, @wr].each(&:close)
|
108
|
+
rescue IOError
|
109
|
+
end
|
65
110
|
end
|
66
111
|
end
|