neovim 0.6.2 → 0.9.0.pre.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +5 -5
- data/.github/workflows/docs.yml +36 -0
- data/.github/workflows/linter.yml +32 -0
- data/.github/workflows/tests.yml +62 -0
- data/.gitignore +5 -1
- data/.rubocop.yml +149 -0
- data/CHANGELOG.md +56 -0
- data/CODE_OF_CONDUCT.md +3 -3
- data/Gemfile +0 -11
- data/README.md +22 -23
- data/Rakefile +47 -15
- data/VimFlavor +1 -0
- data/exe/neovim-ruby-host +5 -0
- data/lib/neovim.rb +15 -6
- data/lib/neovim/api.rb +2 -1
- data/lib/neovim/buffer.rb +81 -53
- data/lib/neovim/client.rb +226 -41
- data/lib/neovim/client_info.rb +46 -0
- data/lib/neovim/connection.rb +73 -0
- data/lib/neovim/event_loop.rb +41 -37
- data/lib/neovim/executable.rb +1 -0
- data/lib/neovim/host.rb +50 -51
- data/lib/neovim/host/cli.rb +41 -0
- data/lib/neovim/host/loader.rb +1 -4
- data/lib/neovim/line_range.rb +16 -16
- data/lib/neovim/logging.rb +18 -18
- data/lib/neovim/message.rb +70 -0
- data/lib/neovim/plugin.rb +7 -5
- data/lib/neovim/plugin/dsl.rb +10 -4
- data/lib/neovim/plugin/handler.rb +8 -8
- data/lib/neovim/remote_object.rb +8 -5
- data/lib/neovim/ruby_provider.rb +52 -26
- data/lib/neovim/ruby_provider/buffer_ext.rb +1 -0
- data/lib/neovim/ruby_provider/object_ext.rb +5 -0
- data/lib/neovim/ruby_provider/vim.rb +19 -6
- data/lib/neovim/ruby_provider/window_ext.rb +1 -0
- data/lib/neovim/session.rb +45 -50
- data/lib/neovim/tabpage.rb +8 -15
- data/lib/neovim/version.rb +1 -1
- data/lib/neovim/window.rb +39 -36
- data/neovim.gemspec +11 -6
- data/script/ci/download_nvim.sh +40 -0
- data/script/{dump_api → dump_api.rb} +1 -1
- data/script/{generate_docs → generate_docs.rb} +6 -7
- data/script/{j2mp → j2mp.rb} +0 -0
- data/script/{mp2j → mp2j.rb} +0 -0
- data/script/run_acceptance.rb +39 -0
- data/spec/acceptance/client_info_spec.vim +42 -0
- data/spec/acceptance/rplugin_autocmd_spec.vim +20 -10
- data/spec/acceptance/rplugin_command_spec.vim +54 -56
- data/spec/acceptance/rplugin_function_spec.vim +28 -22
- data/spec/acceptance/ruby_spec.vim +52 -53
- data/spec/acceptance/rubydo_spec.vim +49 -52
- data/spec/acceptance/rubyeval_spec.vim +22 -0
- data/spec/acceptance/rubyfile/curbuf_ivar_get.rb +1 -1
- data/spec/acceptance/rubyfile/curbuf_ivar_set.rb +1 -1
- data/spec/acceptance/rubyfile/define_foo.rb +1 -1
- data/spec/acceptance/rubyfile/nested.rb +1 -1
- data/spec/acceptance/rubyfile/nested_inner.rb +1 -1
- data/spec/acceptance/rubyfile/set_pwd_after.rb +1 -1
- data/spec/acceptance/rubyfile/set_pwd_before.rb +1 -1
- data/spec/acceptance/rubyfile_spec.vim +60 -66
- data/spec/acceptance/runtime/init.vim +5 -4
- data/spec/acceptance/runtime/rplugin/ruby/autocmds.rb +7 -3
- data/spec/acceptance/runtime/rplugin/ruby/commands.rb +18 -17
- data/spec/acceptance/runtime/rplugin/ruby/functions.rb +9 -9
- data/spec/helper.rb +38 -9
- data/spec/neovim/api_spec.rb +2 -2
- data/spec/neovim/buffer_spec.rb +10 -6
- data/spec/neovim/client_info_spec.rb +77 -0
- data/spec/neovim/client_spec.rb +19 -12
- data/spec/neovim/connection_spec.rb +106 -0
- data/spec/neovim/current_spec.rb +13 -14
- data/spec/neovim/event_loop_spec.rb +48 -46
- data/spec/neovim/executable_spec.rb +2 -2
- data/spec/neovim/host/cli_spec.rb +94 -0
- data/spec/neovim/host/loader_spec.rb +18 -11
- data/spec/neovim/host_spec.rb +84 -92
- data/spec/neovim/line_range_spec.rb +17 -19
- data/spec/neovim/logging_spec.rb +3 -3
- data/spec/neovim/message_spec.rb +119 -0
- data/spec/neovim/plugin_spec.rb +34 -34
- data/spec/neovim/remote_object_spec.rb +1 -2
- data/spec/neovim/ruby_provider/buffer_ext_spec.rb +8 -9
- data/spec/neovim/ruby_provider/object_ext_spec.rb +10 -0
- data/spec/neovim/ruby_provider/vim_spec.rb +5 -5
- data/spec/neovim/ruby_provider/window_ext_spec.rb +12 -15
- data/spec/neovim/session_spec.rb +20 -47
- data/spec/neovim/window_spec.rb +1 -2
- data/spec/neovim_spec.rb +28 -51
- data/spec/support.rb +27 -1
- metadata +83 -48
- data/.coveralls.yml +0 -1
- data/.gitmodules +0 -3
- data/.rspec +0 -1
- data/.travis.yml +0 -23
- data/appveyor.yml +0 -21
- data/bin/neovim-ruby-host +0 -18
- 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/acceptance/runtime/vader.vim/autoload/vader.vim +0 -348
- data/spec/acceptance/runtime/vader.vim/autoload/vader/assert.vim +0 -116
- data/spec/acceptance/runtime/vader.vim/autoload/vader/helper.vim +0 -43
- data/spec/acceptance/runtime/vader.vim/autoload/vader/parser.vim +0 -179
- data/spec/acceptance/runtime/vader.vim/autoload/vader/syntax.vim +0 -73
- data/spec/acceptance/runtime/vader.vim/autoload/vader/window.vim +0 -205
- data/spec/acceptance/runtime/vader.vim/plugin/vader.vim +0 -37
- data/spec/acceptance_spec.rb +0 -82
- 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/host/loader.rb
CHANGED
@@ -8,9 +8,6 @@ module Neovim
|
|
8
8
|
@host = host
|
9
9
|
end
|
10
10
|
|
11
|
-
# Load the provided Ruby files while temporarily overriding
|
12
|
-
# +Neovim.plugin+ to expose the remote plugin DSL and register the result
|
13
|
-
# to the host.
|
14
11
|
def load(paths)
|
15
12
|
paths.each do |path|
|
16
13
|
override_plugin_method(path) do
|
@@ -27,7 +24,7 @@ module Neovim
|
|
27
24
|
|
28
25
|
Neovim.define_singleton_method(:plugin) do |&block|
|
29
26
|
plugin = Plugin.from_config_block(path, &block)
|
30
|
-
at_host.
|
27
|
+
at_host.plugins << plugin
|
31
28
|
end
|
32
29
|
|
33
30
|
yield
|
data/lib/neovim/line_range.rb
CHANGED
@@ -12,8 +12,8 @@ module Neovim
|
|
12
12
|
# @yieldparam line [String]
|
13
13
|
def each(&block)
|
14
14
|
(0...@buffer.count).each_slice(5000) do |linenos|
|
15
|
-
|
16
|
-
@buffer.get_lines(
|
15
|
+
start, stop = linenos[0], linenos[-1] + 1
|
16
|
+
@buffer.get_lines(start, stop, true).each(&block)
|
17
17
|
end
|
18
18
|
end
|
19
19
|
|
@@ -50,15 +50,15 @@ module Neovim
|
|
50
50
|
# @example Get the first two lines using an index and length
|
51
51
|
# line_range[0, 2] # => ["first", "second"]
|
52
52
|
def [](pos, len=nil)
|
53
|
-
if Range
|
53
|
+
if pos.is_a?(Range)
|
54
54
|
@buffer.get_lines(*range_indices(pos), true)
|
55
55
|
else
|
56
|
-
|
57
|
-
lines = @buffer.get_lines(
|
56
|
+
start, stop = length_indices(pos, len || 1)
|
57
|
+
lines = @buffer.get_lines(start, stop, true)
|
58
58
|
len ? lines : lines.first
|
59
59
|
end
|
60
60
|
end
|
61
|
-
|
61
|
+
alias slice []
|
62
62
|
|
63
63
|
# Set a line or line range.
|
64
64
|
#
|
@@ -85,11 +85,11 @@ module Neovim
|
|
85
85
|
*target, val = args
|
86
86
|
pos, len = target
|
87
87
|
|
88
|
-
if Range
|
88
|
+
if pos.is_a?(Range)
|
89
89
|
@buffer.set_lines(*range_indices(pos), true, Array(val))
|
90
90
|
else
|
91
|
-
|
92
|
-
@buffer.set_lines(
|
91
|
+
start, stop = length_indices(pos, len || 1)
|
92
|
+
@buffer.set_lines(start, stop, true, Array(val))
|
93
93
|
end
|
94
94
|
end
|
95
95
|
|
@@ -113,18 +113,18 @@ module Neovim
|
|
113
113
|
private
|
114
114
|
|
115
115
|
def range_indices(range)
|
116
|
-
|
117
|
-
|
118
|
-
|
116
|
+
start = adjust_index(range.begin)
|
117
|
+
stop = adjust_index(range.end)
|
118
|
+
stop += 1 unless range.exclude_end?
|
119
119
|
|
120
|
-
[
|
120
|
+
[start, stop]
|
121
121
|
end
|
122
122
|
|
123
123
|
def length_indices(index, len)
|
124
|
-
|
125
|
-
|
124
|
+
start = adjust_index(index)
|
125
|
+
stop = start < 0 ? [start + len, -1].min : start + len
|
126
126
|
|
127
|
-
[
|
127
|
+
[start, stop]
|
128
128
|
end
|
129
129
|
|
130
130
|
def adjust_index(i)
|
data/lib/neovim/logging.rb
CHANGED
@@ -13,13 +13,12 @@ module Neovim
|
|
13
13
|
def self.logger(env=ENV)
|
14
14
|
return @logger if instance_variable_defined?(:@logger)
|
15
15
|
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
end
|
16
|
+
env_file, env_level =
|
17
|
+
env.values_at("NVIM_RUBY_LOG_FILE", "NVIM_RUBY_LOG_LEVEL")
|
18
|
+
|
19
|
+
@logger = Logger.new(env_file || STDERR)
|
21
20
|
|
22
|
-
if env_level
|
21
|
+
if /\S+/.match?(env_level)
|
23
22
|
begin
|
24
23
|
@logger.level = Integer(env_level)
|
25
24
|
rescue ArgumentError
|
@@ -43,29 +42,30 @@ module Neovim
|
|
43
42
|
end
|
44
43
|
|
45
44
|
def self.json_formatter
|
46
|
-
|
45
|
+
lambda do |level, time, _, fields|
|
47
46
|
require "multi_json"
|
48
47
|
|
49
48
|
MultiJson.encode(
|
50
49
|
{
|
51
|
-
:
|
52
|
-
:
|
50
|
+
_level: level,
|
51
|
+
_time: time.strftime(TIMESTAMP_FORMAT)
|
53
52
|
}.merge!(fields)
|
54
53
|
) << "\n"
|
55
54
|
end
|
56
55
|
end
|
57
56
|
private_class_method :json_formatter
|
58
57
|
|
58
|
+
# @api private
|
59
59
|
module Helpers
|
60
60
|
private
|
61
61
|
|
62
|
-
def log(level,
|
62
|
+
def log(level, method=nil, &block)
|
63
63
|
begin
|
64
64
|
Logging.logger.public_send(level) do
|
65
65
|
{
|
66
|
-
:
|
67
|
-
:
|
68
|
-
}.merge!(
|
66
|
+
_class: self.class,
|
67
|
+
_method: method || block.binding.eval("__method__")
|
68
|
+
}.merge!(yield)
|
69
69
|
end
|
70
70
|
rescue => ex
|
71
71
|
Logging.logger.error("failed to log: #{ex.inspect}")
|
@@ -74,13 +74,13 @@ module Neovim
|
|
74
74
|
# Inability to log shouldn't abort process
|
75
75
|
end
|
76
76
|
|
77
|
-
def log_exception(level, ex,
|
78
|
-
log(level,
|
79
|
-
{:
|
77
|
+
def log_exception(level, ex, method)
|
78
|
+
log(level, method) do
|
79
|
+
{exception: ex.class, message: ex.message}
|
80
80
|
end
|
81
81
|
|
82
|
-
log(:debug,
|
83
|
-
{:
|
82
|
+
log(:debug, method) do
|
83
|
+
{exception: ex.class, message: ex.message, backtrace: ex.backtrace}
|
84
84
|
end
|
85
85
|
end
|
86
86
|
end
|
@@ -0,0 +1,70 @@
|
|
1
|
+
require "neovim/logging"
|
2
|
+
|
3
|
+
module Neovim
|
4
|
+
# @api private
|
5
|
+
class Message
|
6
|
+
def self.from_array((kind, *payload))
|
7
|
+
case kind
|
8
|
+
when 0
|
9
|
+
request(*payload)
|
10
|
+
when 1
|
11
|
+
reqid, (_, error), value = payload
|
12
|
+
response(reqid, error, value)
|
13
|
+
when 2
|
14
|
+
notification(*payload)
|
15
|
+
else
|
16
|
+
raise "Unknown message type #{kind.inspect}"
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
def self.request(id, method, args)
|
21
|
+
Request.new(id, method, args)
|
22
|
+
end
|
23
|
+
|
24
|
+
def self.response(request_id, error, value)
|
25
|
+
Response.new(request_id, error, value)
|
26
|
+
end
|
27
|
+
|
28
|
+
def self.notification(method, args)
|
29
|
+
Notification.new(method, args)
|
30
|
+
end
|
31
|
+
|
32
|
+
Request = Struct.new(:id, :method_name, :arguments) do
|
33
|
+
def to_a
|
34
|
+
[0, id, method_name, arguments]
|
35
|
+
end
|
36
|
+
|
37
|
+
def received(_)
|
38
|
+
yield self
|
39
|
+
end
|
40
|
+
|
41
|
+
def sync?
|
42
|
+
true
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
Response = Struct.new(:request_id, :error, :value) do
|
47
|
+
def to_a
|
48
|
+
[1, request_id, error, value]
|
49
|
+
end
|
50
|
+
|
51
|
+
def received(handlers)
|
52
|
+
handlers.delete(request_id).call(self)
|
53
|
+
end
|
54
|
+
end
|
55
|
+
|
56
|
+
Notification = Struct.new(:method_name, :arguments) do
|
57
|
+
def to_a
|
58
|
+
[2, method_name, arguments]
|
59
|
+
end
|
60
|
+
|
61
|
+
def received(_)
|
62
|
+
yield self
|
63
|
+
end
|
64
|
+
|
65
|
+
def sync?
|
66
|
+
false
|
67
|
+
end
|
68
|
+
end
|
69
|
+
end
|
70
|
+
end
|
data/lib/neovim/plugin.rb
CHANGED
@@ -3,10 +3,9 @@ require "neovim/plugin/dsl"
|
|
3
3
|
module Neovim
|
4
4
|
# @api private
|
5
5
|
class Plugin
|
6
|
-
attr_accessor :handlers, :setup_blocks
|
6
|
+
attr_accessor :handlers, :setup_blocks, :script_host
|
7
7
|
attr_reader :source
|
8
8
|
|
9
|
-
# Entrypoint to the +Neovim.plugin+ DSL.
|
10
9
|
def self.from_config_block(source)
|
11
10
|
new(source).tap do |instance|
|
12
11
|
yield DSL.new(instance) if block_given?
|
@@ -14,21 +13,24 @@ module Neovim
|
|
14
13
|
end
|
15
14
|
|
16
15
|
def initialize(source)
|
17
|
-
@handlers = []
|
18
16
|
@source = source
|
17
|
+
@handlers = []
|
19
18
|
@setup_blocks = []
|
19
|
+
@script_host = false
|
20
20
|
end
|
21
21
|
|
22
|
-
# Return specs used by +nvim+ to register plugins.
|
23
22
|
def specs
|
24
23
|
@handlers.inject([]) do |acc, handler|
|
25
24
|
handler.qualified? ? acc + [handler.to_spec] : acc
|
26
25
|
end
|
27
26
|
end
|
28
27
|
|
29
|
-
# Run all registered setup blocks.
|
30
28
|
def setup(client)
|
31
29
|
@setup_blocks.each { |bl| bl.call(client) }
|
32
30
|
end
|
31
|
+
|
32
|
+
def script_host?
|
33
|
+
!!@script_host
|
34
|
+
end
|
33
35
|
end
|
34
36
|
end
|
data/lib/neovim/plugin/dsl.rb
CHANGED
@@ -68,6 +68,12 @@ module Neovim
|
|
68
68
|
|
69
69
|
private
|
70
70
|
|
71
|
+
# Mark this plugin as the Ruby script host started by nvim. Should only
|
72
|
+
# be used in +Neovim::RubyProvider+.
|
73
|
+
def script_host!
|
74
|
+
@plugin.script_host = true
|
75
|
+
end
|
76
|
+
|
71
77
|
# Register a setup block to run once before the host starts. The block
|
72
78
|
# should expect to receive a single argument, a +Neovim::Client+.
|
73
79
|
#
|
@@ -85,14 +91,14 @@ module Neovim
|
|
85
91
|
@plugin.handlers.push(Handler.unqualified(name, block))
|
86
92
|
end
|
87
93
|
|
88
|
-
def register_handler(type, name,
|
94
|
+
def register_handler(type, name, options, block)
|
89
95
|
if type == :autocmd
|
90
|
-
options =
|
96
|
+
options = options.dup
|
91
97
|
else
|
92
|
-
options = standardize(
|
98
|
+
options = standardize(options.dup)
|
93
99
|
end
|
94
100
|
|
95
|
-
sync = options.delete(:sync)
|
101
|
+
sync = !!options.delete(:sync)
|
96
102
|
|
97
103
|
@plugin.handlers.push(
|
98
104
|
Handler.new(@plugin.source, type, name, sync, options, block)
|
@@ -5,22 +5,22 @@ module Neovim
|
|
5
5
|
attr_reader :block
|
6
6
|
|
7
7
|
def self.unqualified(name, block)
|
8
|
-
new(nil, nil, name, true, {:
|
8
|
+
new(nil, nil, name, true, {qualified: false}, block)
|
9
9
|
end
|
10
10
|
|
11
11
|
def initialize(source, type, name, sync, options, block)
|
12
12
|
@source = source
|
13
13
|
@type = type.to_sym if type.respond_to?(:to_sym)
|
14
14
|
@name = name.to_s
|
15
|
-
@sync =
|
15
|
+
@sync = sync
|
16
16
|
@options = options
|
17
|
-
@block = block ||
|
17
|
+
@block = block || -> {}
|
18
18
|
@qualified =
|
19
19
|
options.key?(:qualified) ? options.delete(:qualified) : true
|
20
20
|
end
|
21
21
|
|
22
22
|
def sync?
|
23
|
-
|
23
|
+
!!@sync
|
24
24
|
end
|
25
25
|
|
26
26
|
def qualified?
|
@@ -40,10 +40,10 @@ module Neovim
|
|
40
40
|
|
41
41
|
def to_spec
|
42
42
|
{
|
43
|
-
:
|
44
|
-
:
|
45
|
-
:
|
46
|
-
:
|
43
|
+
type: @type,
|
44
|
+
name: @name,
|
45
|
+
sync: @sync,
|
46
|
+
opts: @options
|
47
47
|
}
|
48
48
|
end
|
49
49
|
|
data/lib/neovim/remote_object.rb
CHANGED
@@ -1,3 +1,5 @@
|
|
1
|
+
require "set"
|
2
|
+
|
1
3
|
module Neovim
|
2
4
|
# @abstract Superclass for all +nvim+ remote objects.
|
3
5
|
#
|
@@ -23,21 +25,21 @@ module Neovim
|
|
23
25
|
|
24
26
|
# Intercept method calls and delegate to appropriate RPC methods.
|
25
27
|
def method_missing(method_name, *args)
|
26
|
-
if func = @api.function_for_object_method(self, method_name)
|
28
|
+
if (func = @api.function_for_object_method(self, method_name))
|
27
29
|
func.call(@session, @index, *args)
|
28
30
|
else
|
29
31
|
super
|
30
32
|
end
|
31
33
|
end
|
32
34
|
|
33
|
-
# Extend +
|
34
|
-
def
|
35
|
+
# Extend +respond_to_missing?+ to support RPC methods.
|
36
|
+
def respond_to_missing?(method_name, *)
|
35
37
|
super || rpc_methods.include?(method_name.to_sym)
|
36
38
|
end
|
37
39
|
|
38
40
|
# Extend +methods+ to include RPC methods
|
39
41
|
def methods(*args)
|
40
|
-
super | rpc_methods
|
42
|
+
super | rpc_methods.to_a
|
41
43
|
end
|
42
44
|
|
43
45
|
# Extend +==+ to only look at class and index.
|
@@ -48,7 +50,8 @@ module Neovim
|
|
48
50
|
private
|
49
51
|
|
50
52
|
def rpc_methods
|
51
|
-
@
|
53
|
+
@rpc_methods ||=
|
54
|
+
@api.functions_for_object(self).map(&:method_name).to_set
|
52
55
|
end
|
53
56
|
end
|
54
57
|
end
|
data/lib/neovim/ruby_provider.rb
CHANGED
@@ -1,6 +1,8 @@
|
|
1
1
|
require "neovim/ruby_provider/vim"
|
2
|
+
require "neovim/ruby_provider/object_ext"
|
2
3
|
require "neovim/ruby_provider/buffer_ext"
|
3
4
|
require "neovim/ruby_provider/window_ext"
|
5
|
+
require "stringio"
|
4
6
|
|
5
7
|
module Neovim
|
6
8
|
# This class is used to define a +Neovim::Plugin+ to act as a backend for the
|
@@ -13,28 +15,20 @@ module Neovim
|
|
13
15
|
Thread.abort_on_exception = true
|
14
16
|
|
15
17
|
Neovim.plugin do |plug|
|
18
|
+
plug.__send__(:script_host!)
|
19
|
+
|
16
20
|
__define_setup(plug)
|
17
21
|
__define_ruby_execute(plug)
|
22
|
+
__define_ruby_eval(plug)
|
18
23
|
__define_ruby_execute_file(plug)
|
19
24
|
__define_ruby_do_range(plug)
|
20
25
|
__define_ruby_chdir(plug)
|
21
26
|
end
|
22
27
|
end
|
23
28
|
|
24
|
-
#
|
25
|
-
#
|
26
|
-
# 1. Monkeypatch +$stdout+ and +$stderr+ to write to +nvim+.
|
27
|
-
# 2. Define the +DirChanged+ event to update the provider's pwd.
|
29
|
+
# Define the +DirChanged+ event to update the provider's pwd.
|
28
30
|
def self.__define_setup(plug)
|
29
31
|
plug.__send__(:setup) do |client|
|
30
|
-
$stdout.define_singleton_method(:write) do |string|
|
31
|
-
client.out_write(string + "\n")
|
32
|
-
end
|
33
|
-
|
34
|
-
$stderr.define_singleton_method(:write) do |string|
|
35
|
-
client.err_writeln(string)
|
36
|
-
end
|
37
|
-
|
38
32
|
begin
|
39
33
|
cid = client.api.channel_id
|
40
34
|
client.command("au DirChanged * call rpcrequest(#{cid}, 'ruby_chdir', v:event)")
|
@@ -52,12 +46,26 @@ module Neovim
|
|
52
46
|
def self.__define_ruby_execute(plug)
|
53
47
|
plug.__send__(:rpc, :ruby_execute) do |nvim, ruby|
|
54
48
|
__wrap_client(nvim) do
|
55
|
-
eval(ruby, TOPLEVEL_BINDING, "
|
49
|
+
eval(ruby, TOPLEVEL_BINDING, "ruby_execute")
|
56
50
|
end
|
51
|
+
nil
|
57
52
|
end
|
58
53
|
end
|
59
54
|
private_class_method :__define_ruby_execute
|
60
55
|
|
56
|
+
# Evaluate the provided Ruby code, exposing the +Vim+ constant for
|
57
|
+
# interactions with the editor and returning the value.
|
58
|
+
#
|
59
|
+
# This is used by the +:rubyeval+ command.
|
60
|
+
def self.__define_ruby_eval(plug)
|
61
|
+
plug.__send__(:rpc, :ruby_eval) do |nvim, ruby|
|
62
|
+
__wrap_client(nvim) do
|
63
|
+
eval(ruby, TOPLEVEL_BINDING, "ruby_eval")
|
64
|
+
end
|
65
|
+
end
|
66
|
+
end
|
67
|
+
private_class_method :__define_ruby_eval
|
68
|
+
|
61
69
|
# Evaluate the provided Ruby file, exposing the +Vim+ constant for
|
62
70
|
# interactions with the editor.
|
63
71
|
#
|
@@ -65,6 +73,7 @@ module Neovim
|
|
65
73
|
def self.__define_ruby_execute_file(plug)
|
66
74
|
plug.__send__(:rpc, :ruby_execute_file) do |nvim, path|
|
67
75
|
__wrap_client(nvim) { load(path) }
|
76
|
+
nil
|
68
77
|
end
|
69
78
|
end
|
70
79
|
private_class_method :__define_ruby_execute_file
|
@@ -83,14 +92,15 @@ module Neovim
|
|
83
92
|
__start, __stop, __ruby = __args
|
84
93
|
__buffer = __nvim.get_current_buf
|
85
94
|
|
86
|
-
__update_lines_in_chunks(__buffer, __start, __stop,
|
95
|
+
__update_lines_in_chunks(__buffer, __start, __stop, 1_000) do |__lines|
|
87
96
|
__lines.map do |__line|
|
88
97
|
$_ = __line
|
89
|
-
eval(__ruby, binding, "
|
98
|
+
eval(__ruby, binding, "ruby_do_range")
|
90
99
|
$_
|
91
100
|
end
|
92
101
|
end
|
93
102
|
end
|
103
|
+
nil
|
94
104
|
end
|
95
105
|
end
|
96
106
|
private_class_method :__define_ruby_do_range
|
@@ -107,29 +117,45 @@ module Neovim
|
|
107
117
|
Vim.__refresh_globals(client)
|
108
118
|
|
109
119
|
__with_exception_handling(client) do
|
110
|
-
|
120
|
+
__with_std_streams(client) do
|
121
|
+
yield
|
122
|
+
end
|
111
123
|
end
|
112
|
-
nil
|
113
124
|
end
|
114
125
|
private_class_method :__wrap_client
|
115
126
|
|
116
127
|
def self.__with_exception_handling(client)
|
128
|
+
yield
|
129
|
+
rescue ScriptError, StandardError => e
|
130
|
+
msg = [e.class, e.message].join(": ")
|
131
|
+
client.err_writeln(msg)
|
132
|
+
end
|
133
|
+
private_class_method :__with_exception_handling
|
134
|
+
|
135
|
+
def self.__with_std_streams(client)
|
136
|
+
old_stdout = $stdout.dup
|
137
|
+
old_stderr = $stderr.dup
|
138
|
+
|
139
|
+
$stdout, $stderr = StringIO.new, StringIO.new
|
140
|
+
|
117
141
|
begin
|
118
|
-
yield
|
119
|
-
|
120
|
-
|
121
|
-
|
122
|
-
|
123
|
-
|
142
|
+
yield.tap do
|
143
|
+
client.out_write($stdout.string + $/) if $stdout.size > 0
|
144
|
+
client.err_writeln($stderr.string) if $stderr.size > 0
|
145
|
+
end
|
146
|
+
ensure
|
147
|
+
$stdout = old_stdout
|
148
|
+
$stderr = old_stderr
|
124
149
|
end
|
125
150
|
end
|
151
|
+
private_class_method :__with_std_streams
|
126
152
|
|
127
153
|
def self.__update_lines_in_chunks(buffer, start, stop, size)
|
128
154
|
(start..stop).each_slice(size) do |linenos|
|
129
|
-
|
130
|
-
lines = buffer.get_lines(
|
155
|
+
start, stop = linenos[0] - 1, linenos[-1]
|
156
|
+
lines = buffer.get_lines(start, stop, false)
|
131
157
|
|
132
|
-
buffer.set_lines(
|
158
|
+
buffer.set_lines(start, stop, false, yield(lines))
|
133
159
|
end
|
134
160
|
end
|
135
161
|
private_class_method :__update_lines_in_chunks
|