neovim 0.3.3 → 0.4.0

Sign up to get free protection for your applications and to get access to all the features.
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