neovim 0.2.2 → 0.2.3
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.travis.yml +1 -1
- data/CHANGELOG.md +5 -0
- data/README.md +5 -7
- data/Rakefile +16 -0
- data/lib/neovim.rb +9 -23
- data/lib/neovim/api.rb +1 -0
- data/lib/neovim/async_session.rb +3 -1
- data/lib/neovim/buffer.rb +5 -1
- data/lib/neovim/client.rb +4 -5
- data/lib/neovim/current.rb +2 -0
- data/lib/neovim/event_loop.rb +15 -2
- data/lib/neovim/host.rb +85 -41
- data/lib/neovim/host/loader.rb +39 -0
- data/lib/neovim/line_range.rb +8 -0
- data/lib/neovim/logging.rb +1 -0
- data/lib/neovim/msgpack_stream.rb +4 -2
- data/lib/neovim/notification.rb +1 -0
- data/lib/neovim/plugin.rb +1 -0
- data/lib/neovim/request.rb +1 -0
- data/lib/neovim/ruby_provider.rb +2 -0
- data/lib/neovim/session.rb +3 -1
- data/lib/neovim/version.rb +1 -1
- data/spec/helper.rb +1 -0
- data/spec/neovim/buffer_spec.rb +20 -0
- data/spec/neovim/client_spec.rb +1 -0
- data/spec/neovim/current_spec.rb +1 -0
- data/spec/neovim/host/loader_spec.rb +47 -0
- data/spec/neovim/host_spec.rb +116 -28
- data/spec/neovim/line_range_spec.rb +43 -1
- data/spec/neovim/remote_object_spec.rb +6 -3
- data/spec/neovim/ruby_provider/buffer_ext_spec.rb +2 -0
- data/spec/neovim/ruby_provider/window_ext_spec.rb +2 -0
- data/spec/neovim/session_spec.rb +3 -2
- data/spec/neovim/window_spec.rb +14 -3
- data/spec/neovim_spec.rb +16 -13
- metadata +6 -5
- data/lib/neovim/manifest.rb +0 -89
- data/spec/neovim/manifest_spec.rb +0 -137
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: f815ff4bec0348ba8b77aa4f9b04197e8a521655
|
4
|
+
data.tar.gz: 149067ce655eb2b13102f9d68b0ef635668a3578
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: a0b76436db1b7523be49ecfb8be84785f3420a0eeeea294b38f6173b94136a5d60cd02f8c9dd3ff6d209bf728dc1e042c1faf1c5b0a24239a199a3099a5b141b
|
7
|
+
data.tar.gz: e7048d7300227a7effc924d3248798b0669471dfa56820eac798a0300f3cc3545bad333d14d37c682b61b67d3cbf185f9d40c356c17491ff8288706551a2da46
|
data/.travis.yml
CHANGED
data/CHANGELOG.md
CHANGED
@@ -1,3 +1,8 @@
|
|
1
|
+
# 0.2.3
|
2
|
+
- Detach child processes in `Neovim::EventLoop.child`
|
3
|
+
- Improve performance/compatibility of `Buffer#append`
|
4
|
+
- Various improvements around `Host` loading
|
5
|
+
|
1
6
|
# 0.2.2
|
2
7
|
- Make `VIM` constant a module instead of a class
|
3
8
|
- Make `Client#set_option` accept a single string argument
|
data/README.md
CHANGED
@@ -7,7 +7,7 @@
|
|
7
7
|
|
8
8
|
Ruby bindings for [Neovim](https://github.com/neovim/neovim).
|
9
9
|
|
10
|
-
*Warning*: This project
|
10
|
+
*Warning*: This project follows [Semantic Versioning](http://semver.org/), thus its API should be considered unstable until it reaches v1.0.0 ([spec](http://semver.org/#spec-item-4)).
|
11
11
|
|
12
12
|
## Installation
|
13
13
|
|
@@ -25,20 +25,20 @@ Or install it yourself as:
|
|
25
25
|
|
26
26
|
## Usage
|
27
27
|
|
28
|
-
You can control a running `nvim` process by connecting to `$NVIM_LISTEN_ADDRESS`.
|
28
|
+
You can control a running `nvim` process by connecting to `$NVIM_LISTEN_ADDRESS`. For example, to connect to `nvim` over a UNIX domain socket, start it up like this:
|
29
29
|
|
30
30
|
```shell
|
31
31
|
$ NVIM_LISTEN_ADDRESS=/tmp/nvim.sock nvim
|
32
32
|
```
|
33
33
|
|
34
|
-
You can then connect to that socket to get a `Neovim::Client`:
|
34
|
+
You can then connect to that socket path to get a `Neovim::Client`:
|
35
35
|
|
36
36
|
```ruby
|
37
37
|
require "neovim"
|
38
38
|
client = Neovim.attach_unix("/tmp/nvim.sock")
|
39
39
|
```
|
40
40
|
|
41
|
-
|
41
|
+
Refer to the [`Neovim` docs](http://www.rubydoc.info/github/alexgenco/neovim-ruby/master/Neovim) for other ways to connect to `nvim`, and the [`Neovim::Client` docs](http://www.rubydoc.info/github/alexgenco/neovim-ruby/master/Neovim/Client) for a summary of the client interface.
|
42
42
|
|
43
43
|
### Plugins
|
44
44
|
|
@@ -68,9 +68,7 @@ Neovim.plugin do |plug|
|
|
68
68
|
end
|
69
69
|
```
|
70
70
|
|
71
|
-
|
72
|
-
|
73
|
-
Neovim also supports the legacy Vim commands `:ruby`, `:rubyfile`, and `:rubydo`. A detailed description of their usage can be found with `:help ruby`.
|
71
|
+
Ruby plugins go in the `$VIMRUNTIME/rplugin/ruby` directory, and are auto-loaded after calling `:UpdateRemotePlugins`. Refer to the [`Neovim::Plugin::DSL` docs](http://www.rubydoc.info/github/alexgenco/neovim-ruby/master/Neovim/Plugin/DSL) for a more complete overview.
|
74
72
|
|
75
73
|
## Links
|
76
74
|
|
data/Rakefile
CHANGED
@@ -14,9 +14,25 @@ namespace :neovim do
|
|
14
14
|
window_docs = []
|
15
15
|
tabpage_docs = []
|
16
16
|
session = Neovim::Session.child(%w(nvim -u NONE -n))
|
17
|
+
vim_defs = Neovim::Client.instance_methods(false)
|
18
|
+
buffer_defs = Neovim::Buffer.instance_methods(false)
|
19
|
+
tabpage_defs = Neovim::Tabpage.instance_methods(false)
|
20
|
+
window_defs = Neovim::Window.instance_methods(false)
|
17
21
|
|
18
22
|
session.request(:vim_get_api_info)[1]["functions"].each do |func|
|
19
23
|
prefix, method_name = func["name"].split("_", 2)
|
24
|
+
|
25
|
+
case prefix
|
26
|
+
when "vim"
|
27
|
+
next if vim_defs.include?(method_name.to_sym)
|
28
|
+
when "buffer"
|
29
|
+
next if buffer_defs.include?(method_name.to_sym)
|
30
|
+
when "tabpage"
|
31
|
+
next if tabpage_defs.include?(method_name.to_sym)
|
32
|
+
when "window"
|
33
|
+
next if window_defs.include?(method_name.to_sym)
|
34
|
+
end
|
35
|
+
|
20
36
|
return_type = func["return_type"]
|
21
37
|
params = func["parameters"]
|
22
38
|
params.shift unless prefix == "vim"
|
data/lib/neovim.rb
CHANGED
@@ -54,16 +54,6 @@ require "neovim/version"
|
|
54
54
|
# @see Client
|
55
55
|
# @see Plugin::DSL
|
56
56
|
module Neovim
|
57
|
-
class << self
|
58
|
-
# @api private
|
59
|
-
# @return [Manifest, nil]
|
60
|
-
attr_accessor :__configured_plugin_manifest
|
61
|
-
|
62
|
-
# @api private
|
63
|
-
# @return [String, nil]
|
64
|
-
attr_accessor :__configured_plugin_path
|
65
|
-
end
|
66
|
-
|
67
57
|
# Connect to a running +nvim+ instance over TCP.
|
68
58
|
#
|
69
59
|
# @param host [String] The hostname or IP address
|
@@ -92,19 +82,6 @@ module Neovim
|
|
92
82
|
Client.new Session.child(argv)
|
93
83
|
end
|
94
84
|
|
95
|
-
# Define an +nvim+ remote plugin using the plugin DSL.
|
96
|
-
#
|
97
|
-
# @yield [Plugin::DSL]
|
98
|
-
# @return [Plugin]
|
99
|
-
# @see Plugin::DSL
|
100
|
-
def self.plugin(&block)
|
101
|
-
Plugin.from_config_block(__configured_plugin_path, &block).tap do |plugin|
|
102
|
-
if __configured_plugin_manifest.respond_to?(:register)
|
103
|
-
__configured_plugin_manifest.register(plugin)
|
104
|
-
end
|
105
|
-
end
|
106
|
-
end
|
107
|
-
|
108
85
|
# Start a plugin host. This is called by the +nvim-ruby-host+ executable,
|
109
86
|
# which is spawned by +nvim+ to discover and run Ruby plugins, and acts as
|
110
87
|
# the bridge between +nvim+ and the plugin.
|
@@ -116,6 +93,15 @@ module Neovim
|
|
116
93
|
Host.load_from_files(rplugin_paths).run
|
117
94
|
end
|
118
95
|
|
96
|
+
# Placeholder method for exposing the remote plugin DSL. This gets
|
97
|
+
# temporarily overwritten in +Host#load_files+.
|
98
|
+
#
|
99
|
+
# @see Host#load_files
|
100
|
+
# @see Plugin::DSL
|
101
|
+
def self.plugin
|
102
|
+
raise "Can't call Neovim.plugin outside of a plugin host."
|
103
|
+
end
|
104
|
+
|
119
105
|
# Set the Neovim global logger.
|
120
106
|
#
|
121
107
|
# @param logger [Logger] The target logger
|
data/lib/neovim/api.rb
CHANGED
data/lib/neovim/async_session.rb
CHANGED
@@ -6,6 +6,8 @@ module Neovim
|
|
6
6
|
# Handles formatting RPC requests and writing them to the
|
7
7
|
# +MsgpackStream+. This exposes an asynchronous API, in which responses
|
8
8
|
# are handled in callbacks.
|
9
|
+
#
|
10
|
+
# @api private
|
9
11
|
class AsyncSession
|
10
12
|
include Logging
|
11
13
|
|
@@ -72,7 +74,7 @@ module Neovim
|
|
72
74
|
end
|
73
75
|
end
|
74
76
|
rescue => e
|
75
|
-
fatal("got unexpected error #{e}")
|
77
|
+
fatal("got unexpected error #{e.inspect}")
|
76
78
|
debug(e.backtrace.join("\n"))
|
77
79
|
end
|
78
80
|
|
data/lib/neovim/buffer.rb
CHANGED
@@ -97,7 +97,11 @@ module Neovim
|
|
97
97
|
# @param str [String]
|
98
98
|
# @return [String]
|
99
99
|
def append(index, str)
|
100
|
-
|
100
|
+
if index < 0
|
101
|
+
raise ArgumentError, "Index out of bounds"
|
102
|
+
else
|
103
|
+
lines.insert(index, str)
|
104
|
+
end
|
101
105
|
str
|
102
106
|
end
|
103
107
|
|
data/lib/neovim/client.rb
CHANGED
@@ -88,6 +88,10 @@ module Neovim
|
|
88
88
|
end
|
89
89
|
end
|
90
90
|
|
91
|
+
def shutdown
|
92
|
+
@session.shutdown
|
93
|
+
end
|
94
|
+
|
91
95
|
private
|
92
96
|
|
93
97
|
def rpc_methods
|
@@ -176,11 +180,6 @@ module Neovim
|
|
176
180
|
@param [String] name
|
177
181
|
@return [Object]
|
178
182
|
|
179
|
-
@method set_option(name, value)
|
180
|
-
@param [String] name
|
181
|
-
@param [Object] value
|
182
|
-
@return [void]
|
183
|
-
|
184
183
|
@method out_write(str)
|
185
184
|
@param [String] str
|
186
185
|
@return [void]
|
data/lib/neovim/current.rb
CHANGED
data/lib/neovim/event_loop.rb
CHANGED
@@ -3,6 +3,8 @@ require "socket"
|
|
3
3
|
|
4
4
|
module Neovim
|
5
5
|
# The lowest level interface to reading from and writing to +nvim+.
|
6
|
+
#
|
7
|
+
# @api private
|
6
8
|
class EventLoop
|
7
9
|
include Logging
|
8
10
|
|
@@ -32,7 +34,10 @@ module Neovim
|
|
32
34
|
# @param argv [Array] The arguments to pass to the spawned process
|
33
35
|
# @return [EventLoop]
|
34
36
|
def self.child(argv)
|
35
|
-
io = IO.popen(argv | ["--embed"], "rb+")
|
37
|
+
io = IO.popen(argv | ["--embed"], "rb+").tap do |_io|
|
38
|
+
Process.detach(_io.pid)
|
39
|
+
end
|
40
|
+
|
36
41
|
new(io)
|
37
42
|
end
|
38
43
|
|
@@ -87,7 +92,7 @@ module Neovim
|
|
87
92
|
rescue EOFError
|
88
93
|
info("got EOFError")
|
89
94
|
rescue => e
|
90
|
-
fatal("got unexpected error #{e}")
|
95
|
+
fatal("got unexpected error #{e.inspect}")
|
91
96
|
debug(e.backtrace.join("\n"))
|
92
97
|
end
|
93
98
|
|
@@ -109,6 +114,14 @@ module Neovim
|
|
109
114
|
io.close
|
110
115
|
rescue IOError
|
111
116
|
end
|
117
|
+
|
118
|
+
begin
|
119
|
+
if pid = io.pid
|
120
|
+
Process.kill(:TERM, pid)
|
121
|
+
Process.waitpid(pid)
|
122
|
+
end
|
123
|
+
rescue IOError, Errno::ESRCH, Errno::ECHILD
|
124
|
+
end
|
112
125
|
end
|
113
126
|
end
|
114
127
|
end
|
data/lib/neovim/host.rb
CHANGED
@@ -1,69 +1,113 @@
|
|
1
1
|
require "neovim/logging"
|
2
|
-
require "neovim/
|
2
|
+
require "neovim/host/loader"
|
3
3
|
|
4
4
|
module Neovim
|
5
|
+
# @api private
|
5
6
|
class Host
|
6
7
|
include Logging
|
7
8
|
|
8
|
-
attr_reader :
|
9
|
+
attr_reader :handlers, :specs
|
9
10
|
|
10
|
-
#
|
11
|
-
# mutates global state on the +Neovim+ module so that +Neovim.plugin+ calls
|
12
|
-
# will be registered correctly with the provided +Manifest+.
|
13
|
-
#
|
14
|
-
# @overload load_from_files(rplugin_paths)
|
15
|
-
# @param rplugin_paths [Array<String>] The remote plugin paths.
|
16
|
-
#
|
17
|
-
# @overload load_from_files(rplugin_paths, target_manifest)
|
18
|
-
# @param rplugin_paths [Array<String>] The remote plugin paths.
|
19
|
-
# @param target_manifest [Manifest] The plugin manifest.
|
11
|
+
# Initialize and populate a +Host+ from a list of plugin paths.
|
20
12
|
#
|
13
|
+
# @param rplugin_paths [Array<String>]
|
21
14
|
# @return [Host]
|
22
|
-
# @see
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
old_path = Neovim.__configured_plugin_path
|
27
|
-
|
28
|
-
begin
|
29
|
-
Neovim.__configured_plugin_manifest = target_manifest
|
30
|
-
|
31
|
-
rplugin_paths.each do |rplugin_path|
|
32
|
-
Neovim.__configured_plugin_path = rplugin_path
|
33
|
-
Kernel.load(rplugin_path, true)
|
34
|
-
end
|
15
|
+
# @see Loader#load
|
16
|
+
def self.load_from_files(rplugin_paths, options={})
|
17
|
+
session = options.fetch(:session) { Session.stdio }
|
18
|
+
client = options.fetch(:client) { Client.new(session) }
|
35
19
|
|
36
|
-
|
37
|
-
|
38
|
-
Neovim.__configured_plugin_manifest = old_manifest
|
39
|
-
Neovim.__configured_plugin_path = old_path
|
20
|
+
new(session, client).tap do |host|
|
21
|
+
Loader.new(host).load(rplugin_paths)
|
40
22
|
end
|
41
23
|
end
|
42
24
|
|
43
|
-
def initialize(
|
44
|
-
@session = session
|
45
|
-
@
|
25
|
+
def initialize(session, client)
|
26
|
+
@session = session
|
27
|
+
@client = client
|
28
|
+
@handlers = {"poll" => poll_handler, "specs" => specs_handler}
|
29
|
+
@specs = {}
|
30
|
+
end
|
31
|
+
|
32
|
+
# Register a +Plugin+ to receive +Host+ messages.
|
33
|
+
#
|
34
|
+
# @param plugin [Plugin]
|
35
|
+
def register(plugin)
|
36
|
+
plugin.handlers.each do |handler|
|
37
|
+
@handlers[handler.qualified_name] = wrap_plugin_handler(handler)
|
38
|
+
end
|
39
|
+
|
40
|
+
@specs[plugin.source] = plugin.specs
|
46
41
|
end
|
47
42
|
|
48
|
-
# Run the event loop, passing received messages to the
|
43
|
+
# Run the event loop, passing received messages to the appropriate handler.
|
49
44
|
#
|
50
45
|
# @return [void]
|
51
46
|
def run
|
52
|
-
@session.
|
47
|
+
@session.run { |msg| handle(msg) }
|
48
|
+
rescue => e
|
49
|
+
fatal("got unexpected error #{e.inspect}")
|
50
|
+
debug(e.backtrace.join("\n"))
|
51
|
+
end
|
53
52
|
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
53
|
+
# Handle messages received from the host. Sends a +Neovim::Client+ along
|
54
|
+
# with the message to be used in plugin callbacks.
|
55
|
+
#
|
56
|
+
# @param message [Neovim::Request, Neovim::Notification]
|
57
|
+
# @param client [Neovim::Client]
|
58
|
+
def handle(message)
|
59
|
+
debug("received #{message.inspect}")
|
60
|
+
|
61
|
+
@handlers.
|
62
|
+
fetch(message.method_name, default_handler).
|
63
|
+
call(@client, message)
|
58
64
|
rescue => e
|
59
|
-
fatal("got unexpected error #{e}")
|
65
|
+
fatal("got unexpected error #{e.inspect}")
|
60
66
|
debug(e.backtrace.join("\n"))
|
61
67
|
end
|
62
68
|
|
63
69
|
private
|
64
70
|
|
65
|
-
def
|
66
|
-
@
|
71
|
+
def poll_handler
|
72
|
+
@poll_handler ||= Proc.new do |_, req|
|
73
|
+
debug("received 'poll' request #{req.inspect}")
|
74
|
+
req.respond("ok")
|
75
|
+
end
|
76
|
+
end
|
77
|
+
|
78
|
+
def specs_handler
|
79
|
+
@specs_handler ||= Proc.new do |_, req|
|
80
|
+
debug("received 'specs' request #{req.inspect}")
|
81
|
+
source = req.arguments.fetch(0)
|
82
|
+
|
83
|
+
if @specs.key?(source)
|
84
|
+
req.respond(@specs.fetch(source))
|
85
|
+
else
|
86
|
+
req.error("Unknown plugin #{source}")
|
87
|
+
end
|
88
|
+
end
|
89
|
+
end
|
90
|
+
|
91
|
+
def default_handler
|
92
|
+
@default_handler ||= Proc.new do |_, message|
|
93
|
+
if message.sync?
|
94
|
+
message.error("Unknown request #{message.method_name}")
|
95
|
+
end
|
96
|
+
end
|
97
|
+
end
|
98
|
+
|
99
|
+
def wrap_plugin_handler(handler)
|
100
|
+
Proc.new do |client, message|
|
101
|
+
begin
|
102
|
+
debug("received #{message.inspect}")
|
103
|
+
args = message.arguments.flatten(1)
|
104
|
+
result = handler.call(client, *args)
|
105
|
+
message.respond(result) if message.sync?
|
106
|
+
rescue => e
|
107
|
+
warn("got unexpected error #{e.inspect}")
|
108
|
+
message.error(e.message) if message.sync?
|
109
|
+
end
|
110
|
+
end
|
67
111
|
end
|
68
112
|
end
|
69
113
|
end
|
@@ -0,0 +1,39 @@
|
|
1
|
+
module Neovim
|
2
|
+
class Host
|
3
|
+
# @api private
|
4
|
+
class Loader
|
5
|
+
def initialize(host)
|
6
|
+
@host = host
|
7
|
+
end
|
8
|
+
|
9
|
+
# Load the provided Ruby files while temporarily overriding
|
10
|
+
# +Neovim.plugin+ to expose the remote plugin DSL and register the result
|
11
|
+
# to the host.
|
12
|
+
#
|
13
|
+
# @param paths [Array<String>]
|
14
|
+
def load(paths)
|
15
|
+
paths.each do |path|
|
16
|
+
override_plugin_method(path) do
|
17
|
+
Kernel.load(path, true)
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
private
|
23
|
+
|
24
|
+
def override_plugin_method(path)
|
25
|
+
old_plugin_def = Neovim.method(:plugin)
|
26
|
+
at_host = @host
|
27
|
+
|
28
|
+
Neovim.define_singleton_method(:plugin) do |&block|
|
29
|
+
plugin = Plugin.from_config_block(path, &block)
|
30
|
+
at_host.register(plugin)
|
31
|
+
end
|
32
|
+
|
33
|
+
yield
|
34
|
+
ensure
|
35
|
+
Neovim.define_singleton_method(:plugin, &old_plugin_def)
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|