nvim 1.0.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.
- checksums.yaml +7 -0
- data/INFO.yaml +18 -0
- data/LICENSE +52 -0
- data/README.md +264 -0
- data/Rakefile +68 -0
- data/bin/neovim-ruby-host +51 -0
- data/lib/neovim/client.rb +108 -0
- data/lib/neovim/connection.rb +129 -0
- data/lib/neovim/foreign/mplight/bufferio.rb +51 -0
- data/lib/neovim/foreign/mplight.rb +327 -0
- data/lib/neovim/foreign/supplement/socket.rb +20 -0
- data/lib/neovim/foreign/supplement.rb +34 -0
- data/lib/neovim/handler.rb +139 -0
- data/lib/neovim/host.rb +87 -0
- data/lib/neovim/info.rb +10 -0
- data/lib/neovim/logging.rb +249 -0
- data/lib/neovim/messager.rb +185 -0
- data/lib/neovim/meta.rb +68 -0
- data/lib/neovim/remote.rb +56 -0
- data/lib/neovim/remote_object.rb +331 -0
- data/lib/neovim/ruby_provider.rb +372 -0
- data/lib/neovim/session.rb +60 -0
- data/lib/neovim/vimscript_provider.rb +49 -0
- data/lib/neovim.rb +22 -0
- metadata +66 -0
@@ -0,0 +1,331 @@
|
|
1
|
+
#
|
2
|
+
# neovim/remote_object.rb -- Remote Objects: Buffer, Window, Tabpage
|
3
|
+
#
|
4
|
+
|
5
|
+
require "neovim/foreign/mplight"
|
6
|
+
require "neovim/foreign/mplight/bufferio"
|
7
|
+
|
8
|
+
|
9
|
+
module Neovim
|
10
|
+
|
11
|
+
module OptionAccess
|
12
|
+
|
13
|
+
def get_option name, *args
|
14
|
+
vs = [name, *args].map { |a| call_api :get_option_value, a, option_params }
|
15
|
+
if args.empty? then
|
16
|
+
vs.first
|
17
|
+
else
|
18
|
+
vs
|
19
|
+
end
|
20
|
+
end
|
21
|
+
alias get_options get_option
|
22
|
+
|
23
|
+
def set_option *args, **kwargs
|
24
|
+
op = option_params
|
25
|
+
args.each { |a| call_api :set_option_value, a, true, op }
|
26
|
+
kwargs.each { |k,v| call_api :set_option_value, k, v, op }
|
27
|
+
nil
|
28
|
+
end
|
29
|
+
alias set_options set_option
|
30
|
+
|
31
|
+
def option_params
|
32
|
+
r = {}
|
33
|
+
n = self.class::OPTION_PARAM
|
34
|
+
r[ n] = @index if n
|
35
|
+
r
|
36
|
+
end
|
37
|
+
|
38
|
+
end
|
39
|
+
|
40
|
+
|
41
|
+
|
42
|
+
class RemoteObject
|
43
|
+
|
44
|
+
class <<self
|
45
|
+
|
46
|
+
alias plain_new new
|
47
|
+
def new index, client
|
48
|
+
@objs ||= []
|
49
|
+
i = @objs.find { |s| s.index == index && s.client == client }
|
50
|
+
unless i then
|
51
|
+
i = plain_new index, client
|
52
|
+
@objs.push i
|
53
|
+
end
|
54
|
+
i
|
55
|
+
end
|
56
|
+
|
57
|
+
def type
|
58
|
+
@type ||= (name.sub /.*::/, "").to_sym
|
59
|
+
end
|
60
|
+
|
61
|
+
end
|
62
|
+
|
63
|
+
attr_reader :index, :client
|
64
|
+
|
65
|
+
def initialize index, client
|
66
|
+
@index, @client = index, client
|
67
|
+
end
|
68
|
+
|
69
|
+
def type
|
70
|
+
self.class.type
|
71
|
+
end
|
72
|
+
|
73
|
+
def inspect
|
74
|
+
"#<#{self.class}:#{self.object_id} #@index>"
|
75
|
+
end
|
76
|
+
|
77
|
+
# Neovim packs it twice.
|
78
|
+
TRANSFER = MPLight::Types.new
|
79
|
+
TRANSFER.extend MPLight::Packer, MPLight::Unpacker
|
80
|
+
def to_mpdata packer = nil
|
81
|
+
b = MPLight::BufferIO.new
|
82
|
+
TRANSFER.do_output b do TRANSFER.put @index end
|
83
|
+
b.data
|
84
|
+
end
|
85
|
+
class <<self
|
86
|
+
def from_mpdata data, client
|
87
|
+
b = MPLight::BufferIO.new data
|
88
|
+
index = TRANSFER.do_input b do TRANSFER.get end
|
89
|
+
new index, client
|
90
|
+
end
|
91
|
+
end
|
92
|
+
|
93
|
+
def == other
|
94
|
+
(other.class.equal? self.class) && @index == other.index && @client == other.client
|
95
|
+
end
|
96
|
+
|
97
|
+
|
98
|
+
def call_api name, *args, &block
|
99
|
+
@client.call_api name, *args, &block
|
100
|
+
end
|
101
|
+
|
102
|
+
def call_obj name, *args, &block
|
103
|
+
@client.call_obj self, name, *args, &block
|
104
|
+
end
|
105
|
+
|
106
|
+
|
107
|
+
def method_missing sym, *args
|
108
|
+
call_obj sym, *args
|
109
|
+
rescue UnknownApiObjectFunction
|
110
|
+
super
|
111
|
+
end
|
112
|
+
|
113
|
+
def respond_to_missing? sym, priv = nil
|
114
|
+
@client.has_obj_function? self, sym
|
115
|
+
end
|
116
|
+
|
117
|
+
def methods regular = true
|
118
|
+
s = super
|
119
|
+
s |= @client.obj_functions self if regular
|
120
|
+
s
|
121
|
+
end
|
122
|
+
|
123
|
+
include OptionAccess
|
124
|
+
|
125
|
+
end
|
126
|
+
|
127
|
+
|
128
|
+
|
129
|
+
class Buffer < RemoteObject
|
130
|
+
|
131
|
+
# Functions as described in ":h ruby"
|
132
|
+
|
133
|
+
def name ; call_obj :get_name ; end
|
134
|
+
def number ; call_obj :get_number ; end
|
135
|
+
|
136
|
+
def count ; call_obj :line_count ; end
|
137
|
+
alias length count
|
138
|
+
|
139
|
+
def [] pos = nil, len = nil
|
140
|
+
line_indices pos, len do |fst,lst|
|
141
|
+
get_lines fst, lst, false
|
142
|
+
end
|
143
|
+
end
|
144
|
+
|
145
|
+
def []= pos = nil, len = nil, str
|
146
|
+
line_indices pos, len do |fst,lst|
|
147
|
+
set_lines fst, lst, false, (str_lines str)
|
148
|
+
end
|
149
|
+
self
|
150
|
+
end
|
151
|
+
|
152
|
+
def delete pos, len = nil ; self[pos, len] = nil ; end
|
153
|
+
|
154
|
+
def insert pos = nil, str
|
155
|
+
self[ pos||0, 0] = str
|
156
|
+
end
|
157
|
+
|
158
|
+
def append pos = nil, str
|
159
|
+
p = (pos||0) + 1
|
160
|
+
insert p, str
|
161
|
+
end
|
162
|
+
|
163
|
+
|
164
|
+
# Legacy functions
|
165
|
+
|
166
|
+
def line
|
167
|
+
call_api :get_current_line if active?
|
168
|
+
end
|
169
|
+
|
170
|
+
def line= str
|
171
|
+
raise "Buffer not active. Use Buffer#[]= instead." unless active?
|
172
|
+
call_api :set_current_line, str
|
173
|
+
end
|
174
|
+
|
175
|
+
def line_number
|
176
|
+
(call_api :get_current_win).line if active?
|
177
|
+
end
|
178
|
+
|
179
|
+
|
180
|
+
def active?
|
181
|
+
(call_api :get_current_buf).index == @index
|
182
|
+
end
|
183
|
+
|
184
|
+
|
185
|
+
OPTION_PARAM = :buf
|
186
|
+
|
187
|
+
|
188
|
+
# Iterating functions
|
189
|
+
|
190
|
+
include Enumerable
|
191
|
+
|
192
|
+
def each pos = nil, len = nil, &block
|
193
|
+
iter_chunks pos, len do |fst,nxt|
|
194
|
+
(get_lines fst, nxt, true).each &block
|
195
|
+
end
|
196
|
+
end
|
197
|
+
|
198
|
+
def map! pos = nil, len = nil, &block
|
199
|
+
iter_chunks pos, len do |fst,nxt|
|
200
|
+
l = (get_lines fst, nxt, true).map &block
|
201
|
+
set_lines fst, nxt, true, l
|
202
|
+
end
|
203
|
+
end
|
204
|
+
|
205
|
+
def select! pos = nil, len = nil, &block
|
206
|
+
line_indices_positive pos, len do |fst,lst|
|
207
|
+
while fst < lst do
|
208
|
+
l, = get_lines fst, fst+1, true
|
209
|
+
if yield l then
|
210
|
+
fst += 1
|
211
|
+
else
|
212
|
+
set_lines fst, fst+1, true, []
|
213
|
+
lst -= 1
|
214
|
+
end
|
215
|
+
end
|
216
|
+
end
|
217
|
+
end
|
218
|
+
|
219
|
+
def reject! pos = nil, len = nil, &block
|
220
|
+
select! pos, len do |l| !yield l end
|
221
|
+
end
|
222
|
+
|
223
|
+
|
224
|
+
# Don't run into `method_missing`.
|
225
|
+
def get_lines fst, lst, strict ; call_obj :get_lines, fst, lst, strict ; end
|
226
|
+
def set_lines fst, lst, strict, ary ; call_obj :set_lines, fst, lst, strict, ary ; end
|
227
|
+
|
228
|
+
|
229
|
+
private
|
230
|
+
|
231
|
+
def line_indices pos, len
|
232
|
+
if Range === pos then
|
233
|
+
r = pos
|
234
|
+
pos, lst = r.begin, r.end
|
235
|
+
lst += 1 unless r.exclude_end?
|
236
|
+
elsif pos.nil? then
|
237
|
+
pos, lst = 1, 0
|
238
|
+
else
|
239
|
+
lst = pos+1
|
240
|
+
end
|
241
|
+
if len then
|
242
|
+
lst = pos + (len >= 0 ? len : 0)
|
243
|
+
end
|
244
|
+
lst = 0 if pos < 0 and lst >= 0
|
245
|
+
yield pos-1, lst-1
|
246
|
+
end
|
247
|
+
|
248
|
+
def line_indices_positive pos, len
|
249
|
+
line_indices pos, len do |*fl|
|
250
|
+
c = nil
|
251
|
+
fl.map! { |y|
|
252
|
+
if y >= 0 then
|
253
|
+
y
|
254
|
+
else
|
255
|
+
y + 1 + (c ||= count)
|
256
|
+
end
|
257
|
+
}
|
258
|
+
yield *fl
|
259
|
+
end
|
260
|
+
end
|
261
|
+
|
262
|
+
@chunk = 1024 # Attention! Each chunk is its own undo level.
|
263
|
+
class <<self
|
264
|
+
attr_accessor :chunk
|
265
|
+
end
|
266
|
+
|
267
|
+
def iter_chunks pos, len
|
268
|
+
line_indices_positive pos, len do |fst,lst|
|
269
|
+
while lst do
|
270
|
+
nxt = fst + self.class.chunk
|
271
|
+
if nxt > lst then
|
272
|
+
nxt, lst = lst, nil
|
273
|
+
end
|
274
|
+
yield fst, nxt
|
275
|
+
fst = nxt
|
276
|
+
end
|
277
|
+
end
|
278
|
+
end
|
279
|
+
|
280
|
+
def str_lines str
|
281
|
+
if Array === str then
|
282
|
+
str
|
283
|
+
elsif str.nil? then
|
284
|
+
[]
|
285
|
+
else
|
286
|
+
str.lines.each { |l| l.chomp! }
|
287
|
+
end
|
288
|
+
end
|
289
|
+
|
290
|
+
end
|
291
|
+
|
292
|
+
|
293
|
+
class Window < RemoteObject
|
294
|
+
|
295
|
+
def number ; call_obj :get_number ; end
|
296
|
+
|
297
|
+
def buffer ; call_obj :get_buf ; end
|
298
|
+
|
299
|
+
def height ; call_obj :get_height ; end
|
300
|
+
def height= n ; call_obj :set_height, n ; end
|
301
|
+
|
302
|
+
def width ; call_obj :get_width ; end
|
303
|
+
def width= n ; call_obj :set_width, n ; end
|
304
|
+
|
305
|
+
def line ; cursor.first ; end
|
306
|
+
|
307
|
+
def cursor ; call_obj :get_cursor ; end
|
308
|
+
def cursor= yx ; call_obj :set_cursor, yx ; end
|
309
|
+
|
310
|
+
def save_cursor
|
311
|
+
c = cursor
|
312
|
+
yield
|
313
|
+
self.cursor = c
|
314
|
+
end
|
315
|
+
|
316
|
+
OPTION_PARAM = :win
|
317
|
+
|
318
|
+
end
|
319
|
+
|
320
|
+
|
321
|
+
class Tabpage < RemoteObject
|
322
|
+
|
323
|
+
def number ; call_obj :get_number ; end
|
324
|
+
|
325
|
+
# There is currently only one tabpage-local option, 'cmdheight'.
|
326
|
+
OPTION_PARAM = :tab # Neovim is missing this.
|
327
|
+
|
328
|
+
end
|
329
|
+
|
330
|
+
end
|
331
|
+
|
@@ -0,0 +1,372 @@
|
|
1
|
+
#
|
2
|
+
# neovim/ruby_provider.rb -- Plugin for :ruby* commands
|
3
|
+
#
|
4
|
+
|
5
|
+
require "neovim/handler"
|
6
|
+
require "neovim/remote_object"
|
7
|
+
|
8
|
+
|
9
|
+
class Object
|
10
|
+
# Poor, poor RubyGems is polluting the global namespace.
|
11
|
+
# see <https://github.com/rubygems/rubygems/pull/7200>
|
12
|
+
def empty_binding
|
13
|
+
binding
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
|
18
|
+
# The VIM module as documented in ":h ruby".
|
19
|
+
module Vim
|
20
|
+
|
21
|
+
class Buffer < ::Neovim::Buffer
|
22
|
+
class <<self
|
23
|
+
def current ; $vim.get_current_buf ; end
|
24
|
+
def count ; $vim.list_bufs.size ; end
|
25
|
+
def [] i ; $vim.list_bufs[ i] ; end
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
class Window < ::Neovim::Window
|
30
|
+
class <<self
|
31
|
+
def current ; $vim.get_current_win ; end
|
32
|
+
def count ; $vim.get_current_tabpage.list_wins.size ; end
|
33
|
+
def [] i ; $vim.get_current_tabpage.list_wins[ i] ; end
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
class <<self
|
38
|
+
def message str ; $vim.message str ; end
|
39
|
+
def set_option *args, **kwargs ; $vim.set_option *args, **kwargs ; end
|
40
|
+
alias set_options set_option
|
41
|
+
def command arg ; $vim.command arg ; end
|
42
|
+
def evaluate expr ; $vim.evaluate expr ; end
|
43
|
+
end
|
44
|
+
|
45
|
+
::VIM = self
|
46
|
+
|
47
|
+
end
|
48
|
+
|
49
|
+
|
50
|
+
|
51
|
+
|
52
|
+
module Neovim
|
53
|
+
|
54
|
+
class Write
|
55
|
+
class <<self
|
56
|
+
def open client
|
57
|
+
i = new client
|
58
|
+
yield i
|
59
|
+
ensure
|
60
|
+
i.finish
|
61
|
+
end
|
62
|
+
end
|
63
|
+
def initialize client
|
64
|
+
@client = client
|
65
|
+
end
|
66
|
+
def print *args
|
67
|
+
args.each { |a| write a.to_s }
|
68
|
+
nil
|
69
|
+
end
|
70
|
+
def puts *args
|
71
|
+
args.each { |a|
|
72
|
+
a = a.to_s
|
73
|
+
write a
|
74
|
+
write "\n" unless a.end_with? $/
|
75
|
+
}
|
76
|
+
nil
|
77
|
+
end
|
78
|
+
def flush
|
79
|
+
end
|
80
|
+
end
|
81
|
+
|
82
|
+
class WriteStd < Write
|
83
|
+
class <<self
|
84
|
+
def redirect client
|
85
|
+
open client do |i|
|
86
|
+
old, $stdout = $stdout, i
|
87
|
+
yield
|
88
|
+
ensure
|
89
|
+
$stdout = old
|
90
|
+
end
|
91
|
+
end
|
92
|
+
end
|
93
|
+
end
|
94
|
+
|
95
|
+
class WriteOut < WriteStd
|
96
|
+
def write *args
|
97
|
+
args.each { |a|
|
98
|
+
a.notempty? or next
|
99
|
+
@client.out_write a
|
100
|
+
@line_open = !(a.end_with? $/)
|
101
|
+
}
|
102
|
+
nil
|
103
|
+
end
|
104
|
+
def finish
|
105
|
+
if @line_open then
|
106
|
+
@client.out_write $/
|
107
|
+
@line_open = nil
|
108
|
+
end
|
109
|
+
end
|
110
|
+
end
|
111
|
+
|
112
|
+
class WriteErr < Write
|
113
|
+
class <<self
|
114
|
+
def redirect client
|
115
|
+
open client do |i|
|
116
|
+
old, $stderr = $stderr, i
|
117
|
+
yield
|
118
|
+
ensure
|
119
|
+
$stderr = old
|
120
|
+
end
|
121
|
+
end
|
122
|
+
end
|
123
|
+
def write *args
|
124
|
+
args.each { |a|
|
125
|
+
@rest ||= ""
|
126
|
+
@rest << a
|
127
|
+
while @rest =~ /#$// do
|
128
|
+
@client.err_writeln $`
|
129
|
+
@rest = $'
|
130
|
+
end
|
131
|
+
}
|
132
|
+
nil
|
133
|
+
end
|
134
|
+
def finish
|
135
|
+
if @rest.notempty? then
|
136
|
+
@client.err_writeln @rest
|
137
|
+
@rest = nil
|
138
|
+
end
|
139
|
+
end
|
140
|
+
end
|
141
|
+
|
142
|
+
class WriteBuf < WriteStd
|
143
|
+
def write *args
|
144
|
+
s = @rest||""
|
145
|
+
args.each { |a|
|
146
|
+
s << a
|
147
|
+
}
|
148
|
+
s = s.split $/, -1
|
149
|
+
@rest = s.pop
|
150
|
+
@client.put s, "l", true, false
|
151
|
+
nil
|
152
|
+
end
|
153
|
+
def finish
|
154
|
+
if @rest.notempty? then
|
155
|
+
@client.put [@rest], "l", true, false
|
156
|
+
@rest = nil
|
157
|
+
end
|
158
|
+
end
|
159
|
+
end
|
160
|
+
|
161
|
+
|
162
|
+
class DslProvider < DslBase
|
163
|
+
|
164
|
+
TYPE = :script
|
165
|
+
|
166
|
+
def setup &block
|
167
|
+
add_setup_block &block
|
168
|
+
end
|
169
|
+
|
170
|
+
def setup_autocmd event, fn, *args
|
171
|
+
add_setup_block do |client|
|
172
|
+
a = [ client.channel_id, "'#{fn}'", *args].join ", "
|
173
|
+
client.command "autocmd #{event} * call rpcrequest(#{a})"
|
174
|
+
end
|
175
|
+
end
|
176
|
+
|
177
|
+
def updater name, &block
|
178
|
+
add_handler nil, name, &block
|
179
|
+
end
|
180
|
+
|
181
|
+
def rpc name
|
182
|
+
add_handler nil, name do |client,*args|
|
183
|
+
WriteOut.redirect client do
|
184
|
+
WriteErr.redirect client do
|
185
|
+
yield client, *args
|
186
|
+
end
|
187
|
+
end
|
188
|
+
rescue ScriptError, StandardError
|
189
|
+
line = $@.first[ /:(\d+):/, 1]
|
190
|
+
client.err_writeln "Ruby #$! (#{$!.class}), line #{line}"
|
191
|
+
end
|
192
|
+
end
|
193
|
+
|
194
|
+
end
|
195
|
+
|
196
|
+
class <<self
|
197
|
+
|
198
|
+
def set_global_client client
|
199
|
+
$vim = client
|
200
|
+
yield
|
201
|
+
ensure
|
202
|
+
$vim = nil
|
203
|
+
end
|
204
|
+
|
205
|
+
def set_globals client, range
|
206
|
+
set_global_client client do
|
207
|
+
lines = get_lines client, range
|
208
|
+
$range, $lines = range, lines
|
209
|
+
yield lines
|
210
|
+
end
|
211
|
+
ensure
|
212
|
+
$range, $lines = nil, nil
|
213
|
+
end
|
214
|
+
|
215
|
+
def get_lines client, range
|
216
|
+
client.buf_get_lines 0, range.begin-1, range.end, true
|
217
|
+
end
|
218
|
+
|
219
|
+
def plugin_provider &block
|
220
|
+
run_dsl DslProvider, &block
|
221
|
+
end
|
222
|
+
|
223
|
+
def build_sum lines
|
224
|
+
require "bigdecimal"
|
225
|
+
sum = BigDecimal 0
|
226
|
+
prev, decs = 0, 0
|
227
|
+
sep = "."
|
228
|
+
lines.each { |l|
|
229
|
+
l.slice! /^.*:/
|
230
|
+
l.slice! /#.*/
|
231
|
+
l = l.split /(?:\+\s+|\|)/
|
232
|
+
l.map! { |m|
|
233
|
+
m.strip!
|
234
|
+
if m =~ %r/ *%\z/ then
|
235
|
+
prev * (BigDecimal $`) / 100
|
236
|
+
else
|
237
|
+
m = m.split "*"
|
238
|
+
m.map! { |n|
|
239
|
+
n.sub! /,/ do sep = $& ; "." end
|
240
|
+
n.sub! /\.(?:-+|([0-9]+))/ do
|
241
|
+
if $1 then
|
242
|
+
d = $1.length
|
243
|
+
decs = d if decs < d
|
244
|
+
".#$1"
|
245
|
+
else
|
246
|
+
decs = 2
|
247
|
+
nil
|
248
|
+
end
|
249
|
+
end
|
250
|
+
BigDecimal n
|
251
|
+
}
|
252
|
+
prev = m.inject do |p,e| p*e end
|
253
|
+
end
|
254
|
+
}
|
255
|
+
sum = l.inject sum do |s,e| s+e end
|
256
|
+
}
|
257
|
+
sum = sum.round decs
|
258
|
+
case sum
|
259
|
+
when BigDecimal then
|
260
|
+
sum = sum.to_s "F"
|
261
|
+
sum.sub! /(?:\.([0-9]+))?\z/ do
|
262
|
+
sep + ($1.to_s.ljust decs, "0")
|
263
|
+
end
|
264
|
+
when Integer then
|
265
|
+
sum = sum.to_s
|
266
|
+
end
|
267
|
+
sum
|
268
|
+
end
|
269
|
+
|
270
|
+
end
|
271
|
+
|
272
|
+
plugin_provider do |dsl|
|
273
|
+
|
274
|
+
dsl.setup do |client|
|
275
|
+
$curbuf = client.get_current_buf
|
276
|
+
$curwin = client.get_current_win
|
277
|
+
end
|
278
|
+
|
279
|
+
dsl.setup_autocmd :BufEnter, "ruby_bufenter"
|
280
|
+
dsl.updater :ruby_bufenter do |client|
|
281
|
+
$curbuf = client.get_current_buf
|
282
|
+
end
|
283
|
+
|
284
|
+
dsl.setup_autocmd :WinEnter, "ruby_winenter"
|
285
|
+
dsl.updater :ruby_winenter do |client|
|
286
|
+
$curbuf = client.get_current_buf
|
287
|
+
$curwin = client.get_current_win
|
288
|
+
end
|
289
|
+
|
290
|
+
dsl.setup_autocmd :DirChanged, "ruby_chdir", "v:event"
|
291
|
+
dsl.updater :ruby_chdir do |_,event|
|
292
|
+
Dir.chdir event[ "cwd"]
|
293
|
+
end
|
294
|
+
|
295
|
+
|
296
|
+
script_binding = TOPLEVEL_BINDING.eval "empty_binding"
|
297
|
+
|
298
|
+
# This is called by the +:ruby+ command.
|
299
|
+
dsl.rpc :ruby_execute do |client,code,fst,lst|
|
300
|
+
code.rstrip!
|
301
|
+
if !code.notempty? or code == "|" then # Workaround because Neovim doesn't allow empty code (the ultimate Quine)
|
302
|
+
set_global_client client do
|
303
|
+
client.command "#{lst}"
|
304
|
+
code = (get_lines client, fst..lst).join "\n"
|
305
|
+
WriteBuf.redirect client do
|
306
|
+
r = script_binding.eval code, "ruby_run"
|
307
|
+
r.nil? or puts "#=> #{r.inspect}"
|
308
|
+
end
|
309
|
+
end
|
310
|
+
elsif code == "+" then
|
311
|
+
client.command "#{lst}"
|
312
|
+
set_globals client, fst..lst do |lines|
|
313
|
+
WriteBuf.redirect client do
|
314
|
+
s = build_sum lines
|
315
|
+
puts "-"*(s.length + 4)
|
316
|
+
puts s
|
317
|
+
rescue
|
318
|
+
puts "Error: #$! (#{$!.class})"
|
319
|
+
end
|
320
|
+
end
|
321
|
+
else
|
322
|
+
set_globals client, fst..lst do ||
|
323
|
+
script_binding.eval code, "ruby_execute"
|
324
|
+
end
|
325
|
+
end
|
326
|
+
nil
|
327
|
+
end
|
328
|
+
|
329
|
+
# This is called by the +:rubyfile+ command.
|
330
|
+
dsl.rpc :ruby_execute_file do |client,path,fst,lst|
|
331
|
+
set_globals client, fst..lst do ||
|
332
|
+
r = File.read path
|
333
|
+
script_binding.eval r, "ruby_file #{path}"
|
334
|
+
end
|
335
|
+
nil
|
336
|
+
end
|
337
|
+
|
338
|
+
# This is called by the +:rubydo+ command.
|
339
|
+
dsl.rpc :ruby_do_range do |client,fst,lst,code|
|
340
|
+
set_globals client, fst..lst do |lines|
|
341
|
+
i = fst
|
342
|
+
lines.each do |l|
|
343
|
+
h = l.hash
|
344
|
+
(script_binding.eval 'proc do |l,i| $_, $. = l, i end').call l, i
|
345
|
+
script_binding.eval code, "ruby_do_range"
|
346
|
+
m = script_binding.eval '$_'
|
347
|
+
if m.hash != h then
|
348
|
+
m = m.lines
|
349
|
+
m.each { |x| x.chomp! }
|
350
|
+
client.buf_set_lines 0, i-1, i, true, m
|
351
|
+
i += m.length
|
352
|
+
else
|
353
|
+
i += 1
|
354
|
+
end
|
355
|
+
end
|
356
|
+
end
|
357
|
+
nil
|
358
|
+
ensure
|
359
|
+
script_binding.eval '$_, $. = nil, 0'
|
360
|
+
end
|
361
|
+
|
362
|
+
# This is called by the +rubyeval()+ function.
|
363
|
+
dsl.rpc :ruby_eval do |client,code|
|
364
|
+
set_global_client client do
|
365
|
+
script_binding.eval code, "ruby_eval"
|
366
|
+
end
|
367
|
+
end
|
368
|
+
|
369
|
+
end
|
370
|
+
|
371
|
+
end
|
372
|
+
|