neovim 0.3.3 → 0.4.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.gitignore +1 -0
- data/.gitmodules +3 -0
- data/.travis.yml +1 -1
- data/CHANGELOG.md +6 -0
- data/Rakefile +14 -3
- data/lib/neovim.rb +10 -1
- data/lib/neovim/buffer.rb +2 -0
- data/lib/neovim/client.rb +2 -0
- data/lib/neovim/executable.rb +33 -0
- data/lib/neovim/ruby_provider.rb +32 -58
- data/lib/neovim/ruby_provider/vim.rb +15 -1
- data/lib/neovim/tabpage.rb +3 -0
- data/lib/neovim/version.rb +1 -1
- data/lib/neovim/window.rb +3 -0
- data/script/acceptance_tests +46 -0
- data/script/generate_docs +8 -1
- data/spec/acceptance/rplugin_spec.vim +19 -0
- data/spec/acceptance/ruby_spec.vim +94 -0
- data/spec/acceptance/rubydo_spec.vim +66 -0
- data/spec/acceptance/rubyfile/call_foo.rb +1 -0
- data/spec/acceptance/rubyfile/curbuf.rb +1 -0
- data/spec/acceptance/rubyfile/curbuf_ivar_get.rb +1 -0
- data/spec/acceptance/rubyfile/curbuf_ivar_set.rb +1 -0
- data/spec/acceptance/rubyfile/curwin.rb +1 -0
- data/spec/acceptance/rubyfile/define_foo.rb +3 -0
- data/spec/acceptance/rubyfile/raise_standard_error.rb +1 -0
- data/spec/acceptance/rubyfile/raise_syntax_error.rb +1 -0
- data/spec/acceptance/rubyfile/set_pwd_after.rb +1 -0
- data/spec/acceptance/rubyfile/set_pwd_before.rb +1 -0
- data/spec/acceptance/rubyfile/vim_constants.rb +2 -0
- data/spec/acceptance/rubyfile_spec.vim +111 -0
- data/spec/acceptance/runtime/init.vim +1 -0
- data/spec/acceptance/runtime/rplugin/ruby/plugin.rb +13 -0
- data/spec/documentation_spec.rb +24 -0
- data/spec/helper.rb +20 -45
- data/spec/neovim/executable_spec.rb +32 -0
- data/spec/neovim/host_spec.rb +2 -2
- data/spec/neovim/ruby_provider/vim_spec.rb +38 -0
- data/spec/neovim_spec.rb +6 -0
- data/spec/support.rb +45 -0
- metadata +46 -7
- data/spec/acceptance/neovim-ruby-host_spec.rb +0 -69
- data/spec/acceptance/ruby_provider_spec.rb +0 -256
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 421a9bb0ec7f5498ee9f00e98a191abf1972c46e
|
4
|
+
data.tar.gz: b6bdeee0789c0c59cb1337a36826534c1f6a2bb3
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: '079597075fd27fd08cd707bbbb5243579db5bf8fe59ea4fc594fa4eca271864f3bc90e4d318527209c161669c150d214d7abeec4aadafbcb0b20d1359b987f97'
|
7
|
+
data.tar.gz: ad2c5fc451b6b86825edc84d2780e28b5a3a525a1ebaa191e078fa03893fd77a199e10d1265a6dac92fd53c29353b9abbe36847be420afd19f08a6cbe56c88cf
|
data/.gitignore
CHANGED
data/.gitmodules
ADDED
data/.travis.yml
CHANGED
data/CHANGELOG.md
CHANGED
@@ -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"]
|
data/lib/neovim.rb
CHANGED
@@ -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=[
|
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
|
data/lib/neovim/buffer.rb
CHANGED
data/lib/neovim/client.rb
CHANGED
@@ -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
|
data/lib/neovim/ruby_provider.rb
CHANGED
@@ -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__(:
|
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
|
-
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
|
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
|
|
data/lib/neovim/tabpage.rb
CHANGED
data/lib/neovim/version.rb
CHANGED
data/lib/neovim/window.rb
CHANGED
@@ -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)
|
data/script/generate_docs
CHANGED
@@ -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
|
-
|
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
|