[DRE-commits] [ruby-neovim] 03/06: New upstream version 0.3.1

Jason Pleau jpleau-guest at moszumanska.debian.org
Mon Dec 5 00:45:35 UTC 2016


This is an automated email from the git hooks/post-receive script.

jpleau-guest pushed a commit to branch master
in repository ruby-neovim.

commit 6edefd702b4c4e58d8d0de62e7f05056b901f0aa
Author: Jason Pleau <jason at jpleau.ca>
Date:   Thu Oct 13 22:17:17 2016 -0400

    New upstream version 0.3.1
---
 CHANGELOG.md                                 |  8 +++
 Gemfile                                      |  1 +
 README.md                                    |  8 ++-
 Rakefile                                     | 76 ++------------------------
 bin/neovim-ruby-host                         |  5 +-
 lib/neovim.rb                                | 20 ++-----
 lib/neovim/buffer.rb                         | 21 ++++++++
 lib/neovim/client.rb                         | 35 ++++++++++++
 lib/neovim/host.rb                           | 10 ++--
 lib/neovim/host/loader.rb                    |  2 +
 lib/neovim/line_range.rb                     |  2 +-
 lib/neovim/logging.rb                        | 15 +++---
 lib/neovim/plugin/dsl.rb                     |  2 +-
 lib/neovim/ruby_provider.rb                  | 17 +++---
 lib/neovim/ruby_provider/buffer_ext.rb       |  6 +--
 lib/neovim/ruby_provider/vim.rb              |  7 ++-
 lib/neovim/ruby_provider/window_ext.rb       |  6 +--
 lib/neovim/session.rb                        |  4 +-
 lib/neovim/session/api.rb                    |  8 ++-
 lib/neovim/session/event_loop.rb             | 16 ++----
 lib/neovim/session/serializer.rb             |  4 +-
 lib/neovim/tabpage.rb                        |  6 +++
 lib/neovim/version.rb                        |  2 +-
 lib/neovim/window.rb                         | 20 ++++++-
 script/generate_docs                         | 71 +++++++++++++++++++++++++
 {bin => script}/j2mp                         |  0
 {bin => script}/mp2j                         |  0
 spec/acceptance/neovim-ruby-host_spec.rb     |  7 +--
 spec/acceptance/ruby_provider_spec.rb        | 50 ++++++------------
 spec/helper.rb                               | 79 +++++++++++++++-------------
 spec/neovim/buffer_spec.rb                   |  2 +-
 spec/neovim/client_spec.rb                   |  2 +-
 spec/neovim/current_spec.rb                  |  2 +-
 spec/neovim/host/loader_spec.rb              |  2 +
 spec/neovim/host_spec.rb                     | 30 +++++++++--
 spec/neovim/line_range_spec.rb               |  4 +-
 spec/neovim/logging_spec.rb                  | 56 ++++++++++++++++++++
 spec/neovim/plugin_spec.rb                   |  9 ++++
 spec/neovim/remote_object_spec.rb            |  6 ++-
 spec/neovim/ruby_provider/buffer_ext_spec.rb | 10 ++--
 spec/neovim/ruby_provider/vim_spec.rb        | 32 +++++++++++
 spec/neovim/ruby_provider/window_ext_spec.rb | 30 ++++++++---
 spec/neovim/session/api_spec.rb              | 29 ++++++++--
 spec/neovim/session/event_loop_spec.rb       | 55 ++++++++++++++++++-
 spec/neovim/session/notification_spec.rb     | 20 +++++++
 spec/neovim/session/request_spec.rb          | 36 +++++++++++++
 spec/neovim/session/rpc_spec.rb              | 12 +++++
 spec/neovim/session/serializer_spec.rb       | 14 +++++
 spec/neovim/session_spec.rb                  |  8 +--
 spec/neovim/window_spec.rb                   | 18 ++++++-
 spec/neovim_spec.rb                          | 24 ++-------
 51 files changed, 637 insertions(+), 272 deletions(-)

diff --git a/CHANGELOG.md b/CHANGELOG.md
index e771aa1..a1c350c 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,3 +1,11 @@
+# 0.3.1
+- Remove window caching to fix incompatibilities with command-t
+- Add `Vim` module alias
+- Fix `Window.count` and `Window.[]` to work with tabpages
+- Fix `EventLoop.child` bug with repeated arguments
+- Fix `Window#cursor=` incompatibilities
+- Make `Neovim.attach_child` have default argv of `["nvim"]`
+
 # 0.3.0
 - Mark `Plugin::DSL#rpc` private
 - Rename Session constants:
diff --git a/Gemfile b/Gemfile
index dd022d0..8e6e9e4 100644
--- a/Gemfile
+++ b/Gemfile
@@ -6,6 +6,7 @@ group :development do
     gem "coveralls"
     gem "pry-byebug"
   else
+    gem "term-ansicolor", "1.3.2"
     gem "coveralls", "0.8.13"
     gem "pry-debugger"
   end
diff --git a/README.md b/README.md
index 66dcc7d..b7a5e65 100644
--- a/README.md
+++ b/README.md
@@ -1,9 +1,11 @@
 # Neovim Ruby
 
-[![Gem Version](https://badge.fury.io/rb/neovim.svg)](https://badge.fury.io/rb/neovim)
 [![Travis](https://travis-ci.org/alexgenco/neovim-ruby.svg?branch=master)](https://travis-ci.org/alexgenco/neovim-ruby)
-[![Coverage Status](https://coveralls.io/repos/alexgenco/neovim-ruby/badge.png)](https://coveralls.io/r/alexgenco/neovim-ruby)
+[![Coverage Status](https://coveralls.io/repos/alexgenco/neovim-ruby/badge.svg)](https://coveralls.io/r/alexgenco/neovim-ruby)
 [![Code Climate](https://codeclimate.com/github/alexgenco/neovim-ruby/badges/gpa.svg)](https://codeclimate.com/github/alexgenco/neovim-ruby)
+[![Gem Version](https://badge.fury.io/rb/neovim.svg)](https://badge.fury.io/rb/neovim)
+[![Dependency Status](https://gemnasium.com/badges/github.com/alexgenco/neovim-ruby.svg)](https://gemnasium.com/github.com/alexgenco/neovim-ruby)
+[![Inline docs](http://inch-ci.org/github/alexgenco/neovim-ruby.svg?branch=master)](http://inch-ci.org/github/alexgenco/neovim-ruby)
 
 Ruby bindings for [Neovim](https://github.com/neovim/neovim).
 
@@ -70,6 +72,8 @@ end
 
 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.
 
+### Legacy Plugin Support
+
 The Neovim gem also acts as a compatibility layer for Ruby plugins written for legacy `vim`. The `:ruby`, `:rubyfile`, and `:rubydo` commands are intended to behave the same as they did in `vim`, and their documentation can be found [here](https://neovim.io/doc/user/if_ruby.html).
 
 ## Links
diff --git a/Rakefile b/Rakefile
index 2409878..0edf84c 100644
--- a/Rakefile
+++ b/Rakefile
@@ -2,77 +2,9 @@ require "bundler/gem_tasks"
 require "rspec/core/rake_task"
 
 RSpec::Core::RakeTask.new(:spec)
+task :default => :spec
 
-namespace :neovim do
-  desc "Generate Neovim remote API docs"
-  task :generate_docs do
-    require "neovim"
-    require "pathname"
-
-    vim_docs = []
-    buffer_docs = []
-    window_docs = []
-    tabpage_docs = []
-    session = Neovim::Session.child(%w(nvim -u NONE -n))
-    vim_defs = Neovim::Client.instance_methods(false)
-    buffer_defs = Neovim::Buffer.instance_methods(false)
-    tabpage_defs = Neovim::Tabpage.instance_methods(false)
-    window_defs = Neovim::Window.instance_methods(false)
-
-    session.request(:vim_get_api_info)[1]["functions"].each do |func|
-      prefix, method_name = func["name"].split("_", 2)
-
-      case prefix
-      when "vim"
-        next if vim_defs.include?(method_name.to_sym)
-      when "buffer"
-        next if buffer_defs.include?(method_name.to_sym)
-      when "tabpage"
-        next if tabpage_defs.include?(method_name.to_sym)
-      when "window"
-        next if window_defs.include?(method_name.to_sym)
-      end
-
-      return_type = func["return_type"]
-      params = func["parameters"]
-      params.shift unless prefix == "vim"
-      param_names = params.map(&:last)
-      param_str = params.empty? ? "" : "(#{param_names.join(", ")})"
-      method_decl = "@method #{method_name}#{param_str}"
-      param_docs = params.map do |type, name|
-        "  @param [#{type}] #{name}"
-      end
-      return_doc = "  @return [#{return_type}]\n"
-      method_doc = [method_decl, *param_docs, return_doc].join("\n")
-      method_doc.gsub!(/ArrayOf\((\w+)[^)]*\)/, 'Array<\1>')
-      method_doc.gsub!(/Integer/, "Fixnum")
-
-      case prefix
-      when "vim"
-        vim_docs << method_doc
-      when "buffer"
-        buffer_docs << method_doc
-      when "tabpage"
-        tabpage_docs << method_doc
-      when "window"
-        window_docs << method_doc
-      end
-    end
-
-    lib_dir = Pathname.new(File.expand_path("../lib/neovim", __FILE__))
-    {
-      "client.rb" => vim_docs,
-      "buffer.rb" => buffer_docs,
-      "tabpage.rb" => tabpage_docs,
-      "window.rb" => window_docs,
-    }.each do |filename, docs|
-      path = lib_dir.join(filename)
-      contents = File.read(path)
-      doc_str = ["=begin", *docs, "=end"].join("\n")
-
-      File.write(path, contents.sub(/=begin.+=end/m, doc_str))
-    end
-  end
+desc "Generate Neovim remote API docs"
+task :docs do
+  sh File.expand_path("../script/generate_docs", __FILE__)
 end
-
-task :default => :spec
diff --git a/bin/neovim-ruby-host b/bin/neovim-ruby-host
index 7d95281..56905b4 100755
--- a/bin/neovim-ruby-host
+++ b/bin/neovim-ruby-host
@@ -1,5 +1,6 @@
 #!/usr/bin/env ruby
-require "neovim"
+
+require "neovim/host"
 
 ARGV.each do |arg|
   break if arg == "--"
@@ -13,5 +14,5 @@ end
 if STDIN.tty?
   abort("Can't run neovim-ruby-host interactively.")
 else
-  Neovim.start_host(ARGV)
+  Neovim::Host.run(ARGV)
 end
diff --git a/lib/neovim.rb b/lib/neovim.rb
index 0148609..7169aac 100644
--- a/lib/neovim.rb
+++ b/lib/neovim.rb
@@ -1,7 +1,6 @@
 require "neovim/client"
-require "neovim/host"
+require "neovim/logging"
 require "neovim/session"
-require "neovim/plugin"
 require "neovim/version"
 
 # The main entrypoint to the +Neovim+ gem. It allows you to connect to a
@@ -78,25 +77,14 @@ module Neovim
   # @param argv [Array] The arguments to pass to the spawned process
   # @return [Client]
   # @see Session.child
-  def self.attach_child(argv=[])
+  def self.attach_child(argv=["nvim"])
     Client.new Session.child(argv)
   end
 
-  # Start a plugin host. This is called by the +nvim-ruby-host+ executable,
-  # which is spawned by +nvim+ to discover and run Ruby plugins, and acts as
-  # the bridge between +nvim+ and the plugin.
-  #
-  # @param rplugin_paths [Array<String>] The paths to remote plugin files
-  # @return [void]
-  # @see Host
-  def self.start_host(rplugin_paths)
-    Host.load_from_files(rplugin_paths).run
-  end
-
   # Placeholder method for exposing the remote plugin DSL. This gets
-  # temporarily overwritten in +Host#load_files+.
+  # temporarily overwritten in +Host::Loader#load+.
   #
-  # @see Host#load_files
+  # @see Host::Loader#load
   # @see Plugin::DSL
   def self.plugin
     raise "Can't call Neovim.plugin outside of a plugin host."
diff --git a/lib/neovim/buffer.rb b/lib/neovim/buffer.rb
index 6963726..0acf5a4 100644
--- a/lib/neovim/buffer.rb
+++ b/lib/neovim/buffer.rb
@@ -151,22 +151,27 @@ module Neovim
 # The following methods are dynamically generated.
 =begin
 @method line_count
+  Send the +buffer_line_count+ RPC to +nvim+
   @return [Fixnum]
 
 @method get_line(index)
+  Send the +buffer_get_line+ RPC to +nvim+
   @param [Fixnum] index
   @return [String]
 
 @method set_line(index, line)
+  Send the +buffer_set_line+ RPC to +nvim+
   @param [Fixnum] index
   @param [String] line
   @return [void]
 
 @method del_line(index)
+  Send the +buffer_del_line+ RPC to +nvim+
   @param [Fixnum] index
   @return [void]
 
 @method get_line_slice(start, end, include_start, include_end)
+  Send the +buffer_get_line_slice+ RPC to +nvim+
   @param [Fixnum] start
   @param [Fixnum] end
   @param [Boolean] include_start
@@ -174,12 +179,14 @@ module Neovim
   @return [Array<String>]
 
 @method get_lines(start, end, strict_indexing)
+  Send the +buffer_get_lines+ RPC to +nvim+
   @param [Fixnum] start
   @param [Fixnum] end
   @param [Boolean] strict_indexing
   @return [Array<String>]
 
 @method set_line_slice(start, end, include_start, include_end, replacement)
+  Send the +buffer_set_line_slice+ RPC to +nvim+
   @param [Fixnum] start
   @param [Fixnum] end
   @param [Boolean] include_start
@@ -188,6 +195,7 @@ module Neovim
   @return [void]
 
 @method set_lines(start, end, strict_indexing, replacement)
+  Send the +buffer_set_lines+ RPC to +nvim+
   @param [Fixnum] start
   @param [Fixnum] end
   @param [Boolean] strict_indexing
@@ -195,50 +203,62 @@ module Neovim
   @return [void]
 
 @method get_var(name)
+  Send the +buffer_get_var+ RPC to +nvim+
   @param [String] name
   @return [Object]
 
 @method set_var(name, value)
+  Send the +buffer_set_var+ RPC to +nvim+
   @param [String] name
   @param [Object] value
   @return [Object]
 
 @method del_var(name)
+  Send the +buffer_del_var+ RPC to +nvim+
   @param [String] name
   @return [Object]
 
 @method get_option(name)
+  Send the +buffer_get_option+ RPC to +nvim+
   @param [String] name
   @return [Object]
 
 @method set_option(name, value)
+  Send the +buffer_set_option+ RPC to +nvim+
   @param [String] name
   @param [Object] value
   @return [void]
 
 @method get_number
+  Send the +buffer_get_number+ RPC to +nvim+
   @return [Fixnum]
 
 @method get_name
+  Send the +buffer_get_name+ RPC to +nvim+
   @return [String]
 
 @method set_name(name)
+  Send the +buffer_set_name+ RPC to +nvim+
   @param [String] name
   @return [void]
 
 @method is_valid
+  Send the +buffer_is_valid+ RPC to +nvim+
   @return [Boolean]
 
 @method insert(lnum, lines)
+  Send the +buffer_insert+ RPC to +nvim+
   @param [Fixnum] lnum
   @param [Array<String>] lines
   @return [void]
 
 @method get_mark(name)
+  Send the +buffer_get_mark+ RPC to +nvim+
   @param [String] name
   @return [Array<Fixnum>]
 
 @method add_highlight(src_id, hl_group, line, col_start, col_end)
+  Send the +buffer_add_highlight+ RPC to +nvim+
   @param [Fixnum] src_id
   @param [String] hl_group
   @param [Fixnum] line
@@ -247,6 +267,7 @@ module Neovim
   @return [Fixnum]
 
 @method clear_highlight(src_id, line_start, line_end)
+  Send the +buffer_clear_highlight+ RPC to +nvim+
   @param [Fixnum] src_id
   @param [Fixnum] line_start
   @param [Fixnum] line_end
diff --git a/lib/neovim/client.rb b/lib/neovim/client.rb
index 4e8872e..007c9db 100644
--- a/lib/neovim/client.rb
+++ b/lib/neovim/client.rb
@@ -105,20 +105,24 @@ module Neovim
 # The following methods are dynamically generated.
 =begin
 @method command(str)
+  Send the +vim_command+ RPC to +nvim+
   @param [String] str
   @return [void]
 
 @method feedkeys(keys, mode, escape_csi)
+  Send the +vim_feedkeys+ RPC to +nvim+
   @param [String] keys
   @param [String] mode
   @param [Boolean] escape_csi
   @return [void]
 
 @method input(keys)
+  Send the +vim_input+ RPC to +nvim+
   @param [String] keys
   @return [Fixnum]
 
 @method replace_termcodes(str, from_part, do_lt, special)
+  Send the +vim_replace_termcodes+ RPC to +nvim+
   @param [String] str
   @param [Boolean] from_part
   @param [Boolean] do_lt
@@ -126,118 +130,149 @@ module Neovim
   @return [String]
 
 @method command_output(str)
+  Send the +vim_command_output+ RPC to +nvim+
   @param [String] str
   @return [String]
 
 @method eval(str)
+  Send the +vim_eval+ RPC to +nvim+
   @param [String] str
   @return [Object]
 
 @method call_function(fname, args)
+  Send the +vim_call_function+ RPC to +nvim+
   @param [String] fname
   @param [Array] args
   @return [Object]
 
 @method strwidth(str)
+  Send the +vim_strwidth+ RPC to +nvim+
   @param [String] str
   @return [Fixnum]
 
 @method list_runtime_paths
+  Send the +vim_list_runtime_paths+ RPC to +nvim+
   @return [Array<String>]
 
 @method change_directory(dir)
+  Send the +vim_change_directory+ RPC to +nvim+
   @param [String] dir
   @return [void]
 
 @method get_current_line
+  Send the +vim_get_current_line+ RPC to +nvim+
   @return [String]
 
 @method set_current_line(line)
+  Send the +vim_set_current_line+ RPC to +nvim+
   @param [String] line
   @return [void]
 
 @method del_current_line
+  Send the +vim_del_current_line+ RPC to +nvim+
   @return [void]
 
 @method get_var(name)
+  Send the +vim_get_var+ RPC to +nvim+
   @param [String] name
   @return [Object]
 
 @method set_var(name, value)
+  Send the +vim_set_var+ RPC to +nvim+
   @param [String] name
   @param [Object] value
   @return [Object]
 
 @method del_var(name)
+  Send the +vim_del_var+ RPC to +nvim+
   @param [String] name
   @return [Object]
 
 @method get_vvar(name)
+  Send the +vim_get_vvar+ RPC to +nvim+
   @param [String] name
   @return [Object]
 
 @method get_option(name)
+  Send the +vim_get_option+ RPC to +nvim+
   @param [String] name
   @return [Object]
 
 @method out_write(str)
+  Send the +vim_out_write+ RPC to +nvim+
   @param [String] str
   @return [void]
 
 @method err_write(str)
+  Send the +vim_err_write+ RPC to +nvim+
   @param [String] str
   @return [void]
 
 @method report_error(str)
+  Send the +vim_report_error+ RPC to +nvim+
   @param [String] str
   @return [void]
 
 @method get_buffers
+  Send the +vim_get_buffers+ RPC to +nvim+
   @return [Array<Buffer>]
 
 @method get_current_buffer
+  Send the +vim_get_current_buffer+ RPC to +nvim+
   @return [Buffer]
 
 @method set_current_buffer(buffer)
+  Send the +vim_set_current_buffer+ RPC to +nvim+
   @param [Buffer] buffer
   @return [void]
 
 @method get_windows
+  Send the +vim_get_windows+ RPC to +nvim+
   @return [Array<Window>]
 
 @method get_current_window
+  Send the +vim_get_current_window+ RPC to +nvim+
   @return [Window]
 
 @method set_current_window(window)
+  Send the +vim_set_current_window+ RPC to +nvim+
   @param [Window] window
   @return [void]
 
 @method get_tabpages
+  Send the +vim_get_tabpages+ RPC to +nvim+
   @return [Array<Tabpage>]
 
 @method get_current_tabpage
+  Send the +vim_get_current_tabpage+ RPC to +nvim+
   @return [Tabpage]
 
 @method set_current_tabpage(tabpage)
+  Send the +vim_set_current_tabpage+ RPC to +nvim+
   @param [Tabpage] tabpage
   @return [void]
 
 @method subscribe(event)
+  Send the +vim_subscribe+ RPC to +nvim+
   @param [String] event
   @return [void]
 
 @method unsubscribe(event)
+  Send the +vim_unsubscribe+ RPC to +nvim+
   @param [String] event
   @return [void]
 
 @method name_to_color(name)
+  Send the +vim_name_to_color+ RPC to +nvim+
   @param [String] name
   @return [Fixnum]
 
 @method get_color_map
+  Send the +vim_get_color_map+ RPC to +nvim+
   @return [Dictionary]
 
 @method get_api_info
+  Send the +vim_get_api_info+ RPC to +nvim+
   @return [Array]
 
 =end
diff --git a/lib/neovim/host.rb b/lib/neovim/host.rb
index 8e5cf53..819cdde 100644
--- a/lib/neovim/host.rb
+++ b/lib/neovim/host.rb
@@ -1,4 +1,4 @@
-require "neovim/logging"
+require "neovim"
 require "neovim/host/loader"
 
 module Neovim
@@ -8,14 +8,16 @@ module Neovim
 
     attr_reader :handlers, :specs
 
-    # Initialize and populate a +Host+ from a list of plugin paths.
-    def self.load_from_files(rplugin_paths, options={})
+    # Start a plugin host. This is called by the +nvim-ruby-host+ executable,
+    # which is spawned by +nvim+ to discover and run Ruby plugins, and acts as
+    # the bridge between +nvim+ and the plugin.
+    def self.run(rplugin_paths, options={})
       session = options.fetch(:session) { Session.stdio }
       client = options.fetch(:client) { Client.new(session) }
 
       new(session, client).tap do |host|
         Loader.new(host).load(rplugin_paths)
-      end
+      end.run
     end
 
     def initialize(session, client)
diff --git a/lib/neovim/host/loader.rb b/lib/neovim/host/loader.rb
index 61eb57c..b09684e 100644
--- a/lib/neovim/host/loader.rb
+++ b/lib/neovim/host/loader.rb
@@ -1,3 +1,5 @@
+require "neovim/plugin"
+
 module Neovim
   class Host
     # @api private
diff --git a/lib/neovim/line_range.rb b/lib/neovim/line_range.rb
index bc2c929..440a0ed 100644
--- a/lib/neovim/line_range.rb
+++ b/lib/neovim/line_range.rb
@@ -55,7 +55,7 @@ module Neovim
           LineRange.new(
             @buffer,
             abs_line(pos),
-            abs_line(pos + len -1)
+            abs_line(pos + len - 1)
           )
         else
           @buffer.get_line(abs_line(pos))
diff --git a/lib/neovim/logging.rb b/lib/neovim/logging.rb
index 37a4e7a..91d71c9 100644
--- a/lib/neovim/logging.rb
+++ b/lib/neovim/logging.rb
@@ -2,6 +2,7 @@ require "logger"
 
 module Neovim
   # Mixed into classes for unified logging helper methods.
+  #
   # @api private
   module Logging
     class << self
@@ -9,22 +10,22 @@ module Neovim
     end
 
     # Return the value of @logger, or construct it from the environment.
-    # $NVIM_RUBY_LOG_FILE specifies a file to log to (default +STDOUT+), while
+    # $NVIM_RUBY_LOG_FILE specifies a file to log to (default +STDERR+), while
     # NVIM_RUBY_LOG_LEVEL specifies the level (default +WARN+)
-    def self.logger
+    def self.logger(env=ENV)
       return @logger if instance_variable_defined?(:@logger)
 
-      if env_file = ENV["NVIM_RUBY_LOG_FILE"]
+      if env_file = env["NVIM_RUBY_LOG_FILE"]
         @logger = Logger.new(env_file)
       else
         @logger = Logger.new(STDERR)
       end
 
-      if env_level = ENV["NVIM_RUBY_LOG_LEVEL"]
-        if Logger.const_defined?(env_level.upcase)
-          @logger.level = Logger.const_get(env_level.upcase)
-        else
+      if env_level = env["NVIM_RUBY_LOG_LEVEL"]
+        begin
           @logger.level = Integer(env_level)
+        rescue ArgumentError
+          @logger.level = Logger.const_get(env_level.upcase)
         end
       else
         @logger.level = Logger::WARN
diff --git a/lib/neovim/plugin/dsl.rb b/lib/neovim/plugin/dsl.rb
index 0318a23..35c7d48 100644
--- a/lib/neovim/plugin/dsl.rb
+++ b/lib/neovim/plugin/dsl.rb
@@ -42,7 +42,7 @@ module Neovim
       # @param options [Hash] Function options.
       # @param &block [Proc, nil] The body of the function.
       #
-      # @option options [String, Boolean] :range The range argument. 
+      # @option options [String, Boolean] :range The range argument.
       #   See +:h command-range+.
       # @option options [String] :eval An +nvim+ expression. Gets evaluated and
       #   passed as an argument to the block.
diff --git a/lib/neovim/ruby_provider.rb b/lib/neovim/ruby_provider.rb
index 0f19aee..706d60d 100644
--- a/lib/neovim/ruby_provider.rb
+++ b/lib/neovim/ruby_provider.rb
@@ -9,6 +9,8 @@ module Neovim
   #
   # @api private
   module RubyProvider
+    @__buffer_cache = {}
+
     def self.__define_plugin!
       Thread.abort_on_exception = true
 
@@ -19,7 +21,7 @@ module Neovim
       end
     end
 
-    # Evaluate the provided Ruby code, exposing the +VIM+ constant for
+    # Evaluate the provided Ruby code, exposing the +Vim+ constant for
     # interactions with the editor.
     #
     # This is used by the +:ruby+ command.
@@ -32,7 +34,7 @@ module Neovim
     end
     private_class_method :__define_ruby_execute
 
-    # Evaluate the provided Ruby file, exposing the +VIM+ constant for
+    # Evaluate the provided Ruby file, exposing the +Vim+ constant for
     # interactions with the editor.
     #
     # This is used by the +:rubyfile+ command.
@@ -82,25 +84,20 @@ module Neovim
     private_class_method :__wrap_client
 
     def self.__with_globals(client)
-      @__buffer_cache ||= {}
-      @__window_cache ||= {}
-
-      bufnr, winnr = client.evaluate("[bufnr('%'), winnr()]")
+      bufnr = client.evaluate("bufnr('%')")
 
       $curbuf = @__buffer_cache.fetch(bufnr) do
         @__buffer_cache[bufnr] = client.get_current_buffer
       end
 
-      $curwin = @__window_cache.fetch(winnr) do
-        @__window_cache[winnr] = client.get_current_window
-      end
+      $curwin = client.get_current_window
 
       yield
     end
     private_class_method :__with_globals
 
     def self.__with_vim_constant(client)
-      ::VIM.__client = client
+      ::Vim.__client = client
       yield
     end
     private_class_method :__with_vim_constant
diff --git a/lib/neovim/ruby_provider/buffer_ext.rb b/lib/neovim/ruby_provider/buffer_ext.rb
index cdb9ecc..598cd0d 100644
--- a/lib/neovim/ruby_provider/buffer_ext.rb
+++ b/lib/neovim/ruby_provider/buffer_ext.rb
@@ -3,15 +3,15 @@ require "neovim/ruby_provider/vim"
 module Neovim
   class Buffer
     def self.current
-      ::VIM.get_current_buffer
+      ::Vim.get_current_buffer
     end
 
     def self.count
-      ::VIM.get_buffers.size
+      ::Vim.get_buffers.size
     end
 
     def self.[](index)
-      ::VIM.get_buffers[index]
+      ::Vim.get_buffers[index]
     end
   end
 end
diff --git a/lib/neovim/ruby_provider/vim.rb b/lib/neovim/ruby_provider/vim.rb
index b052b55..64b3e74 100644
--- a/lib/neovim/ruby_provider/vim.rb
+++ b/lib/neovim/ruby_provider/vim.rb
@@ -1,7 +1,9 @@
 require "neovim/buffer"
 require "neovim/window"
 
-module VIM
+# The VIM module provides backwards compatibility for the legacy +:ruby+,
+# +:rubyfile+, and +:rubydo+ +vim+ functions.
+module Vim
   Buffer = ::Neovim::Buffer
   Window = ::Neovim::Window
 
@@ -9,7 +11,10 @@ module VIM
     @__client = client
   end
 
+  # Delegate all method calls to the underlying +Neovim::Client+ object.
   def self.method_missing(method, *args, &block)
     @__client.public_send(method, *args, &block)
   end
 end
+
+VIM = Vim
diff --git a/lib/neovim/ruby_provider/window_ext.rb b/lib/neovim/ruby_provider/window_ext.rb
index 1bb0af6..0465cea 100644
--- a/lib/neovim/ruby_provider/window_ext.rb
+++ b/lib/neovim/ruby_provider/window_ext.rb
@@ -3,15 +3,15 @@ require "neovim/ruby_provider/vim"
 module Neovim
   class Window
     def self.current
-      ::VIM.get_current_window
+      ::Vim.get_current_window
     end
 
     def self.count
-      ::VIM.get_windows.size
+      ::Vim.get_current_tabpage.get_windows.size
     end
 
     def self.[](index)
-      ::VIM.get_windows[index]
+      ::Vim.get_current_tabpage.get_windows[index]
     end
   end
 end
diff --git a/lib/neovim/session.rb b/lib/neovim/session.rb
index 9abbbf2..72873e4 100644
--- a/lib/neovim/session.rb
+++ b/lib/neovim/session.rb
@@ -66,8 +66,8 @@ module Neovim
     def run
       @running = true
 
-      while message = @pending_messages.shift
-        Fiber.new { yield message if block_given? }.resume
+      while pending = @pending_messages.shift
+        Fiber.new { yield pending if block_given? }.resume
       end
 
       return unless @running
diff --git a/lib/neovim/session/api.rb b/lib/neovim/session/api.rb
index 1a795b9..117737c 100644
--- a/lib/neovim/session/api.rb
+++ b/lib/neovim/session/api.rb
@@ -45,7 +45,13 @@ module Neovim
         "#<#{self.class}:0x%x @types={...} @functions={...}>" % (object_id << 1)
       end
 
-      class Function < Struct.new(:name, :async)
+      class Function
+        attr_reader :name, :async
+
+        def initialize(name, async)
+          @name, @async = name, async
+        end
+
         # Apply this function to a running RPC session. Sends either a request if
         # +async+ is +false+ or a notification if +async+ is +true+.
         def call(session, *args)
diff --git a/lib/neovim/session/event_loop.rb b/lib/neovim/session/event_loop.rb
index 6ab1686..bce6048 100644
--- a/lib/neovim/session/event_loop.rb
+++ b/lib/neovim/session/event_loop.rb
@@ -9,8 +9,6 @@ module Neovim
     class EventLoop
       include Logging
 
-      private_class_method :new
-
       # Connect to a TCP socket.
       def self.tcp(host, port)
         socket = TCPSocket.new(host, port)
@@ -24,8 +22,10 @@ module Neovim
       end
 
       # Spawn and connect to a child +nvim+ process.
-      def self.child(argv)
-        io = IO.popen(argv | ["--embed"], "rb+").tap do |_io|
+      def self.child(_argv)
+        argv = _argv.include?("--embed") ? _argv : _argv + ["--embed"]
+
+        io = IO.popen(argv, "rb+").tap do |_io|
           Process.detach(_io.pid)
         end
 
@@ -93,14 +93,6 @@ module Neovim
             io.close
           rescue IOError
           end
-
-          begin
-            if pid = io.pid
-              Process.kill(:TERM, pid)
-              Process.waitpid(pid)
-            end
-          rescue IOError, Errno::ESRCH, Errno::ECHILD
-          end
         end
       end
     end
diff --git a/lib/neovim/session/serializer.rb b/lib/neovim/session/serializer.rb
index f0c4f17..bd215ce 100644
--- a/lib/neovim/session/serializer.rb
+++ b/lib/neovim/session/serializer.rb
@@ -10,9 +10,9 @@ module Neovim
     class Serializer
       include Logging
 
-      def initialize(event_loop)
+      def initialize(event_loop, unpacker=nil)
         @event_loop = event_loop
-        @unpacker = MessagePack::Unpacker.new
+        @unpacker = unpacker || MessagePack::Unpacker.new
       end
 
       # Serialize an RPC message to and write it to the event loop.
diff --git a/lib/neovim/tabpage.rb b/lib/neovim/tabpage.rb
index 874e1e0..a2fd03e 100644
--- a/lib/neovim/tabpage.rb
+++ b/lib/neovim/tabpage.rb
@@ -6,25 +6,31 @@ module Neovim
 # The following methods are dynamically generated.
 =begin
 @method get_windows
+  Send the +tabpage_get_windows+ RPC to +nvim+
   @return [Array<Window>]
 
 @method get_var(name)
+  Send the +tabpage_get_var+ RPC to +nvim+
   @param [String] name
   @return [Object]
 
 @method set_var(name, value)
+  Send the +tabpage_set_var+ RPC to +nvim+
   @param [String] name
   @param [Object] value
   @return [Object]
 
 @method del_var(name)
+  Send the +tabpage_del_var+ RPC to +nvim+
   @param [String] name
   @return [Object]
 
 @method get_window
+  Send the +tabpage_get_window+ RPC to +nvim+
   @return [Window]
 
 @method is_valid
+  Send the +tabpage_is_valid+ RPC to +nvim+
   @return [Boolean]
 
 =end
diff --git a/lib/neovim/version.rb b/lib/neovim/version.rb
index 34551db..92d2ce4 100644
--- a/lib/neovim/version.rb
+++ b/lib/neovim/version.rb
@@ -1,3 +1,3 @@
 module Neovim
-  VERSION = Gem::Version.new("0.3.0")
+  VERSION = Gem::Version.new("0.3.1")
 end
diff --git a/lib/neovim/window.rb b/lib/neovim/window.rb
index e54490c..b470f3f 100644
--- a/lib/neovim/window.rb
+++ b/lib/neovim/window.rb
@@ -53,64 +53,82 @@ module Neovim
     # @param coords [Array(Fixnum, Fixnum)]
     # @return [Array(Fixnum, Fixnum)]
     def cursor=(coords)
-      set_cursor(coords)
+      _x, _y = coords
+      x = [_x, 1].max
+      y = [_y, 0].max + 1
+      @session.request(:vim_eval, "cursor(#{x}, #{y})")
     end
 
 # The following methods are dynamically generated.
 =begin
 @method get_buffer
+  Send the +window_get_buffer+ RPC to +nvim+
   @return [Buffer]
 
 @method get_cursor
+  Send the +window_get_cursor+ RPC to +nvim+
   @return [Array<Fixnum>]
 
 @method set_cursor(pos)
+  Send the +window_set_cursor+ RPC to +nvim+
   @param [Array<Fixnum>] pos
   @return [void]
 
 @method get_height
+  Send the +window_get_height+ RPC to +nvim+
   @return [Fixnum]
 
 @method set_height(height)
+  Send the +window_set_height+ RPC to +nvim+
   @param [Fixnum] height
   @return [void]
 
 @method get_width
+  Send the +window_get_width+ RPC to +nvim+
   @return [Fixnum]
 
 @method set_width(width)
+  Send the +window_set_width+ RPC to +nvim+
   @param [Fixnum] width
   @return [void]
 
 @method get_var(name)
+  Send the +window_get_var+ RPC to +nvim+
   @param [String] name
   @return [Object]
 
 @method set_var(name, value)
+  Send the +window_set_var+ RPC to +nvim+
   @param [String] name
   @param [Object] value
   @return [Object]
 
 @method del_var(name)
+  Send the +window_del_var+ RPC to +nvim+
   @param [String] name
   @return [Object]
 
 @method get_option(name)
+  Send the +window_get_option+ RPC to +nvim+
   @param [String] name
   @return [Object]
 
 @method set_option(name, value)
+  Send the +window_set_option+ RPC to +nvim+
   @param [String] name
   @param [Object] value
   @return [void]
 
 @method get_position
+  Send the +window_get_position+ RPC to +nvim+
   @return [Array<Fixnum>]
 
 @method get_tabpage
+  Send the +window_get_tabpage+ RPC to +nvim+
   @return [Tabpage]
 
 @method is_valid
+  Send the +window_is_valid+ RPC to +nvim+
   @return [Boolean]
 
 =end
diff --git a/script/generate_docs b/script/generate_docs
new file mode 100755
index 0000000..2007737
--- /dev/null
+++ b/script/generate_docs
@@ -0,0 +1,71 @@
+#!/usr/bin/env ruby
+
+$:.unshift File.expand_path("../../lib", __FILE__)
+
+require "neovim"
+require "pathname"
+
+vim_docs = []
+buffer_docs = []
+window_docs = []
+tabpage_docs = []
+session = Neovim::Session.child(%w(nvim -u NONE -n))
+vim_defs = Neovim::Client.instance_methods(false)
+buffer_defs = Neovim::Buffer.instance_methods(false)
+tabpage_defs = Neovim::Tabpage.instance_methods(false)
+window_defs = Neovim::Window.instance_methods(false)
+
+session.request(:vim_get_api_info)[1]["functions"].each do |func|
+  prefix, method_name = func["name"].split("_", 2)
+
+  case prefix
+  when "vim"
+    next if vim_defs.include?(method_name.to_sym)
+  when "buffer"
+    next if buffer_defs.include?(method_name.to_sym)
+  when "tabpage"
+    next if tabpage_defs.include?(method_name.to_sym)
+  when "window"
+    next if window_defs.include?(method_name.to_sym)
+  end
+
+  return_type = func["return_type"]
+  params = func["parameters"]
+  params.shift unless prefix == "vim"
+  param_names = params.map(&:last)
+  param_str = params.empty? ? "" : "(#{param_names.join(", ")})"
+  method_decl = "@method #{method_name}#{param_str}"
+  method_desc = "  Send the +#{prefix}_#{method_name}+ RPC to +nvim+"
+  param_docs = params.map do |type, name|
+    "  @param [#{type}] #{name}"
+  end
+  return_doc = "  @return [#{return_type}]\n"
+  method_doc = [method_decl, method_desc, *param_docs, return_doc].join("\n")
+  method_doc.gsub!(/ArrayOf\((\w+)[^)]*\)/, 'Array<\1>')
+  method_doc.gsub!(/Integer/, "Fixnum")
+
+  case prefix
+  when "vim"
+    vim_docs << method_doc
+  when "buffer"
+    buffer_docs << method_doc
+  when "tabpage"
+    tabpage_docs << method_doc
+  when "window"
+    window_docs << method_doc
+  end
+end
+
+lib_dir = Pathname.new(File.expand_path("../../lib/neovim", __FILE__))
+{
+  "client.rb" => vim_docs,
+  "buffer.rb" => buffer_docs,
+  "tabpage.rb" => tabpage_docs,
+  "window.rb" => window_docs,
+}.each do |filename, docs|
+  path = lib_dir.join(filename)
+  contents = File.read(path)
+  doc_str = ["=begin", *docs, "=end"].join("\n")
+
+  File.write(path, contents.sub(/=begin.+=end/m, doc_str))
+end
diff --git a/bin/j2mp b/script/j2mp
similarity index 100%
rename from bin/j2mp
rename to script/j2mp
diff --git a/bin/mp2j b/script/mp2j
similarity index 100%
rename from bin/mp2j
rename to script/mp2j
diff --git a/spec/acceptance/neovim-ruby-host_spec.rb b/spec/acceptance/neovim-ruby-host_spec.rb
index 4f8eb60..38e54b8 100644
--- a/spec/acceptance/neovim-ruby-host_spec.rb
+++ b/spec/acceptance/neovim-ruby-host_spec.rb
@@ -15,17 +15,12 @@ RSpec.describe "neovim-ruby-host" do
   end
 
   it "fails when attached to a TTY" do
-    yielded = false
-
     PTY.spawn(host_exe) do |rd, wr, pid|
-      yielded = true
       expect(rd.gets).to match(/can't run.+interactively/i)
 
       _, status = Process.waitpid2(pid)
       expect(status.exitstatus).to be(1)
     end
-
-    expect(yielded).to be(true)
   end
 
   it "loads and runs plugins from Ruby source files" do
@@ -46,7 +41,7 @@ RSpec.describe "neovim-ruby-host" do
       end
     RUBY
 
-    nvim = Neovim.attach_child(["nvim", "-u", "NONE", "-n"])
+    nvim = Neovim.attach_child(Support.child_argv)
 
     nvim.command("let host = rpcstart('#{host_exe}', ['#{plugin_path}'])")
 
diff --git a/spec/acceptance/ruby_provider_spec.rb b/spec/acceptance/ruby_provider_spec.rb
index 875be06..427b4e7 100644
--- a/spec/acceptance/ruby_provider_spec.rb
+++ b/spec/acceptance/ruby_provider_spec.rb
@@ -2,7 +2,7 @@ require "helper"
 
 RSpec.describe "ruby_provider" do
   let!(:nvim) do
-    Neovim.attach_child(["nvim", "-u", "NONE", "-n"])
+    Neovim.attach_child(Support.child_argv)
   end
 
   around do |spec|
@@ -15,15 +15,14 @@ RSpec.describe "ruby_provider" do
     begin
       spec.run
     ensure
-      nvim.session.shutdown
+      nvim.shutdown
     end
   end
 
   describe "ruby_execute" do
-    it "runs ruby directly" do
-      ruby = "VIM.command('let myvar = [1, 2]')".inspect
+    it "exposes the VIM constant" do
+      ruby = "VIM.equal?(Vim) || raise".inspect
       nvim.eval("rpcrequest(host, 'ruby_execute', #{ruby})")
-      expect(nvim.eval("g:myvar")).to eq([1, 2])
     end
 
     it "exposes the $curwin variable" do
@@ -43,31 +42,31 @@ RSpec.describe "ruby_provider" do
     end
 
     it "persists state between requests" do
-      nvim.eval("rpcrequest(host, 'ruby_execute', 'def foo; VIM.command(\"let g:called = 1\"); end')")
+      nvim.eval("rpcrequest(host, 'ruby_execute', 'def foo; Vim.command(\"let g:called = 1\"); end')")
       expect { nvim.get_var("called") }.to raise_error(/key not found/i)
 
       nvim.eval("rpcrequest(host, 'ruby_execute', 'foo')")
       expect(nvim.get_var("called")).to be(1)
     end
 
-    it "persists instance state in globals" do
+    it "persists instance state in $curbuf" do
       nvim.eval("rpcrequest(host, 'ruby_execute', '$curbuf.instance_variable_set(:@foo, 123)')")
-      nvim.eval("rpcrequest(host, 'ruby_execute', 'VIM.command(\"let g:foo = \#{$curbuf.instance_variable_get(:@foo)}\")')")
+      nvim.eval("rpcrequest(host, 'ruby_execute', 'Vim.command(\"let g:foo = \#{$curbuf.instance_variable_get(:@foo)}\")')")
 
       expect(nvim.get_var("foo")).to be(123)
-
-      nvim.eval("rpcrequest(host, 'ruby_execute', '$curwin.instance_variable_set(:@bar, 456)')")
-      nvim.eval("rpcrequest(host, 'ruby_execute', 'VIM.command(\"let g:bar = \#{$curwin.instance_variable_get(:@bar)}\")')")
-
-      expect(nvim.get_var("bar")).to be(456)
     end
   end
 
   describe "ruby_execute_file" do
     let(:script_path) { Support.file_path("script.rb") }
 
+    it "exposes the VIM constant" do
+      File.write(script_path, "VIM.equal?(Vim) || raise")
+      nvim.eval("rpcrequest(host, 'ruby_execute_file', '#{script_path}')")
+    end
+
     it "runs ruby from a file" do
-      File.write(script_path, "VIM.command('let myvar = [1, 2]')")
+      File.write(script_path, "Vim.command('let myvar = [1, 2]')")
       nvim.eval("rpcrequest(host, 'ruby_execute_file', '#{script_path}')")
       expect(nvim.eval("g:myvar")).to eq([1, 2])
     end
@@ -90,7 +89,7 @@ RSpec.describe "ruby_provider" do
     end
 
     it "persists state between requests" do
-      File.write(script_path, "def foo; VIM.command(\"let g:called = 1\"); end")
+      File.write(script_path, "def foo; Vim.command(\"let g:called = 1\"); end")
       nvim.eval("rpcrequest(host, 'ruby_execute_file', '#{script_path}')")
       expect { nvim.get_var("called") }.to raise_error(/key not found/i)
 
@@ -100,7 +99,7 @@ RSpec.describe "ruby_provider" do
 
     it "can run the same file multiple times" do
       nvim.set_var("called", 0)
-      File.write(script_path, "VIM.command(\"let g:called += 1\")")
+      File.write(script_path, "Vim.command(\"let g:called += 1\")")
 
       nvim.eval("rpcrequest(host, 'ruby_execute_file', '#{script_path}')")
       expect(nvim.get_var("called")).to be(1)
@@ -109,14 +108,14 @@ RSpec.describe "ruby_provider" do
       expect(nvim.get_var("called")).to be(2)
     end
 
-    it "persists instance state in globals" do
+    it "persists instance state in $curbuf" do
       File.write(script_path, <<-RUBY)
         def $curbuf.foo
           @foo ||= 0
           @foo += 1
         end
 
-        VIM.command("let g:foo = \#{$curbuf.foo}")
+        Vim.command("let g:foo = \#{$curbuf.foo}")
       RUBY
 
       nvim.eval("rpcrequest(host, 'ruby_execute_file', '#{script_path}')")
@@ -124,21 +123,6 @@ RSpec.describe "ruby_provider" do
 
       nvim.eval("rpcrequest(host, 'ruby_execute_file', '#{script_path}')")
       expect(nvim.get_var("foo")).to be(2)
-
-      File.write(script_path, <<-RUBY)
-        def $curwin.bar
-          @bar ||= 0
-          @bar += 1
-        end
-
-        VIM.command("let g:bar = \#{$curwin.bar}")
-      RUBY
-
-      nvim.eval("rpcrequest(host, 'ruby_execute_file', '#{script_path}')")
-      expect(nvim.get_var("bar")).to be(1)
-
-      nvim.eval("rpcrequest(host, 'ruby_execute_file', '#{script_path}')")
-      expect(nvim.get_var("bar")).to be(2)
     end
   end
 
diff --git a/spec/helper.rb b/spec/helper.rb
index 9568b46..b727349 100644
--- a/spec/helper.rb
+++ b/spec/helper.rb
@@ -1,16 +1,53 @@
 require "bundler/setup"
+
+if ENV["REPORT_COVERAGE"]
+  require "coveralls"
+  Coveralls.wear!
+end
+
+require "fileutils"
 require "neovim"
 require "pry"
 require "stringio"
 require "timeout"
-require "fileutils"
 
-if ENV["REPORT_COVERAGE"]
-  require "coveralls"
-  Coveralls.wear!
+module Support
+  def self.workspace
+    File.expand_path("../workspace", __FILE__)
+  end
+
+  def self.socket_path
+    file_path("nvim.sock")
+  end
+
+  def self.tcp_port
+    server = TCPServer.new("0.0.0.0", 0)
+
+    begin
+      server.addr[1]
+    ensure
+      server.close
+    end
+  end
+
+  def self.file_path(name)
+    File.join(workspace, name)
+  end
+
+  def self.setup_workspace
+    FileUtils.mkdir_p(workspace)
+  end
+
+  def self.teardown_workspace
+    FileUtils.rm_rf(workspace)
+  end
+
+  def self.child_argv
+    ["nvim", "--headless", "-i", "NONE", "-u", "NONE", "-n"]
+  end
 end
 
-unless system("nvim -nu NONE +q")
+unless system("#{Support.child_argv.join(" ")} +q")
   warn("Can't find `nvim` executable. See installation instructions:")
   warn("https://github.com/neovim/neovim/wiki/Installing-Neovim")
   exit(1)
@@ -49,36 +86,4 @@ RSpec.configure do |config|
   Kernel.srand config.seed
 end
 
-module Support
-  def self.workspace
-    File.expand_path("../workspace", __FILE__)
-  end
-
-  def self.socket_path
-    file_path("nvim.sock")
-  end
-
-  def self.port
-    server = TCPServer.new("0.0.0.0", 0)
-
-    begin
-      server.addr[1]
-    ensure
-      server.close
-    end
-  end
-
-  def self.file_path(name)
-    File.join(workspace, name)
-  end
-
-  def self.setup_workspace
-    FileUtils.mkdir_p(workspace)
-  end
-
-  def self.teardown_workspace
-    FileUtils.rm_rf(workspace)
-  end
-end
-
 Thread.abort_on_exception = true
diff --git a/spec/neovim/buffer_spec.rb b/spec/neovim/buffer_spec.rb
index 178a4f4..d4a25af 100644
--- a/spec/neovim/buffer_spec.rb
+++ b/spec/neovim/buffer_spec.rb
@@ -2,7 +2,7 @@ require "helper"
 
 module Neovim
   RSpec.describe Buffer do
-    let(:client) { Neovim.attach_child(["nvim", "-n", "-u", "NONE"]) }
+    let(:client) { Neovim.attach_child(Support.child_argv) }
     let(:buffer) { client.current.buffer }
     after { client.shutdown }
 
diff --git a/spec/neovim/client_spec.rb b/spec/neovim/client_spec.rb
index c33feb6..a7d6c39 100644
--- a/spec/neovim/client_spec.rb
+++ b/spec/neovim/client_spec.rb
@@ -2,7 +2,7 @@ require "helper"
 
 module Neovim
   RSpec.describe Client do
-    let(:client) { Neovim.attach_child(["nvim", "-n", "-u", "NONE"]) }
+    let(:client) { Neovim.attach_child(Support.child_argv) }
     after { client.shutdown }
 
     specify do
diff --git a/spec/neovim/current_spec.rb b/spec/neovim/current_spec.rb
index 0cf51d3..823952d 100644
--- a/spec/neovim/current_spec.rb
+++ b/spec/neovim/current_spec.rb
@@ -2,7 +2,7 @@ require "helper"
 
 module Neovim
   RSpec.describe Current do
-    let(:client) { Neovim.attach_child(["nvim", "-n", "-u", "NONE"]) }
+    let(:client) { Neovim.attach_child(Support.child_argv) }
     let(:current) { client.current }
     after { client.shutdown }
 
diff --git a/spec/neovim/host/loader_spec.rb b/spec/neovim/host/loader_spec.rb
index f4a465c..c78be48 100644
--- a/spec/neovim/host/loader_spec.rb
+++ b/spec/neovim/host/loader_spec.rb
@@ -1,4 +1,6 @@
 require "helper"
+require "neovim/host"
+require "neovim/host/loader"
 
 module Neovim
   class Host
diff --git a/spec/neovim/host_spec.rb b/spec/neovim/host_spec.rb
index 2d0ba2a..4fbb13e 100644
--- a/spec/neovim/host_spec.rb
+++ b/spec/neovim/host_spec.rb
@@ -1,4 +1,5 @@
 require "helper"
+require "neovim/host"
 
 module Neovim
   RSpec.describe Host do
@@ -6,17 +7,36 @@ module Neovim
     let(:client) { instance_double(Client) }
     let(:host) { Host.new(session, client) }
 
-    describe ".load_from_files" do
-      it "instantiates with a session and loads plugins" do
+    describe ".run" do
+      it "loads plugins and runs the host event loop" do
         paths = ["/foo", "/bar"]
+
+        expect(Host).to receive(:new).and_return(host)
+        expect(host).to receive(:run)
+
         loader = instance_double(Host::Loader)
 
+        expect(loader).to receive(:load).with(paths)
         expect(Host::Loader).to receive(:new).
-          with(kind_of(Host)).
+          with(host).
           and_return(loader)
-        expect(loader).to receive(:load).with(paths)
 
-        Host.load_from_files(paths, :session => session, :client => client)
+        Host.run(paths, :session => session, :client => client)
+      end
+    end
+
+    describe "#run" do
+      it "runs the session event loop and handles messages" do
+        message = double(:message)
+        expect(session).to receive(:run).and_yield(message)
+        expect(host).to receive(:handle).with(message)
+
+        host.run
+      end
+
+      it "rescues session exceptions", :silence_logging do
+        expect(session).to receive(:run).and_raise("BOOM")
+        expect { host.run }.not_to raise_error
       end
     end
 
diff --git a/spec/neovim/line_range_spec.rb b/spec/neovim/line_range_spec.rb
index 80ca370..e0471a2 100644
--- a/spec/neovim/line_range_spec.rb
+++ b/spec/neovim/line_range_spec.rb
@@ -2,7 +2,7 @@ require "helper"
 
 module Neovim
   RSpec.describe LineRange do
-    let(:client) { Neovim.attach_child(["nvim", "-n", "-u", "NONE"]) }
+    let(:client) { Neovim.attach_child(Support.child_argv) }
     let(:buffer) { client.current.buffer }
     let(:line_range) { LineRange.new(buffer, 0, -1) }
     let(:sub_range) { LineRange.new(buffer, 1, 2) }
@@ -18,7 +18,7 @@ module Neovim
 
     it "is enumerable" do
       expect(line_range).to be_an(Enumerable)
-      expect(line_range).to respond_to(:each)
+      expect(line_range.each.to_a).to eq(["1", "2", "3", "4"])
     end
 
     describe "#to_a" do
diff --git a/spec/neovim/logging_spec.rb b/spec/neovim/logging_spec.rb
new file mode 100644
index 0000000..61d963e
--- /dev/null
+++ b/spec/neovim/logging_spec.rb
@@ -0,0 +1,56 @@
+require "helper"
+
+module Neovim
+  RSpec.describe Logging do
+    around do |spec|
+      old_logger = Logging.logger
+
+      begin
+        Logging.send(:remove_instance_variable, :@logger)
+        spec.run
+      ensure
+        Logging.logger = old_logger
+      end
+    end
+
+    describe ".logger" do
+      it "fetches the output from $NVIM_RUBY_LOG_FILE" do
+        logger = instance_double(Logger, :level= => nil)
+        expect(Logger).to receive(:new).with("/tmp/nvim.log").and_return(logger)
+        Logging.logger("NVIM_RUBY_LOG_FILE" => "/tmp/nvim.log")
+        expect(Logging.logger).to be(logger)
+      end
+
+      it "defaults the output to STDERR" do
+        logger = instance_double(Logger, :level= => nil)
+        expect(Logger).to receive(:new).with(STDERR).and_return(logger)
+        Logging.logger({})
+        expect(Logging.logger).to be(logger)
+      end
+
+      it "fetches the level from $NVIM_RUBY_LOG_LEVEL as a string" do
+        logger = instance_double(Logger)
+        expect(Logger).to receive(:new).and_return(logger)
+        expect(logger).to receive(:level=).with(Logger::DEBUG)
+        Logging.logger("NVIM_RUBY_LOG_LEVEL" => "DEBUG")
+        expect(Logging.logger).to be(logger)
+      end
+
+      it "fetches the level from $NVIM_RUBY_LOG_LEVEL as an integer" do
+        logger = instance_double(Logger)
+        expect(Logger).to receive(:new).and_return(logger)
+        expect(logger).to receive(:level=).with(0)
+        Logging.logger("NVIM_RUBY_LOG_LEVEL" => "0")
+        expect(Logging.logger).to be(logger)
+      end
+
+      it "defaults the level to WARN" do
+        logger = instance_double(Logger)
+        expect(Logger).to receive(:new).and_return(logger)
+        expect(logger).to receive(:level=).with(Logger::WARN)
+        Logging.logger({})
+        expect(Logging.logger).to be(logger)
+      end
+    end
+  end
+end
diff --git a/spec/neovim/plugin_spec.rb b/spec/neovim/plugin_spec.rb
index a2ec4e2..4b3ad45 100644
--- a/spec/neovim/plugin_spec.rb
+++ b/spec/neovim/plugin_spec.rb
@@ -1,4 +1,5 @@
 require "helper"
+require "neovim/plugin"
 
 module Neovim
   RSpec.describe Plugin do
@@ -13,6 +14,8 @@ module Neovim
         expect(plugin.handlers.size).to be(1)
         handler = plugin.handlers.first
 
+        expect(handler.sync?).to be(false)
+        expect(handler.qualified?).to be(true)
         expect(handler.block).to eq(cmd_block)
         expect(handler.qualified_name).to eq("source:command:Foo")
         expect(handler.to_spec).to eq(
@@ -33,6 +36,8 @@ module Neovim
         expect(plugin.handlers.size).to be(1)
         handler = plugin.handlers.first
 
+        expect(handler.sync?).to be(false)
+        expect(handler.qualified?).to be(true)
         expect(handler.block).to eq(au_block)
         expect(handler.qualified_name).to eq("source:autocmd:BufEnter:*.rb")
         expect(handler.to_spec).to eq(
@@ -53,6 +58,8 @@ module Neovim
         expect(plugin.handlers.size).to be(1)
         handler = plugin.handlers.first
 
+        expect(handler.sync?).to be(false)
+        expect(handler.qualified?).to be(true)
         expect(handler.block).to eq(fun_block)
         expect(handler.qualified_name).to eq("source:function:Foo")
         expect(handler.to_spec).to eq(
@@ -73,6 +80,8 @@ module Neovim
         expect(plugin.handlers.size).to be(1)
         handler = plugin.handlers.first
 
+        expect(handler.sync?).to be(true)
+        expect(handler.qualified?).to be(false)
         expect(handler.block).to eq(cmd_block)
         expect(handler.qualified_name).to eq("Foo")
       end
diff --git a/spec/neovim/remote_object_spec.rb b/spec/neovim/remote_object_spec.rb
index 1bc781c..b0c0b79 100644
--- a/spec/neovim/remote_object_spec.rb
+++ b/spec/neovim/remote_object_spec.rb
@@ -2,7 +2,7 @@ require "helper"
 
 module Neovim
   RSpec.describe RemoteObject do
-    let(:client) { Neovim.attach_child(["nvim", "-n", "-u", "NONE"]) }
+    let(:client) { Neovim.attach_child(Support.child_argv) }
     after { client.shutdown }
 
     context Window do
@@ -26,6 +26,10 @@ module Neovim
         it "enables window_* function calls" do
           expect(window.get_cursor).to eq([1, 0])
         end
+
+        it "falls back to super" do
+          expect { window.foobar }.to raise_error(NoMethodError)
+        end
       end
 
       describe "#methods" do
diff --git a/spec/neovim/ruby_provider/buffer_ext_spec.rb b/spec/neovim/ruby_provider/buffer_ext_spec.rb
index aafc29a..1f6ce4e 100644
--- a/spec/neovim/ruby_provider/buffer_ext_spec.rb
+++ b/spec/neovim/ruby_provider/buffer_ext_spec.rb
@@ -4,21 +4,21 @@ require "neovim/ruby_provider/buffer_ext"
 module Neovim
   RSpec.describe Buffer do
     let!(:nvim) do
-      Neovim.attach_child(["nvim", "-u", "NONE", "-n"]).tap do |nvim|
-        stub_const("::VIM", nvim)
+      Neovim.attach_child(Support.child_argv).tap do |nvim|
+        stub_const("::Vim", nvim)
       end
     end
 
     after { nvim.shutdown }
 
     describe ".current" do
-      it "returns the current buffer from the global VIM client" do
+      it "returns the current buffer from the global Vim client" do
         expect(Buffer.current).to eq(nvim.get_current_buffer)
       end
     end
 
     describe ".count" do
-      it "returns the current buffer count from the global VIM client" do
+      it "returns the current buffer count from the global Vim client" do
         expect {
           nvim.command("new")
         }.to change { Buffer.count }.by(1)
@@ -26,7 +26,7 @@ module Neovim
     end
 
     describe ".[]" do
-      it "returns the buffer from the global VIM client at the given index" do
+      it "returns the buffer from the global Vim client at the given index" do
         expect(Buffer[0]).to eq(nvim.get_current_buffer)
         nvim.command("new")
         expect(Buffer[1]).to eq(nvim.get_current_buffer)
diff --git a/spec/neovim/ruby_provider/vim_spec.rb b/spec/neovim/ruby_provider/vim_spec.rb
new file mode 100644
index 0000000..fb864ec
--- /dev/null
+++ b/spec/neovim/ruby_provider/vim_spec.rb
@@ -0,0 +1,32 @@
+require "helper"
+require "neovim/ruby_provider/vim"
+
+RSpec.describe Vim do
+  describe Vim::Buffer do
+    it "refers to Neovim::Buffer" do
+      expect(Vim::Buffer).to be(Neovim::Buffer)
+    end
+  end
+
+  describe Vim::Window do
+    it "refers to Neovim::Window" do
+      expect(Vim::Window).to be(Neovim::Window)
+    end
+  end
+
+  describe VIM do
+    it "is an alias for the Vim module" do
+      expect(VIM).to be(Vim)
+    end
+  end
+
+  describe "#method_missing" do
+    it "delegates method calls to @__client" do
+      client = double(:client)
+      expect(client).to receive(:foo).with(1, 2)
+
+      Vim.__client = client
+      Vim.foo(1, 2)
+    end
+  end
+end
diff --git a/spec/neovim/ruby_provider/window_ext_spec.rb b/spec/neovim/ruby_provider/window_ext_spec.rb
index 7cecd00..4e3bf65 100644
--- a/spec/neovim/ruby_provider/window_ext_spec.rb
+++ b/spec/neovim/ruby_provider/window_ext_spec.rb
@@ -4,32 +4,46 @@ require "neovim/ruby_provider/window_ext"
 module Neovim
   RSpec.describe Window do
     let!(:nvim) do
-      Neovim.attach_child(["nvim", "-u", "NONE", "-n"]).tap do |nvim|
-        stub_const("::VIM", nvim)
+      Neovim.attach_child(Support.child_argv).tap do |nvim|
+        stub_const("::Vim", nvim)
       end
     end
 
     after { nvim.shutdown }
 
     describe ".current" do
-      it "returns the current window from the global VIM client" do
+      it "returns the current window from the global Vim client" do
         expect(Window.current).to eq(nvim.get_current_window)
       end
     end
 
     describe ".count" do
-      it "returns the current window count from the global VIM client" do
+      it "returns the current window count from the global Vim client" do
         expect {
           nvim.command("new")
         }.to change { Window.count }.by(1)
       end
+
+      it "only includes windows within a tabpage" do
+        expect {
+          nvim.command("tabnew")
+        }.not_to change { Window.count }.from(1)
+      end
     end
 
     describe ".[]" do
-      it "returns the window from the global VIM client at the given index" do
-        expect(Window[0]).to eq(nvim.get_current_window)
-        nvim.command("tabnew")
-        expect(Window[1]).to eq(nvim.get_current_window)
+      it "returns the window at the given index" do
+        expect {
+          nvim.command("new")
+        }.to change { Window[1] }.from(nil).to(kind_of(Window))
+      end
+
+      it "only includes windows within a tabpage" do
+        nvim.command("new")
+
+        expect {
+          nvim.command("tabnew")
+        }.to change { Window[1] }.from(kind_of(Window)).to(nil)
       end
     end
   end
diff --git a/spec/neovim/session/api_spec.rb b/spec/neovim/session/api_spec.rb
index a239f27..55a7ffb 100644
--- a/spec/neovim/session/api_spec.rb
+++ b/spec/neovim/session/api_spec.rb
@@ -13,17 +13,36 @@ module Neovim
       end
 
       describe "#function" do
-        it "returns a corresponding Function object" do
+        it "returns a sync function object" do
           api = API.new(
             [nil, {"functions" => [
-              {"name" => "vim_strwidth", "async" => false}
+              {"name" => "vim_sync", "async" => false}
             ]}]
           )
 
-          function = api.function("vim_strwidth")
-          expect(function).to be_a(API::Function)
-          expect(function.name).to eq("vim_strwidth")
+          function = api.function("vim_sync")
+          expect(function.name).to eq("vim_sync")
           expect(function.async).to be(false)
+
+          session = instance_double(Session)
+          expect(session).to receive(:request).with("vim_sync", "msg")
+          function.call(session, "msg")
+        end
+
+        it "returns an async function object" do
+          api = API.new(
+            [nil, {"functions" => [
+              {"name" => "vim_async", "async" => true}
+            ]}]
+          )
+
+          function = api.function("vim_async")
+          expect(function.name).to eq("vim_async")
+          expect(function.async).to be(true)
+
+          session = instance_double(Session)
+          expect(session).to receive(:notify).with("vim_async", "msg")
+          function.call(session, "msg")
         end
       end
 
diff --git a/spec/neovim/session/event_loop_spec.rb b/spec/neovim/session/event_loop_spec.rb
index 2e38c48..805935e 100644
--- a/spec/neovim/session/event_loop_spec.rb
+++ b/spec/neovim/session/event_loop_spec.rb
@@ -82,7 +82,7 @@ module Neovim
 
       context "child" do
         it "sends and receives data" do
-          event_loop = EventLoop.child(["nvim", "-n", "-u", "NONE"])
+          event_loop = EventLoop.child(Support.child_argv)
           input = MessagePack.pack([0, 0, :vim_strwidth, ["hi"]])
 
           response = nil
@@ -94,6 +94,59 @@ module Neovim
           expect(response).to eq(MessagePack.pack([1, 0, nil, 2]))
         end
       end
+
+      describe "#run" do
+        it "handles EOF" do
+          rd, wr = IO.pipe
+          wr.close
+          event_loop = EventLoop.new(rd, wr)
+          expect(event_loop).to receive(:info).with(/EOFError/)
+
+          event_loop.run
+        end
+
+        it "handles other errors" do
+          rd, wr = IO.pipe
+          rd.close
+          event_loop = EventLoop.new(rd, wr)
+          expect(event_loop).to receive(:fatal).with(/IOError/)
+
+          event_loop.run
+        end
+      end
+
+      describe "#write" do
+        it "retries when writes would block" do
+          rd, wr = IO.pipe
+          event_loop = EventLoop.new(rd, wr)
+          err_class = Class.new(RuntimeError) { include IO::WaitWritable }
+
+          expect(wr).to receive(:write_nonblock).and_raise(err_class)
+          expect(wr).to receive(:write_nonblock).and_call_original
+
+          event_loop.write("a")
+          expect(rd.readpartial(1)).to eq("a")
+        end
+      end
+
+      describe "#shutdown" do
+        it "closes IO handles" do
+          rd, wr = IO.pipe
+          EventLoop.new(rd, wr).shutdown
+
+          expect(rd).to be_closed
+          expect(wr).to be_closed
+        end
+
+        it "kills spawned processes" do
+          io = IO.popen("cat", "rb+")
+          pid = io.pid
+          expect(pid).to respond_to(:to_int)
+
+          EventLoop.new(io).shutdown
+          expect { Process.kill(0, pid) }.to raise_error(Errno::ESRCH)
+        end
+      end
     end
   end
 end
diff --git a/spec/neovim/session/notification_spec.rb b/spec/neovim/session/notification_spec.rb
new file mode 100644
index 0000000..e651a66
--- /dev/null
+++ b/spec/neovim/session/notification_spec.rb
@@ -0,0 +1,20 @@
+require "helper"
+
+module Neovim
+  class Session
+    RSpec.describe Notification do
+      let(:notification) { Notification.new(:method, ["arg"]) }
+
+      it "has readers" do
+        expect(notification.method_name).to eq("method")
+        expect(notification.arguments).to eq(["arg"])
+      end
+
+      describe "#sync?" do
+        it "is false" do
+          expect(notification.sync?).to be(false)
+        end
+      end
+    end
+  end
+end
diff --git a/spec/neovim/session/request_spec.rb b/spec/neovim/session/request_spec.rb
new file mode 100644
index 0000000..1d01638
--- /dev/null
+++ b/spec/neovim/session/request_spec.rb
@@ -0,0 +1,36 @@
+require "helper"
+
+module Neovim
+  class Session
+    RSpec.describe Request do
+      let(:serializer) { double(:serializer) }
+      let(:reqid) { 1 }
+      let(:request) { Request.new(:method, ["arg"], serializer, reqid) }
+
+      it "has readers" do
+        expect(request.method_name).to eq("method")
+        expect(request.arguments).to eq(["arg"])
+      end
+
+      describe "#sync?" do
+        it "is true" do
+          expect(request.sync?).to be(true)
+        end
+      end
+
+      describe "#respond" do
+        it "writes an RPC response to serializer" do
+          expect(serializer).to receive(:write).with([1, reqid, nil, "val"])
+          request.respond("val")
+        end
+      end
+
+      describe "#error" do
+        it "writes an RPC error response to serializer" do
+          expect(serializer).to receive(:write).with([1, reqid, "err", nil])
+          request.error("err")
+        end
+      end
+    end
+  end
+end
diff --git a/spec/neovim/session/rpc_spec.rb b/spec/neovim/session/rpc_spec.rb
index 41689dc..5ffc663 100644
--- a/spec/neovim/session/rpc_spec.rb
+++ b/spec/neovim/session/rpc_spec.rb
@@ -103,6 +103,18 @@ module Neovim
 
         include_context "rpc behavior"
       end
+
+      describe "#run" do
+        it "logs exceptions" do
+          serializer = instance_double(Serializer)
+          rpc = RPC.new(serializer)
+
+          expect(serializer).to receive(:run).and_raise("BOOM")
+          expect(rpc).to receive(:fatal).with(/BOOM/)
+
+          rpc.run
+        end
+      end
     end
   end
 end
diff --git a/spec/neovim/session/serializer_spec.rb b/spec/neovim/session/serializer_spec.rb
index a6c6d17..2acdb55 100644
--- a/spec/neovim/session/serializer_spec.rb
+++ b/spec/neovim/session/serializer_spec.rb
@@ -43,6 +43,20 @@ module Neovim
 
         include_context "serializer behavior"
       end
+
+      describe "#run" do
+        it "logs exceptions" do
+          unpacker = instance_double(MessagePack::Unpacker)
+          event_loop = instance_double(EventLoop)
+          serializer = Serializer.new(event_loop, unpacker)
+
+          expect(event_loop).to receive(:run).and_yield("data")
+          expect(unpacker).to receive(:feed_each).with("data").and_raise("BOOM")
+          expect(serializer).to receive(:fatal).with(/BOOM/)
+
+          serializer.run
+        end
+      end
     end
   end
 end
diff --git a/spec/neovim/session_spec.rb b/spec/neovim/session_spec.rb
index dc7025d..c3ba793 100644
--- a/spec/neovim/session_spec.rb
+++ b/spec/neovim/session_spec.rb
@@ -95,11 +95,11 @@ module Neovim
     end
 
     context "tcp" do
-      let!(:nvim_port) { Support.port }
+      let!(:nvim_port) { Support.tcp_port }
       let!(:nvim_pid) do
         pid = Process.spawn(
           {"NVIM_LISTEN_ADDRESS" => "0.0.0.0:#{nvim_port}"},
-          "nvim --headless -n -u NONE",
+          Support.child_argv.join(" "),
           [:out, :err] => "/dev/null"
         )
 
@@ -126,7 +126,7 @@ module Neovim
       let!(:nvim_pid) do
         pid = Process.spawn(
           {"NVIM_LISTEN_ADDRESS" => socket_path},
-          "nvim --headless -n -u NONE",
+          Support.child_argv.join(" "),
           [:out, :err] => "/dev/null"
         )
 
@@ -149,7 +149,7 @@ module Neovim
     end
 
     context "child" do
-      let!(:session) { Session.child(["nvim", "-n", "-u", "NONE"]) }
+      let!(:session) { Session.child(Support.child_argv) }
       include_context "session behavior"
       after { session.shutdown }
     end
diff --git a/spec/neovim/window_spec.rb b/spec/neovim/window_spec.rb
index 2dafa33..de58215 100644
--- a/spec/neovim/window_spec.rb
+++ b/spec/neovim/window_spec.rb
@@ -2,7 +2,7 @@ require "helper"
 
 module Neovim
   RSpec.describe Window do
-    let(:client) { Neovim.attach_child(["nvim", "-n", "-u", "NONE"]) }
+    let(:client) { Neovim.attach_child(Support.child_argv) }
     let(:window) { client.current.window }
     after { client.shutdown }
 
@@ -69,6 +69,22 @@ module Neovim
             client.command("normal ix")
           }.to change { client.current.line }.to("oxne")
         end
+
+        it "supports out of range indexes" do
+          window.buffer.lines = ["x", "xx"]
+
+          expect {
+            window.cursor = [10, 10]
+          }.to change { window.cursor }.to([2, 1])
+
+          expect {
+            window.cursor = [0, -1]
+          }.to change { window.cursor }.to([1, 0])
+        end
+
+        it "returns the cursor array" do
+          expect(window.cursor = [10, 10]).to eq([10, 10])
+        end
       end
     end
   end
diff --git a/spec/neovim_spec.rb b/spec/neovim_spec.rb
index d2867de..ae8c242 100644
--- a/spec/neovim_spec.rb
+++ b/spec/neovim_spec.rb
@@ -1,13 +1,11 @@
 require "helper"
 
 RSpec.describe Neovim do
-  let(:nvim_argv) { %w(nvim --headless -u NONE -i NONE -n) }
-
   describe ".attach_tcp" do
     it "attaches to a TCP socket" do
-      port = Support.port
+      port = Support.tcp_port
       env = {"NVIM_LISTEN_ADDRESS" => "0.0.0.0:#{port}"}
-      pid = Process.spawn(env, *nvim_argv, [:out, :err] => "/dev/null")
+      pid = Process.spawn(env, *Support.child_argv, [:out, :err] => "/dev/null")
 
       begin
         client = Neovim.attach_tcp("0.0.0.0", port)
@@ -28,7 +26,7 @@ RSpec.describe Neovim do
     it "attaches to a UNIX socket" do
       socket_path = Support.socket_path
       env = {"NVIM_LISTEN_ADDRESS" => socket_path}
-      pid = Process.spawn(env, *nvim_argv, [:out, :err] => "/dev/null")
+      pid = Process.spawn(env, *Support.child_argv, [:out, :err] => "/dev/null")
 
       begin
         client = Neovim.attach_unix(socket_path)
@@ -48,25 +46,11 @@ RSpec.describe Neovim do
   describe ".attach_child" do
     it "spawns and attaches to a child process" do
       begin
-        client = Neovim.attach_child(nvim_argv)
+        client = Neovim.attach_child(Support.child_argv)
         expect(client.strwidth("hi")).to eq(2)
       ensure
         client.shutdown
       end
     end
   end
-
-  describe ".start_host" do
-    it "loads and runs a Host" do
-      paths = ["/foo", "/bar"]
-      host = double(:host)
-
-      expect(Neovim::Host).to receive(:load_from_files).
-        with(paths).
-        and_return(host)
-
-      expect(host).to receive(:run)
-      Neovim.start_host(paths)
-    end
-  end
 end

-- 
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/pkg-ruby-extras/ruby-neovim.git



More information about the Pkg-ruby-extras-commits mailing list