neovim 0.3.3 → 0.4.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (44) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +1 -0
  3. data/.gitmodules +3 -0
  4. data/.travis.yml +1 -1
  5. data/CHANGELOG.md +6 -0
  6. data/Rakefile +14 -3
  7. data/lib/neovim.rb +10 -1
  8. data/lib/neovim/buffer.rb +2 -0
  9. data/lib/neovim/client.rb +2 -0
  10. data/lib/neovim/executable.rb +33 -0
  11. data/lib/neovim/ruby_provider.rb +32 -58
  12. data/lib/neovim/ruby_provider/vim.rb +15 -1
  13. data/lib/neovim/tabpage.rb +3 -0
  14. data/lib/neovim/version.rb +1 -1
  15. data/lib/neovim/window.rb +3 -0
  16. data/script/acceptance_tests +46 -0
  17. data/script/generate_docs +8 -1
  18. data/spec/acceptance/rplugin_spec.vim +19 -0
  19. data/spec/acceptance/ruby_spec.vim +94 -0
  20. data/spec/acceptance/rubydo_spec.vim +66 -0
  21. data/spec/acceptance/rubyfile/call_foo.rb +1 -0
  22. data/spec/acceptance/rubyfile/curbuf.rb +1 -0
  23. data/spec/acceptance/rubyfile/curbuf_ivar_get.rb +1 -0
  24. data/spec/acceptance/rubyfile/curbuf_ivar_set.rb +1 -0
  25. data/spec/acceptance/rubyfile/curwin.rb +1 -0
  26. data/spec/acceptance/rubyfile/define_foo.rb +3 -0
  27. data/spec/acceptance/rubyfile/raise_standard_error.rb +1 -0
  28. data/spec/acceptance/rubyfile/raise_syntax_error.rb +1 -0
  29. data/spec/acceptance/rubyfile/set_pwd_after.rb +1 -0
  30. data/spec/acceptance/rubyfile/set_pwd_before.rb +1 -0
  31. data/spec/acceptance/rubyfile/vim_constants.rb +2 -0
  32. data/spec/acceptance/rubyfile_spec.vim +111 -0
  33. data/spec/acceptance/runtime/init.vim +1 -0
  34. data/spec/acceptance/runtime/rplugin/ruby/plugin.rb +13 -0
  35. data/spec/documentation_spec.rb +24 -0
  36. data/spec/helper.rb +20 -45
  37. data/spec/neovim/executable_spec.rb +32 -0
  38. data/spec/neovim/host_spec.rb +2 -2
  39. data/spec/neovim/ruby_provider/vim_spec.rb +38 -0
  40. data/spec/neovim_spec.rb +6 -0
  41. data/spec/support.rb +45 -0
  42. metadata +46 -7
  43. data/spec/acceptance/neovim-ruby-host_spec.rb +0 -69
  44. data/spec/acceptance/ruby_provider_spec.rb +0 -256
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 9fc40ef389b3a8f14b2f8c732553d9e4c02f0ce2
4
- data.tar.gz: f99653d06b7373c3c05021d3f1d9db6e26a60185
3
+ metadata.gz: 421a9bb0ec7f5498ee9f00e98a191abf1972c46e
4
+ data.tar.gz: b6bdeee0789c0c59cb1337a36826534c1f6a2bb3
5
5
  SHA512:
6
- metadata.gz: b2f8af36212e0abd4ad2663b4a288452072fd761e017d5e33c19b17dcac93befa562ac4439c69e7d5764fa59013fb5aab321db8836e4f9db4834b0150d1c3c96
7
- data.tar.gz: 6ac9d1e4d97870f26dbd28cad4dde0c556d9cb301cec0c3a78775b36db585026d8249e852b71482c5fb65f81ecc2e6702580f776a6a8f8d24ca12f62bc8e8dde
6
+ metadata.gz: '079597075fd27fd08cd707bbbb5243579db5bf8fe59ea4fc594fa4eca271864f3bc90e4d318527209c161669c150d214d7abeec4aadafbcb0b20d1359b987f97'
7
+ data.tar.gz: ad2c5fc451b6b86825edc84d2780e28b5a3a525a1ebaa191e078fa03893fd77a199e10d1265a6dac92fd53c29353b9abbe36847be420afd19f08a6cbe56c88cf
data/.gitignore CHANGED
@@ -17,4 +17,5 @@ test/tmp
17
17
  test/version_tmp
18
18
  tmp
19
19
  spec/workspace
20
+ spec/acceptance/runtime/rplugin.vim
20
21
  vendor/bundle
@@ -0,0 +1,3 @@
1
+ [submodule "vendor/vader.vim"]
2
+ path = vendor/vader.vim
3
+ url = https://github.com/junegunn/vader.vim.git
@@ -17,4 +17,4 @@ before_install:
17
17
  - eval "$(curl -Ss https://raw.githubusercontent.com/neovim/bot-ci/master/scripts/travis-setup.sh) nightly-x64"
18
18
 
19
19
  env: REPORT_COVERAGE=1
20
- script: travis_retry bundle exec rake --trace spec
20
+ script: travis_retry bundle exec rake --trace
@@ -1,3 +1,9 @@
1
+ # 0.4.0
2
+ - Add `Neovim.executable` for accessing `nvim` info
3
+ - Fix bug where `$curwin` and `$curbuf` got out of sync after `Vim.command`
4
+ invocations
5
+ - Use vader.vim for running vimscript acceptance tests
6
+
1
7
  # 0.3.3
2
8
  - Hotfix older nvim clients' inability to hook into DirChanged
3
9
 
data/Rakefile CHANGED
@@ -1,9 +1,6 @@
1
1
  require "bundler/gem_tasks"
2
2
  require "rspec/core/rake_task"
3
3
 
4
- RSpec::Core::RakeTask.new(:spec)
5
- task :default => :spec
6
-
7
4
  desc "Generate Neovim remote API docs"
8
5
  task :docs do
9
6
  sh File.expand_path("../script/generate_docs", __FILE__)
@@ -13,3 +10,17 @@ desc "Dump nvim remote API"
13
10
  task :api do
14
11
  sh File.expand_path("../script/dump_api", __FILE__)
15
12
  end
13
+
14
+ namespace :spec do
15
+ desc "Run functional tests"
16
+ RSpec::Core::RakeTask.new(:functional)
17
+
18
+ desc "Run acceptance tests"
19
+ task :acceptance do
20
+ sh "git submodule update --init"
21
+ sh File.expand_path("../script/acceptance_tests", __FILE__)
22
+ end
23
+ end
24
+
25
+ task :spec => "spec:functional"
26
+ task :default => ["spec:acceptance", "spec:functional"]
@@ -1,4 +1,5 @@
1
1
  require "neovim/client"
2
+ require "neovim/executable"
2
3
  require "neovim/logging"
3
4
  require "neovim/session"
4
5
  require "neovim/version"
@@ -77,7 +78,7 @@ module Neovim
77
78
  # @param argv [Array] The arguments to pass to the spawned process
78
79
  # @return [Client]
79
80
  # @see Session.child
80
- def self.attach_child(argv=["nvim"])
81
+ def self.attach_child(argv=[executable.path])
81
82
  Client.new Session.child(argv)
82
83
  end
83
84
 
@@ -90,6 +91,14 @@ module Neovim
90
91
  raise "Can't call Neovim.plugin outside of a plugin host."
91
92
  end
92
93
 
94
+ # Return a +Neovim::Executable+ representing the active +nvim+ executable.
95
+ #
96
+ # @return [Executable]
97
+ # @see Executable
98
+ def self.executable
99
+ @executable ||= Executable.from_env
100
+ end
101
+
93
102
  # Set the Neovim global logger.
94
103
  #
95
104
  # @param logger [Logger] The target logger
@@ -3,6 +3,8 @@ require "neovim/line_range"
3
3
 
4
4
  module Neovim
5
5
  # Class representing an +nvim+ buffer.
6
+ #
7
+ # The methods documented here were generated using NVIM v0.1.7
6
8
  class Buffer < RemoteObject
7
9
  # A +LineRange+ object representing the buffer's lines.
8
10
  #
@@ -6,6 +6,8 @@ module Neovim
6
6
  # +RemoteObject+ subclasses (i.e. +Buffer+, +Window+, or +Tabpage+),
7
7
  # which similarly have dynamically generated interfaces.
8
8
  #
9
+ # The methods documented here were generated using NVIM v0.1.7
10
+ #
9
11
  # @see Buffer
10
12
  # @see Window
11
13
  # @see Tabpage
@@ -0,0 +1,33 @@
1
+ module Neovim
2
+ class Executable
3
+ VERSION_PATTERN = /\ANVIM v?(.+)$/
4
+
5
+ class Error < RuntimeError; end
6
+
7
+ # Load the current executable from the +NVIM_EXECUTABLE+ environment
8
+ # variable.
9
+ #
10
+ # @param env [Hash]
11
+ # @return [Executable]
12
+ def self.from_env(env=ENV)
13
+ new(env.fetch("NVIM_EXECUTABLE", "nvim"))
14
+ end
15
+
16
+ attr_reader :path
17
+
18
+ def initialize(path)
19
+ @path = path
20
+ end
21
+
22
+ # Fetch the +nvim+ version.
23
+ #
24
+ # @return [String]
25
+ def version
26
+ @version ||= IO.popen([path, "--version"]) do |io|
27
+ io.gets[VERSION_PATTERN, 1]
28
+ end
29
+ rescue => e
30
+ raise Error, "Couldn't load #{path}: #{e}"
31
+ end
32
+ end
33
+ end
@@ -9,12 +9,11 @@ module Neovim
9
9
  #
10
10
  # @api private
11
11
  module RubyProvider
12
- @__buffer_cache = {}
13
-
14
12
  def self.__define_plugin!
15
13
  Thread.abort_on_exception = true
16
14
 
17
15
  Neovim.plugin do |plug|
16
+ __define_setup(plug)
18
17
  __define_ruby_execute(plug)
19
18
  __define_ruby_execute_file(plug)
20
19
  __define_ruby_do_range(plug)
@@ -22,6 +21,30 @@ module Neovim
22
21
  end
23
22
  end
24
23
 
24
+ # Bootstrap the provider client:
25
+ #
26
+ # 1. Monkeypatch +$stdout+ and +$stderr+ to write to +nvim+.
27
+ # 2. Define the +DirChanged+ event to update the provider's pwd.
28
+ def self.__define_setup(plug)
29
+ plug.__send__(:setup) do |client|
30
+ $stdout.define_singleton_method(:write) do |string|
31
+ client.out_write(string)
32
+ end
33
+
34
+ $stderr.define_singleton_method(:write) do |string|
35
+ client.report_error(string)
36
+ end
37
+
38
+ begin
39
+ cid = client.channel_id
40
+ client.command("au DirChanged * call rpcrequest(#{cid}, 'ruby_chdir', v:event)")
41
+ rescue ArgumentError
42
+ # Swallow this exception for now. This means the nvim installation is
43
+ # from before DirChanged was implemented.
44
+ end
45
+ end
46
+ end
47
+
25
48
  # Evaluate the provided Ruby code, exposing the +Vim+ constant for
26
49
  # interactions with the editor.
27
50
  #
@@ -73,76 +96,27 @@ module Neovim
73
96
  private_class_method :__define_ruby_do_range
74
97
 
75
98
  def self.__define_ruby_chdir(plug)
76
- plug.__send__(:setup) do |client|
77
- begin
78
- cid = client.channel_id
79
- client.command("au DirChanged * call rpcrequest(#{cid}, 'ruby_chdir', v:event)")
80
- rescue ArgumentError
81
- # Swallow this exception for now. This means the nvim installation is
82
- # from before DirChanged was implemented.
83
- end
84
- end
85
-
86
- plug.__send__(:rpc, :ruby_chdir) do |nvim, event|
99
+ plug.__send__(:rpc, :ruby_chdir) do |_, event|
87
100
  Dir.chdir(event.fetch("cwd"))
88
101
  end
89
102
  end
90
103
  private_class_method :__define_ruby_chdir
91
104
 
92
105
  def self.__wrap_client(client)
93
- __with_globals(client) do
94
- __with_vim_constant(client) do
95
- __with_redirect_streams(client) do
96
- __with_exception_handling(client) do
97
- yield
98
- end
99
- end
100
- end
106
+ Vim.__client = client
107
+ Vim.__refresh_globals(client)
108
+
109
+ __with_exception_handling(client) do
110
+ yield
101
111
  end
102
112
  nil
103
113
  end
104
114
  private_class_method :__wrap_client
105
115
 
106
- def self.__with_globals(client)
107
- bufnr = client.evaluate("bufnr('%')")
108
-
109
- $curbuf = @__buffer_cache.fetch(bufnr) do
110
- @__buffer_cache[bufnr] = client.get_current_buffer
111
- end
112
-
113
- $curwin = client.get_current_window
114
-
115
- yield
116
- end
117
- private_class_method :__with_globals
118
-
119
- def self.__with_vim_constant(client)
120
- ::Vim.__client = client
121
- yield
122
- end
123
- private_class_method :__with_vim_constant
124
-
125
- def self.__with_redirect_streams(client)
126
- @__with_redirect_streams ||= begin
127
- $stdout.define_singleton_method(:write) do |string|
128
- client.out_write(string)
129
- end
130
-
131
- $stderr.define_singleton_method(:write) do |string|
132
- client.report_error(string)
133
- end
134
-
135
- true
136
- end
137
-
138
- yield
139
- end
140
- private_class_method :__with_redirect_streams
141
-
142
116
  def self.__with_exception_handling(client)
143
117
  begin
144
118
  yield
145
- rescue SyntaxError, StandardError => e
119
+ rescue SyntaxError, LoadError, StandardError => e
146
120
  msg = [e.class, e.message].join(": ")
147
121
  client.report_error(msg.lines.first.strip)
148
122
  end
@@ -7,13 +7,27 @@ module Vim
7
7
  Buffer = ::Neovim::Buffer
8
8
  Window = ::Neovim::Window
9
9
 
10
+ @__buffer_cache = {}
11
+
10
12
  def self.__client=(client)
11
13
  @__client = client
12
14
  end
13
15
 
14
16
  # Delegate all method calls to the underlying +Neovim::Client+ object.
15
17
  def self.method_missing(method, *args, &block)
16
- @__client.public_send(method, *args, &block)
18
+ @__client.public_send(method, *args, &block).tap do
19
+ __refresh_globals(@__client)
20
+ end
21
+ end
22
+
23
+ def self.__refresh_globals(client)
24
+ bufnr = client.evaluate("bufnr('%')")
25
+
26
+ $curbuf = @__buffer_cache.fetch(bufnr) do
27
+ @__buffer_cache[bufnr] = client.get_current_buffer
28
+ end
29
+
30
+ $curwin = client.get_current_window
17
31
  end
18
32
  end
19
33
 
@@ -1,6 +1,9 @@
1
1
  require "neovim/remote_object"
2
2
 
3
3
  module Neovim
4
+ # Class representing an +nvim+ tabpage.
5
+ #
6
+ # The methods documented here were generated using NVIM v0.1.7
4
7
  class Tabpage < RemoteObject
5
8
 
6
9
  # The following methods are dynamically generated.
@@ -1,3 +1,3 @@
1
1
  module Neovim
2
- VERSION = Gem::Version.new("0.3.3")
2
+ VERSION = Gem::Version.new("0.4.0")
3
3
  end
@@ -1,6 +1,9 @@
1
1
  require "neovim/remote_object"
2
2
 
3
3
  module Neovim
4
+ # Class representing an +nvim+ window.
5
+ #
6
+ # The methods documented here were generated using NVIM v0.1.7
4
7
  class Window < RemoteObject
5
8
  # Get the buffer displayed in the window
6
9
  #
@@ -0,0 +1,46 @@
1
+ #!/usr/bin/env ruby
2
+ # encoding: utf-8
3
+
4
+ $:.unshift File.expand_path("../../lib", __FILE__)
5
+
6
+ require "neovim"
7
+ require "shellwords"
8
+ require "tempfile"
9
+ require File.expand_path("../../spec/support.rb", __FILE__)
10
+
11
+ nvim = Neovim.executable.path
12
+ vader = File.expand_path("../../vendor/vader.vim", __FILE__)
13
+ specs = File.expand_path("../../spec/acceptance/*_spec.vim", __FILE__)
14
+ root = File.expand_path("../..", __FILE__)
15
+ exitstatus = 0
16
+
17
+ Dir.glob(specs) do |vader_spec|
18
+ Tempfile.open("vader.out") do |tmp|
19
+ Dir.chdir(root) do
20
+ system(
21
+ {
22
+ "VADER_OUTPUT_FILE" => tmp.path,
23
+ "NVIM_RPLUGIN_MANIFEST" => "spec/acceptance/runtime/rplugin.vim"
24
+ },
25
+ "bash", "-c",
26
+ "#{nvim} --headless -nu spec/acceptance/runtime/init.vim +'Vader! #{vader_spec}'"
27
+ )
28
+ end
29
+
30
+ if $?.success?
31
+ puts "[✔] #{vader_spec}"
32
+ else
33
+ exitstatus = $?.exitstatus
34
+ IO.copy_stream(tmp, $stderr)
35
+ puts "[✘] #{vader_spec}"
36
+ end
37
+ end
38
+ end
39
+
40
+ if exitstatus == 0
41
+ puts "[✔] Acceptance tests passed."
42
+ else
43
+ puts "[✘] Acceptance tests failed."
44
+ end
45
+
46
+ exit(exitstatus)
@@ -10,6 +10,7 @@ buffer_docs = []
10
10
  window_docs = []
11
11
  tabpage_docs = []
12
12
  nvim_exe = ENV.fetch("NVIM_EXECUTABLE", "nvim")
13
+ nvim_vrs = %x(#{nvim_exe} --version).split("\n").first
13
14
 
14
15
  session = Neovim::Session.child([nvim_exe, "-u", "NONE", "-n"])
15
16
  vim_defs = Neovim::Client.instance_methods(false)
@@ -68,5 +69,11 @@ lib_dir = Pathname.new(File.expand_path("../../lib/neovim", __FILE__))
68
69
  contents = File.read(path)
69
70
  doc_str = ["=begin", *docs, "=end"].join("\n")
70
71
 
71
- File.write(path, contents.sub(/=begin.+=end/m, doc_str))
72
+ contents.sub!(/=begin.+=end/m, doc_str)
73
+ contents.sub!(
74
+ /# The methods documented here were generated using .+$/,
75
+ "# The methods documented here were generated using #{nvim_vrs}"
76
+ )
77
+
78
+ File.write(path, contents)
72
79
  end
@@ -0,0 +1,19 @@
1
+ Given:
2
+ one
3
+ two
4
+
5
+ Execute (Update remote plugins):
6
+ silent UpdateRemotePlugins
7
+
8
+ Execute (Call rplugin command):
9
+ PlugSetFoo bar
10
+ sleep 100m
11
+ AssertEqual "bar", g:PlugFoo
12
+
13
+ Execute (Call rplugin function):
14
+ AssertEqual 3, PlugAdd(1, 2)
15
+
16
+ Execute (Trigger rplugin autocmd):
17
+ silent edit foo.rb
18
+ sleep 100m
19
+ AssertEqual 1, g:PlugInRuby
@@ -0,0 +1,94 @@
1
+ Execute (Set nvim_version):
2
+ if has('nvim')
3
+ let g:nvim_version = api_info()['version']
4
+ else
5
+ let g:nvim_version = {'major': 99, 'minor': 99, 'patch': 99}
6
+ endif
7
+
8
+ Given:
9
+ one
10
+ two
11
+
12
+ Execute (Access `Vim` and `VIM` constants):
13
+ ruby Vim.command('1normal! Sfirst')
14
+ ruby VIM.command('2normal! Ssecond')
15
+
16
+ Expect:
17
+ first
18
+ second
19
+
20
+ Execute (Access `$curbuf` global variable):
21
+ ruby $curbuf[1] = "first"
22
+
23
+ Expect:
24
+ first
25
+ two
26
+
27
+ Execute (Access `$curwin` global variable):
28
+ ruby $curwin.buffer[1] = "first"
29
+
30
+ Expect:
31
+ first
32
+ two
33
+
34
+ Execute (Define a Ruby method):
35
+ ruby def foo; Vim.command("let g:called = 1"); end
36
+
37
+ Execute (Call a Ruby method):
38
+ ruby foo
39
+
40
+ Then:
41
+ AssertEqual 1, g:called
42
+
43
+ Execute (Update instance state on `$curbuf`):
44
+ ruby $curbuf.instance_variable_set(:@foo, 123)
45
+ ruby Vim.command("let g:foo = #{$curbuf.instance_variable_get(:@foo)}")
46
+
47
+ Then:
48
+ AssertEqual 123, g:foo
49
+
50
+ Execute (Change the working directory explicitly):
51
+ cd /
52
+ ruby Vim.command("let g:ruby_pwd = '#{Dir.pwd}'")
53
+ cd -
54
+
55
+ Then:
56
+ if g:nvim_version['major'] > 0 || g:nvim_version['minor'] >= 2
57
+ AssertEqual "/", g:ruby_pwd
58
+ endif
59
+
60
+ Execute (Change the working directory implicitly):
61
+ split | lcd /
62
+ ruby Vim.command("let g:before_pwd = '#{Dir.pwd}'")
63
+ wincmd p
64
+ ruby Vim.command("let g:after_pwd = '#{Dir.pwd}'")
65
+ wincmd p | lcd -
66
+
67
+ Then:
68
+ if g:nvim_version['major'] > 0 || g:nvim_version['minor'] >= 2
69
+ AssertNotEqual g:before_pwd, g:after_pwd
70
+ endif
71
+
72
+ Execute (Raise a Ruby standard error):
73
+ try
74
+ ruby raise "BOOM"
75
+ catch /BOOM/
76
+ endtry
77
+
78
+ ruby $curbuf[1] = "still works"
79
+
80
+ Expect:
81
+ still works
82
+ two
83
+
84
+ Execute (Raise a Ruby syntax error):
85
+ try
86
+ ruby puts[
87
+ catch /SyntaxError/
88
+ endtry
89
+
90
+ ruby $curbuf[1] = "still works"
91
+
92
+ Expect:
93
+ still works
94
+ two