nvim 1.0.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/INFO.yaml +18 -0
- data/LICENSE +52 -0
- data/README.md +264 -0
- data/Rakefile +68 -0
- data/bin/neovim-ruby-host +51 -0
- data/lib/neovim/client.rb +108 -0
- data/lib/neovim/connection.rb +129 -0
- data/lib/neovim/foreign/mplight/bufferio.rb +51 -0
- data/lib/neovim/foreign/mplight.rb +327 -0
- data/lib/neovim/foreign/supplement/socket.rb +20 -0
- data/lib/neovim/foreign/supplement.rb +34 -0
- data/lib/neovim/handler.rb +139 -0
- data/lib/neovim/host.rb +87 -0
- data/lib/neovim/info.rb +10 -0
- data/lib/neovim/logging.rb +249 -0
- data/lib/neovim/messager.rb +185 -0
- data/lib/neovim/meta.rb +68 -0
- data/lib/neovim/remote.rb +56 -0
- data/lib/neovim/remote_object.rb +331 -0
- data/lib/neovim/ruby_provider.rb +372 -0
- data/lib/neovim/session.rb +60 -0
- data/lib/neovim/vimscript_provider.rb +49 -0
- data/lib/neovim.rb +22 -0
- metadata +66 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: d8207d1ea220ae3a18b71de6377beaac8f117b7b8fb2c816f773a36dc2852043
|
4
|
+
data.tar.gz: eb0c7bf8c52bc66a26952c5985edc3a0ffca154b0ba51560f9802428e51594b2
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 17c4b731220d2da8b667da00bfba85b63f27664d0d6119f4d021b92e66c24ecabd279abc090b8cba6b5ff84baeb2561d6ce3410c7fabb1c91a94857c82d2f82e
|
7
|
+
data.tar.gz: 3197fe71bdd9506350206fff209e2b0c9fb93bfa926f204e4bebcbacfee849a566b42f9f576efdeb86ee751fbc7b8197a07329fe6e2e9191b735ad86ac3c9604
|
data/INFO.yaml
ADDED
@@ -0,0 +1,18 @@
|
|
1
|
+
#
|
2
|
+
# INFO.yaml -- Version number etc.
|
3
|
+
#
|
4
|
+
|
5
|
+
nvim:
|
6
|
+
version: 1.0.0
|
7
|
+
license: BSD-2-Clause+
|
8
|
+
authors:
|
9
|
+
- Bertram Scharpf
|
10
|
+
email: software@bertram-scharpf.de
|
11
|
+
|
12
|
+
summary: Yet another Ruby client for Neovim
|
13
|
+
description: |-
|
14
|
+
A simple Ruby client for Neovim.
|
15
|
+
Clean code, minimal dependecies, no frills, no wokeness.
|
16
|
+
|
17
|
+
homepage: http://bertram-scharpf.de
|
18
|
+
|
data/LICENSE
ADDED
@@ -0,0 +1,52 @@
|
|
1
|
+
# BSD-2-clause license, extended by language use conditions
|
2
|
+
|
3
|
+
Copyright (C) 2024, Bertram Scharpf <software@bertram-scharpf.de>.
|
4
|
+
All rights reserved.
|
5
|
+
|
6
|
+
Redistribution and use in source and binary forms, with or without
|
7
|
+
modification, are permitted provided that the following conditions are
|
8
|
+
met:
|
9
|
+
|
10
|
+
* Redistributions of source code must retain the above copyright
|
11
|
+
notice, this list of conditions and the following disclaimer.
|
12
|
+
|
13
|
+
* Redistributions in binary form must reproduce the above copyright
|
14
|
+
notice, this list of conditions and the following disclaimer in
|
15
|
+
the documentation and/or other materials provided with the
|
16
|
+
distribution.
|
17
|
+
|
18
|
+
* Redistributions must not contain any clauses about anticipated
|
19
|
+
harassment or discrimination, nor must they be held in a so-called
|
20
|
+
"inclusive language". As far as German language is used, the
|
21
|
+
conditions mentioned below additionally apply.
|
22
|
+
|
23
|
+
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
|
24
|
+
IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
|
25
|
+
TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
|
26
|
+
PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
|
27
|
+
OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
28
|
+
EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
29
|
+
PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
30
|
+
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
31
|
+
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
32
|
+
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
33
|
+
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
34
|
+
|
35
|
+
|
36
|
+
## Use of the German Language
|
37
|
+
|
38
|
+
Beim Gebrauch deutscher Sprache sind Weiterentwicklungen und
|
39
|
+
-verbreitungen nur gestattet unter Einhaltung folgender
|
40
|
+
zusätzlicher Bedingungen:
|
41
|
+
|
42
|
+
* Keine Verwendung von sogenannter „geschlechtergerechter Sprache“,
|
43
|
+
also Anfügen von weiblichen Endungen mit Binnen-I, Sternchen,
|
44
|
+
Doppelpunkt, Unterstrich oder ähnlichem, oder Konstruktionen, die
|
45
|
+
den Sachverhalt falsch wiedergeben („Radfahrende“, „Studierende“).
|
46
|
+
|
47
|
+
* Keine Verwendung der „reformierten Rechtschreibung“ von 1996,
|
48
|
+
insbesondere Doppel-S am Silbenende, „plazieren“ mit T, sowie
|
49
|
+
Großschreibung von Wendungen wie „des weiteren“.
|
50
|
+
|
51
|
+
|
52
|
+
<!-- vim:set ft=markdown : -->
|
data/README.md
ADDED
@@ -0,0 +1,264 @@
|
|
1
|
+
# Ruby-Nvim
|
2
|
+
|
3
|
+
Ruby support for [Neovim](https://github.com/neovim/neovim).
|
4
|
+
|
5
|
+
Clean code, minimal dependecies, no frills, no wokeness.
|
6
|
+
|
7
|
+
*I would have written a shorter letter, but I did not have the time.* --
|
8
|
+
Blaise Pascal
|
9
|
+
|
10
|
+
|
11
|
+
## Installation
|
12
|
+
|
13
|
+
```shell
|
14
|
+
sudo gem uninstall neovim || true
|
15
|
+
sudo gem install nvim
|
16
|
+
```
|
17
|
+
|
18
|
+
You may prefer to also install the dependencies. Yet, this is not
|
19
|
+
neccessary, as they are small and Ruby-Nvim includes a copy of them.
|
20
|
+
|
21
|
+
```shell
|
22
|
+
sudo gem install supplement mplight
|
23
|
+
```
|
24
|
+
|
25
|
+
|
26
|
+
## Usage
|
27
|
+
|
28
|
+
|
29
|
+
### Command, Function and Autoload Plugins
|
30
|
+
|
31
|
+
Put this into a new buffer:
|
32
|
+
|
33
|
+
```ruby
|
34
|
+
Neovim.plugin do |dsl|
|
35
|
+
dsl.command :SetLine, nargs: 1 do |client,(str)|
|
36
|
+
client.set_current_line str
|
37
|
+
end
|
38
|
+
dsl.function :Sum, nargs: 2, sync: true do |client,(x,y)|
|
39
|
+
x + y
|
40
|
+
end
|
41
|
+
dsl.autocmd :BufEnter, pattern: "*.rb" do |client|
|
42
|
+
client.command "echom 'Hello, Ruby!'"
|
43
|
+
end
|
44
|
+
end
|
45
|
+
```
|
46
|
+
|
47
|
+
Then run these Vim commands:
|
48
|
+
|
49
|
+
```vim
|
50
|
+
w ++p ~/.config/nvim/rplugin/ruby/demo.rb
|
51
|
+
UpdateRemotePlugins
|
52
|
+
|
53
|
+
" Check the generated manifest file
|
54
|
+
split ~/.local/share/nvim/rplugin.vim
|
55
|
+
help remote-plugin-manifest
|
56
|
+
```
|
57
|
+
|
58
|
+
Open a new Neovim and see what happens:
|
59
|
+
|
60
|
+
```vim
|
61
|
+
e dummy.rb
|
62
|
+
SetLine some text
|
63
|
+
echo Sum(13,7)
|
64
|
+
```
|
65
|
+
|
66
|
+
|
67
|
+
### Calling the :ruby... Interface
|
68
|
+
|
69
|
+
The `:ruby...` commands and the `rubyeval()` function behave as descibed
|
70
|
+
in `:h ruby`.
|
71
|
+
|
72
|
+
Additionally you can directly execute the buffers contents:
|
73
|
+
|
74
|
+
```vim
|
75
|
+
set number
|
76
|
+
```
|
77
|
+
|
78
|
+
```
|
79
|
+
1 class C
|
80
|
+
2 def f
|
81
|
+
3 :F
|
82
|
+
4 end
|
83
|
+
5 end
|
84
|
+
6 c = C.new
|
85
|
+
~
|
86
|
+
~
|
87
|
+
~
|
88
|
+
:1,6ruby |
|
89
|
+
```
|
90
|
+
|
91
|
+
The last value, if it is not `nil`, will be added through `#inspect` as
|
92
|
+
a comment.
|
93
|
+
|
94
|
+
```
|
95
|
+
1 class C
|
96
|
+
2 def f
|
97
|
+
3 :F
|
98
|
+
4 end
|
99
|
+
5 end
|
100
|
+
6 c = C.new
|
101
|
+
7 #=> #<C:0x000001b347456478>
|
102
|
+
~
|
103
|
+
~
|
104
|
+
:
|
105
|
+
```
|
106
|
+
|
107
|
+
The classes and variables will be preserved and are available during the
|
108
|
+
next call.
|
109
|
+
|
110
|
+
```
|
111
|
+
5 end
|
112
|
+
6 c = C.new
|
113
|
+
7 #=> #<C:0x00001fd2fd1f89d0>
|
114
|
+
8 [ c.f, C]
|
115
|
+
~
|
116
|
+
~
|
117
|
+
~
|
118
|
+
:8ruby |
|
119
|
+
```
|
120
|
+
|
121
|
+
This results in:
|
122
|
+
|
123
|
+
```
|
124
|
+
7 #=> #<C:0x00001fd2fd1f89d0>
|
125
|
+
8 [ c.f, C]
|
126
|
+
9 #=> [:F, C]
|
127
|
+
~
|
128
|
+
~
|
129
|
+
:
|
130
|
+
```
|
131
|
+
|
132
|
+
Output will be added to the buffer, too.
|
133
|
+
|
134
|
+
```
|
135
|
+
1 puts "ba" + "na"*2
|
136
|
+
2 print "hell"
|
137
|
+
3 puts "o"
|
138
|
+
~
|
139
|
+
~
|
140
|
+
:%ruby |
|
141
|
+
```
|
142
|
+
|
143
|
+
Further, a simple number/cash summing tool is included.
|
144
|
+
|
145
|
+
```
|
146
|
+
Apples : 3.99
|
147
|
+
Bananas : 5 * 0.40 # multiplication
|
148
|
+
Oranges : 3.59 | -10% # percentage added (here subtracted)
|
149
|
+
Kiwi : 0,40 # comma is allowed
|
150
|
+
Coconut : 5,- # empty decimal places
|
151
|
+
~
|
152
|
+
~
|
153
|
+
:%ruby +
|
154
|
+
```
|
155
|
+
|
156
|
+
|
157
|
+
### Modern rpcrequest() Calls
|
158
|
+
|
159
|
+
Put this into a new buffer:
|
160
|
+
|
161
|
+
```ruby
|
162
|
+
require "neovim"
|
163
|
+
counter = 0
|
164
|
+
Neovim.start_remote do |dsl|
|
165
|
+
dsl.register_handler "rb_add" do |client,n|
|
166
|
+
counter += n
|
167
|
+
client.command "echo 'Counter value now is: '..#{counter}..'.'"
|
168
|
+
end
|
169
|
+
dsl.register_handler "rb_raise" do |client|
|
170
|
+
raise "Ouch!"
|
171
|
+
end
|
172
|
+
end
|
173
|
+
```
|
174
|
+
|
175
|
+
Then enter these Vim commands:
|
176
|
+
|
177
|
+
```vim
|
178
|
+
w demo_remote.rb
|
179
|
+
let chan = jobstart(['ruby','demo_remote.rb'], { 'rpc': v:true })
|
180
|
+
call rpcrequest(chan, 'rb_add', 7)
|
181
|
+
call rpcrequest(chan, 'rb_raise')
|
182
|
+
call jobstop(chan)
|
183
|
+
```
|
184
|
+
|
185
|
+
If you prefer, you can also use a shebang line.
|
186
|
+
|
187
|
+
```ruby
|
188
|
+
#!/usr/bin/env ruby
|
189
|
+
require "neovim"
|
190
|
+
Neovim.start_remote do |dsl|
|
191
|
+
# ... (as above)
|
192
|
+
end
|
193
|
+
```
|
194
|
+
|
195
|
+
Then enter these Vim commands:
|
196
|
+
|
197
|
+
```vim
|
198
|
+
w demo_remote.rb
|
199
|
+
!chmod +x %
|
200
|
+
let chan = jobstart('./demo_remote.rb', { 'rpc': v:true })
|
201
|
+
" proceed as above
|
202
|
+
```
|
203
|
+
|
204
|
+
|
205
|
+
### Logging and Debugging
|
206
|
+
|
207
|
+
Logging is a easy as this:
|
208
|
+
|
209
|
+
```shell
|
210
|
+
export NVIM_RUBY_LOG_LEVEL=all NVIM_RUBY_LOG_FILE=nvim.log
|
211
|
+
nvim +'ruby puts "hi"*10'
|
212
|
+
```
|
213
|
+
|
214
|
+
To show the log levels, simply run in Neovim:
|
215
|
+
|
216
|
+
```vim
|
217
|
+
ruby puts Neovim::Logging::LEVELS.keys
|
218
|
+
```
|
219
|
+
|
220
|
+
If you are inside a [Tmux](https://tmux.github.io), you might prefer to trace the colored log in a split window.
|
221
|
+
|
222
|
+
```shell
|
223
|
+
tmux split-window -fhd 'echo -e "\e[33m==== $$ ==== `tty` ====\e[m" ; ln -sf `tty` /tmp/tmux-`id -u`/debug ; exec cat >/dev/null 2>&1'
|
224
|
+
export NVIM_RUBY_LOG_LEVEL=all NVIM_RUBY_LOG_FILE=/tmp/tmux-`id -u`/debug
|
225
|
+
|
226
|
+
examples/demo_attach
|
227
|
+
|
228
|
+
nvim +'ruby puts "hi"*10'
|
229
|
+
```
|
230
|
+
|
231
|
+
You may start an interactive session and control a running Neovim through it.
|
232
|
+
Open Neovim specifying the `--listen` option
|
233
|
+
|
234
|
+
```shell
|
235
|
+
nvim --listen /path/to/some.sock
|
236
|
+
```
|
237
|
+
|
238
|
+
or ask the running Neovim for its server name.
|
239
|
+
|
240
|
+
```vim
|
241
|
+
echo v:servername
|
242
|
+
```
|
243
|
+
|
244
|
+
Then connect to it. This requires the [Intar](https://github.com/BertramScharpf/ruby-intar) gem.
|
245
|
+
|
246
|
+
```
|
247
|
+
$ intar -r neovim/remote
|
248
|
+
main:0:001> include Neovim
|
249
|
+
=> Object
|
250
|
+
main:0:002> Remote.start_client ConnectionUnix, "/path/to/some.sock" do |c|&
|
251
|
+
main:1:001> c.command "e /etc/passwd"
|
252
|
+
main:1:002> b = c.get_current_buf
|
253
|
+
=> #<Neovim::Buffer:400 1>
|
254
|
+
main:1:003> b[1]
|
255
|
+
=> ["root:*:0:0:Charlie &:/root:/bin/sh"]
|
256
|
+
main:1:004> \q!!
|
257
|
+
```
|
258
|
+
|
259
|
+
|
260
|
+
## Copyright
|
261
|
+
|
262
|
+
* (C) 2024 Bertram Scharpf <software@bertram-scharpf.de>
|
263
|
+
* License: [BSD-2-Clause+](./LICENSE)
|
264
|
+
|
data/Rakefile
ADDED
@@ -0,0 +1,68 @@
|
|
1
|
+
#
|
2
|
+
# Rakefile -- Generate files
|
3
|
+
#
|
4
|
+
|
5
|
+
|
6
|
+
INFOFILE = "lib/neovim/info.rb"
|
7
|
+
|
8
|
+
|
9
|
+
GENERATED = [ INFOFILE]
|
10
|
+
|
11
|
+
task :default => GENERATED
|
12
|
+
task :infofile => INFOFILE
|
13
|
+
|
14
|
+
|
15
|
+
file INFOFILE => "INFO.yaml" do |f|
|
16
|
+
create_info f.name, f.source
|
17
|
+
end
|
18
|
+
|
19
|
+
|
20
|
+
task :clean do
|
21
|
+
rm *GENERATED
|
22
|
+
end
|
23
|
+
|
24
|
+
|
25
|
+
def commit
|
26
|
+
c = `git rev-parse --short HEAD`
|
27
|
+
c.chomp!
|
28
|
+
c
|
29
|
+
end
|
30
|
+
|
31
|
+
def create_info dst, src
|
32
|
+
File.open dst, "w" do |vf|
|
33
|
+
require "yaml"
|
34
|
+
m = YAML.load File.read src
|
35
|
+
name = m.keys.first
|
36
|
+
args = m[ name]
|
37
|
+
args[ :commit] = commit
|
38
|
+
unless args[ :authors] then
|
39
|
+
u = args.delete :author
|
40
|
+
args[ :authors] = [ u] if u
|
41
|
+
end
|
42
|
+
vf.puts 'require "neovim/meta.rb"'
|
43
|
+
vf.print "Neovim::INFO = Neovim::Meta.new #{name.inspect}"
|
44
|
+
args.each { |k,v|
|
45
|
+
vf.puts ","
|
46
|
+
vf.print " #{k.to_sym}: #{v.inspect}"
|
47
|
+
}
|
48
|
+
vf.puts
|
49
|
+
end
|
50
|
+
end
|
51
|
+
|
52
|
+
|
53
|
+
task :diffdeps do
|
54
|
+
%w(mplight).each { |gem|
|
55
|
+
c = `gem contents #{gem}`
|
56
|
+
unless $?.success? then
|
57
|
+
puts "Gem #{gem} not installed. Cannot compare."
|
58
|
+
next
|
59
|
+
end
|
60
|
+
(c.split $/).each { |file|
|
61
|
+
if file =~ %r[/gems/#{gem}-.*/lib/(.*\.rb)$] then
|
62
|
+
ours = "lib/neovim/foreign/#$1"
|
63
|
+
sh *%W(nvim -d #{ours} #{file}) if File.exist? ours
|
64
|
+
end
|
65
|
+
}
|
66
|
+
}
|
67
|
+
end
|
68
|
+
|
@@ -0,0 +1,51 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
#
|
4
|
+
# bin/neovim-ruby-host -- Child started by Neovim
|
5
|
+
#
|
6
|
+
|
7
|
+
require "neovim/host"
|
8
|
+
|
9
|
+
|
10
|
+
module Neovim
|
11
|
+
|
12
|
+
class <<self
|
13
|
+
|
14
|
+
def plugin &block
|
15
|
+
require "neovim/vimscript_provider"
|
16
|
+
run_dsl DslVimscript, &block
|
17
|
+
end
|
18
|
+
|
19
|
+
private
|
20
|
+
|
21
|
+
def run_dsl dsl
|
22
|
+
@host or raise "Can't add plugins outside of a running session."
|
23
|
+
dsl.open @path, @host do |dsl|
|
24
|
+
yield dsl
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
end
|
29
|
+
|
30
|
+
if $*.delete "--version" then
|
31
|
+
puts [ Neovim::INFO.name, Neovim::INFO.version].join " "
|
32
|
+
exit
|
33
|
+
end
|
34
|
+
|
35
|
+
r = Host.run do |h|
|
36
|
+
begin
|
37
|
+
@host = h
|
38
|
+
$*.each do |p|
|
39
|
+
@path = p
|
40
|
+
Kernel.load @path, true
|
41
|
+
ensure
|
42
|
+
@path = nil
|
43
|
+
end
|
44
|
+
ensure
|
45
|
+
@host = nil
|
46
|
+
end
|
47
|
+
end
|
48
|
+
exit r.to_i
|
49
|
+
|
50
|
+
end
|
51
|
+
|
@@ -0,0 +1,108 @@
|
|
1
|
+
#
|
2
|
+
# neovim/client.rb -- Clients
|
3
|
+
#
|
4
|
+
|
5
|
+
require "neovim/foreign/supplement"
|
6
|
+
|
7
|
+
require "neovim/remote_object"
|
8
|
+
|
9
|
+
|
10
|
+
module Neovim
|
11
|
+
|
12
|
+
class Client
|
13
|
+
|
14
|
+
@strict = true
|
15
|
+
class <<self
|
16
|
+
attr_accessor :strict
|
17
|
+
end
|
18
|
+
|
19
|
+
class UnknownApiFunction < RuntimeError ; end
|
20
|
+
class UnknownApiObjectFunction < RuntimeError ; end
|
21
|
+
|
22
|
+
|
23
|
+
attr_reader :channel_id
|
24
|
+
|
25
|
+
def initialize comm, channel_id
|
26
|
+
@comm, @channel_id = comm, channel_id
|
27
|
+
@functions = {}
|
28
|
+
@objfuncs = Hash.new do |h,k| h[k] = {} end
|
29
|
+
end
|
30
|
+
|
31
|
+
def inspect
|
32
|
+
"#<#{self.class} #@channel_id>"
|
33
|
+
end
|
34
|
+
|
35
|
+
def add_functions list, prefixes
|
36
|
+
list.each { |fn|
|
37
|
+
next if fn[ "deprecated_since"] && self.class.strict
|
38
|
+
n = fn[ "name"]
|
39
|
+
next unless n =~ /\Anvim_/
|
40
|
+
@functions[ $'.to_sym] = n
|
41
|
+
t, = prefixes.find { |t,p| n =~ p }
|
42
|
+
@objfuncs[ t][ $'.to_sym] = n if t
|
43
|
+
}
|
44
|
+
end
|
45
|
+
|
46
|
+
|
47
|
+
def call_api name, *args
|
48
|
+
f = @functions[ name.to_sym]
|
49
|
+
f or raise UnknownApiFunction, "Function: #{name}"
|
50
|
+
@comm.request f, *args
|
51
|
+
end
|
52
|
+
|
53
|
+
def call_obj obj, name, *args
|
54
|
+
n = obj.type
|
55
|
+
f = @objfuncs[ n.to_sym][ name.to_sym]
|
56
|
+
f or raise UnknownApiObjectFunction, "Object: #{n}, Function: #{name}"
|
57
|
+
@comm.request f, obj.index, *args
|
58
|
+
end
|
59
|
+
|
60
|
+
|
61
|
+
|
62
|
+
def method_missing sym, *args
|
63
|
+
call_api sym, *args
|
64
|
+
rescue UnknownApiFunction
|
65
|
+
super
|
66
|
+
end
|
67
|
+
|
68
|
+
def respond_to_missing? sym, priv = nil
|
69
|
+
# Be aware that calling a proc (our handlers) with a single argument
|
70
|
+
# asks whether that argument is an array. In case it is a Client object,
|
71
|
+
# we end up here with +sym = to_ary+.
|
72
|
+
@functions[ sym.to_sym].to_bool
|
73
|
+
end
|
74
|
+
|
75
|
+
def methods regular = true
|
76
|
+
s = super
|
77
|
+
s |= @functions.keys if regular
|
78
|
+
s
|
79
|
+
end
|
80
|
+
|
81
|
+
|
82
|
+
def has_obj_function? obj, name
|
83
|
+
@objfuncs[ obj.type][ name.to_sym].to_bool
|
84
|
+
end
|
85
|
+
|
86
|
+
def obj_functions obj
|
87
|
+
@objfuncs[ obj.type].keys
|
88
|
+
end
|
89
|
+
|
90
|
+
|
91
|
+
|
92
|
+
def message str
|
93
|
+
call_api :out_write, str
|
94
|
+
str.end_with? $/ or call_api :out_write, $/
|
95
|
+
end
|
96
|
+
|
97
|
+
|
98
|
+
include OptionAccess
|
99
|
+
OPTION_PARAM = nil
|
100
|
+
|
101
|
+
def command arg ; call_api :command, arg ; end
|
102
|
+
|
103
|
+
def evaluate expr ; call_api :eval, expr ; end
|
104
|
+
|
105
|
+
end
|
106
|
+
|
107
|
+
end
|
108
|
+
|
@@ -0,0 +1,129 @@
|
|
1
|
+
#
|
2
|
+
# neovim/connection.rb -- Connections
|
3
|
+
#
|
4
|
+
|
5
|
+
require "neovim/logging"
|
6
|
+
require "neovim/client"
|
7
|
+
require "neovim/info"
|
8
|
+
|
9
|
+
|
10
|
+
module Neovim
|
11
|
+
|
12
|
+
class Connection < MPLight::Types
|
13
|
+
|
14
|
+
include Logging
|
15
|
+
|
16
|
+
include MPLight::Packer, MPLight::Unpacker
|
17
|
+
|
18
|
+
attr_reader :client
|
19
|
+
|
20
|
+
def initialize rd, wr
|
21
|
+
super
|
22
|
+
default_to_string!
|
23
|
+
init_input rd
|
24
|
+
init_output wr
|
25
|
+
@errors = {}
|
26
|
+
end
|
27
|
+
|
28
|
+
def additional_data ; [ *super, @client] ; end
|
29
|
+
|
30
|
+
|
31
|
+
def error id
|
32
|
+
@errors[ id] || "Error #{id}"
|
33
|
+
end
|
34
|
+
|
35
|
+
|
36
|
+
def start comm, client_name, client_type, client_methods = nil
|
37
|
+
comm.notify :nvim_set_client_info, client_name, Neovim::INFO.version_h, client_type, client_methods||{}, Neovim::INFO.attributes
|
38
|
+
channel_id, api_info = *(comm.request :nvim_get_api_info)
|
39
|
+
@client = Client.new comm, channel_id
|
40
|
+
prefixes = {}
|
41
|
+
api_info[ "types"].each do |type,info|
|
42
|
+
type = type.to_sym
|
43
|
+
prefixes[ type] = /\A#{info[ "prefix"]}/
|
44
|
+
register_type type, info[ "id"]
|
45
|
+
end
|
46
|
+
@client.add_functions api_info[ "functions"], prefixes
|
47
|
+
api_info[ "error_types"].each { |type,info|
|
48
|
+
register_error type, info[ "id"]
|
49
|
+
}
|
50
|
+
nil
|
51
|
+
end
|
52
|
+
|
53
|
+
private
|
54
|
+
|
55
|
+
def register_type type, id
|
56
|
+
klass = Neovim.const_get type
|
57
|
+
klass or raise "Class #{type} is not defined."
|
58
|
+
klass < RemoteObject or raise "Class #{klass} is not a descendant of RemoteObject."
|
59
|
+
log :debug2, "Registering type", type: type, id: id
|
60
|
+
register id, klass
|
61
|
+
end
|
62
|
+
|
63
|
+
def register_error id, type
|
64
|
+
@errors[ id] = type
|
65
|
+
end
|
66
|
+
|
67
|
+
end
|
68
|
+
|
69
|
+
|
70
|
+
class ConnectionTcp < Connection
|
71
|
+
class <<self
|
72
|
+
def open_files host, port
|
73
|
+
require "socket"
|
74
|
+
TCPSocket.open host, port do |socket|
|
75
|
+
yield (new socket, socket)
|
76
|
+
end
|
77
|
+
end
|
78
|
+
end
|
79
|
+
end
|
80
|
+
|
81
|
+
class ConnectionUnix < Connection
|
82
|
+
class <<self
|
83
|
+
def open_files path
|
84
|
+
require "socket"
|
85
|
+
UNIXSocket.open path do |socket|
|
86
|
+
yield (new socket, socket)
|
87
|
+
end
|
88
|
+
end
|
89
|
+
end
|
90
|
+
end
|
91
|
+
|
92
|
+
class ConnectionChild < Connection
|
93
|
+
|
94
|
+
class <<self
|
95
|
+
|
96
|
+
def open_files *argv
|
97
|
+
eb = "--embed"
|
98
|
+
argv.unshift eb unless argv.include? eb
|
99
|
+
argv.unshift path
|
100
|
+
IO.popen argv, "r+" do |io|
|
101
|
+
Process.detach io.pid
|
102
|
+
yield (new io, io)
|
103
|
+
end
|
104
|
+
end
|
105
|
+
|
106
|
+
def path
|
107
|
+
ENV[ "NVIM_EXECUTABLE"].notempty? || "nvim"
|
108
|
+
end
|
109
|
+
|
110
|
+
def version
|
111
|
+
IO.popen [ path, "--version"] do |io|
|
112
|
+
io.gets[ /\ANVIM +v?(.+)/, 1]
|
113
|
+
end
|
114
|
+
end
|
115
|
+
|
116
|
+
end
|
117
|
+
|
118
|
+
end
|
119
|
+
|
120
|
+
class ConnectionStdio < Connection
|
121
|
+
class <<self
|
122
|
+
def open_files *argv
|
123
|
+
yield (new $stdin, $stdout)
|
124
|
+
end
|
125
|
+
end
|
126
|
+
end
|
127
|
+
|
128
|
+
end
|
129
|
+
|