nvim 1.4.0 → 1.5.1
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.
- checksums.yaml +4 -4
- data/INFO.yaml +1 -1
- data/LICENSE +2 -2
- data/README.md +96 -5
- data/examples/demo.rb +35 -0
- data/examples/demo_attach +38 -0
- data/examples/demo_intar +47 -0
- data/examples/demo_remote.rb +36 -0
- data/examples/demo_remote_inside_block.rb +47 -0
- data/examples/demo_sub +30 -0
- data/examples/dump_api +99 -0
- data/examples/passwords +78 -0
- data/lib/neovim/client.rb +20 -7
- data/lib/neovim/connection.rb +25 -7
- data/lib/neovim/foreign/supplement.rb +4 -0
- data/lib/neovim/handler.rb +4 -0
- data/lib/neovim/host.rb +34 -3
- data/lib/neovim/info.rb +2 -2
- data/lib/neovim/logging.rb +2 -2
- data/lib/neovim/remote.rb +10 -9
- data/lib/neovim/remote_object.rb +1 -1
- data/lib/neovim/ruby_provider.rb +14 -14
- data/lib/neovim/tools/calculator.rb +15 -6
- data/lib/neovim.rb +1 -5
- data/nvim.gemspec +31 -0
- metadata +27 -10
- data/TODO +0 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: b2f33b262cf70f6226c1af40d6b6173c56f5d808e7e4ba6629caa342f3131944
|
4
|
+
data.tar.gz: b78833e0442c2ba8e6a74786576bb4dcfecf5ecebf005bd45dd1c9b4a49732f5
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 49a0ba665e6d93a4f629b1b0375c29237d90cbb2510bb99d4ff3e4533f7e5cab68c76ee841cc7b25a5117411f5fb5e2ab24d3763f9cf4fa9617b9bef4d693cab
|
7
|
+
data.tar.gz: 1dafb13f71a994566f383577de178766fa6e0dc05a36075dc2af53c77cf3c5a0c8b21ac8dc08835fcbe89824441b857a193cfa8a503537f8ad642775276b8f6b
|
data/INFO.yaml
CHANGED
data/LICENSE
CHANGED
@@ -36,8 +36,8 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
36
36
|
## Use of the German Language
|
37
37
|
|
38
38
|
Beim Gebrauch deutscher Sprache sind Weiterentwicklungen und
|
39
|
-
-verbreitungen nur gestattet unter Einhaltung
|
40
|
-
zusätzlicher Bedingungen:
|
39
|
+
-verbreitungen nur gestattet unter Einhaltung sowie abermaligen
|
40
|
+
Einforderns folgender zusätzlicher Bedingungen:
|
41
41
|
|
42
42
|
* Keine Verwendung von sogenannter „geschlechtergerechter Sprache“,
|
43
43
|
also Anfügen von weiblichen Endungen mit Binnen-I, Sternchen,
|
data/README.md
CHANGED
@@ -15,7 +15,7 @@ sudo gem uninstall neovim || true
|
|
15
15
|
sudo gem install nvim
|
16
16
|
```
|
17
17
|
|
18
|
-
You may prefer to also install the dependencies.
|
18
|
+
You may prefer to also install the dependencies. Yet, this is not
|
19
19
|
neccessary, as they are small and Ruby-Nvim includes a copy of them.
|
20
20
|
|
21
21
|
```shell
|
@@ -91,7 +91,7 @@ set number
|
|
91
91
|
:1,6ruby |
|
92
92
|
```
|
93
93
|
|
94
|
-
The last value, if it is not `nil`,
|
94
|
+
The last value, if it is not `nil`, will be added through `#inspect` as
|
95
95
|
a comment.
|
96
96
|
|
97
97
|
```
|
@@ -132,7 +132,44 @@ This results in:
|
|
132
132
|
:
|
133
133
|
```
|
134
134
|
|
135
|
-
|
135
|
+
To inhibit the output of the last value, add a minus (`-`) to the
|
136
|
+
`:ruby|` call.
|
137
|
+
|
138
|
+
```
|
139
|
+
pp Regexp.constants
|
140
|
+
~
|
141
|
+
~
|
142
|
+
:.ruby |-
|
143
|
+
```
|
144
|
+
|
145
|
+
In this case, you may even omit the pipe (`|`) character.
|
146
|
+
|
147
|
+
|
148
|
+
#### Last return value
|
149
|
+
|
150
|
+
The anonymous variable `_` will hold the result
|
151
|
+
of the last evaluation.
|
152
|
+
|
153
|
+
```
|
154
|
+
1 7*11*13
|
155
|
+
~
|
156
|
+
~
|
157
|
+
:%ruby |
|
158
|
+
```
|
159
|
+
|
160
|
+
Then this will work:
|
161
|
+
|
162
|
+
```
|
163
|
+
1 7*11*13
|
164
|
+
2 #=> 1001
|
165
|
+
3 _ - 1
|
166
|
+
~
|
167
|
+
~
|
168
|
+
:3ruby |
|
169
|
+
```
|
170
|
+
|
171
|
+
|
172
|
+
#### Standard output
|
136
173
|
|
137
174
|
Output will be added to the buffer, too.
|
138
175
|
|
@@ -142,9 +179,63 @@ Output will be added to the buffer, too.
|
|
142
179
|
3 puts "o"
|
143
180
|
~
|
144
181
|
~
|
182
|
+
:1,3ruby |
|
183
|
+
```
|
184
|
+
|
185
|
+
Error output will be displayed on the command line,
|
186
|
+
highlighted by `ErrorMsg`.
|
187
|
+
|
188
|
+
```
|
189
|
+
1 $stderr.puts "Oh, no!"
|
190
|
+
~
|
191
|
+
~
|
192
|
+
:%ruby |
|
193
|
+
```
|
194
|
+
|
195
|
+
This even applies to subprocesses. They won't mess up
|
196
|
+
the RPC communication.
|
197
|
+
|
198
|
+
```
|
199
|
+
1 system *%w(ls -l)
|
200
|
+
2 system *%w(ls nonexistent)
|
201
|
+
~
|
202
|
+
~
|
145
203
|
:%ruby |
|
146
204
|
```
|
147
205
|
|
206
|
+
Yet, you should avoid to use `fork` and `exec`, except when
|
207
|
+
you're absolutely sure what you're doing.
|
208
|
+
|
209
|
+
|
210
|
+
### List all API functions
|
211
|
+
|
212
|
+
To show a list of the API functions call something like this:
|
213
|
+
|
214
|
+
```
|
215
|
+
pp $vim.functions.sort
|
216
|
+
pp $vim.obj_classes.map { |c| [ c.type, ($vim.obj_functions c).sort] }.to_h
|
217
|
+
~
|
218
|
+
~
|
219
|
+
:%ruby |-
|
220
|
+
```
|
221
|
+
|
222
|
+
Deprecated functions and old functions not starting with `nvim_` will be
|
223
|
+
hidden. The full list of API functions can be obtained by a call to
|
224
|
+
`get_api_info`.
|
225
|
+
|
226
|
+
```
|
227
|
+
pp $vim.get_api_info
|
228
|
+
~
|
229
|
+
~
|
230
|
+
:.ruby |-
|
231
|
+
```
|
232
|
+
|
233
|
+
See the script `examples/dump_api` for a more elaborated and colorized
|
234
|
+
output.
|
235
|
+
|
236
|
+
|
237
|
+
### Calculator
|
238
|
+
|
148
239
|
Further, a simple number/cash summing tool is included.
|
149
240
|
|
150
241
|
```
|
@@ -253,7 +344,7 @@ or ask the running Neovim for its server name.
|
|
253
344
|
echo v:servername
|
254
345
|
```
|
255
346
|
|
256
|
-
Then connect to it.
|
347
|
+
Then connect to it. This requires the [Intar](https://github.com/BertramScharpf/ruby-intar) gem.
|
257
348
|
|
258
349
|
```
|
259
350
|
$ intar -r neovim/remote
|
@@ -276,7 +367,7 @@ Put text into an X selection or a TMux register.
|
|
276
367
|
```vim
|
277
368
|
let g:ruby_require = "neovim/tools/copy"
|
278
369
|
'<,'>ruby xsel $lines
|
279
|
-
'<,'>ruby xsel! $
|
370
|
+
'<,'>ruby xsel! $lines
|
280
371
|
'<,'>ruby tmuxbuf $lines
|
281
372
|
```
|
282
373
|
|
data/examples/demo.rb
ADDED
@@ -0,0 +1,35 @@
|
|
1
|
+
#
|
2
|
+
# demo.rb -- Demo plugin
|
3
|
+
#
|
4
|
+
|
5
|
+
|
6
|
+
Neovim.plugin do |dsl|
|
7
|
+
|
8
|
+
dsl.command :SetLine, nargs: 1 do |client,(str)|
|
9
|
+
client.set_current_line str
|
10
|
+
end
|
11
|
+
|
12
|
+
dsl.command :Fail, nargs: 0 do |client|
|
13
|
+
raise "ouch!"
|
14
|
+
end
|
15
|
+
|
16
|
+
dsl.function :Sum, nargs: 2, sync: true do |client,x,y|
|
17
|
+
x + y
|
18
|
+
end
|
19
|
+
|
20
|
+
dsl.function :Fail do |client|
|
21
|
+
raise "ouch!"
|
22
|
+
end
|
23
|
+
|
24
|
+
dsl.function :Other, nargs: 2, range: true, eval: "strftime('%s')" do |client,(x,y),range,evaled|
|
25
|
+
r = "<<<#{x}---#{y}===#{range}---#{evaled}>>>"
|
26
|
+
client.buf_set_lines 0, 0, 0, false, [r.inspect]
|
27
|
+
r
|
28
|
+
end
|
29
|
+
|
30
|
+
dsl.autocmd :BufEnter, pattern: "*.rb" do |client|
|
31
|
+
client.command "echom 'Hello, Ruby!'"
|
32
|
+
end
|
33
|
+
|
34
|
+
end
|
35
|
+
|
@@ -0,0 +1,38 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
#
|
4
|
+
# demo_attach -- Start a Neovim session and attach to it
|
5
|
+
#
|
6
|
+
|
7
|
+
require "neovim/remote"
|
8
|
+
|
9
|
+
|
10
|
+
module Neovim
|
11
|
+
|
12
|
+
SOCKET = "/tmp/nvim-#$$.sock"
|
13
|
+
|
14
|
+
system *%W(tmux split-window -dv nvim --listen #{SOCKET})
|
15
|
+
|
16
|
+
Remote.start_client ConnectionUnix, SOCKET, timeout: 1 do |c|
|
17
|
+
c.command "e /etc/passwd"
|
18
|
+
c.command "/home"
|
19
|
+
b = c.get_current_buf
|
20
|
+
puts b.inspect
|
21
|
+
puts
|
22
|
+
sleep 1
|
23
|
+
puts b[1]
|
24
|
+
w = c.get_current_win
|
25
|
+
puts w.index
|
26
|
+
puts b[w.line]
|
27
|
+
c.command "bw"
|
28
|
+
sleep 1
|
29
|
+
e = c.evaluate "3*9"
|
30
|
+
puts e.inspect
|
31
|
+
sleep 1
|
32
|
+
c.command "q"
|
33
|
+
rescue Remote::Disconnected
|
34
|
+
puts "done."
|
35
|
+
end
|
36
|
+
|
37
|
+
end
|
38
|
+
|
data/examples/demo_intar
ADDED
@@ -0,0 +1,47 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
#
|
4
|
+
# demo_intar -- Start a Neovim session, attach to it and control it from an interactive Ruby
|
5
|
+
#
|
6
|
+
|
7
|
+
require "neovim/remote"
|
8
|
+
require "intar"
|
9
|
+
|
10
|
+
|
11
|
+
module Neovim
|
12
|
+
|
13
|
+
SOCKET = "/tmp/nvim-#$$.sock"
|
14
|
+
|
15
|
+
system *%W(tmux split-window -dv nvim --listen #{SOCKET})
|
16
|
+
|
17
|
+
Remote.start_client ConnectionUnix, SOCKET, timeout: 1 do |c|
|
18
|
+
c.command "set cuc cul"
|
19
|
+
c.set_option buftype: "nofile"
|
20
|
+
c.set_option :nu
|
21
|
+
b = c.get_current_buf
|
22
|
+
w = c.get_current_win
|
23
|
+
b[] = ["A".."Z", "a".."z", "0".."9"].map { |r| r.to_a }.flatten.map { |x| x*4 }
|
24
|
+
c.message "Hello from interactive Ruby!"
|
25
|
+
Intar.open do |i|
|
26
|
+
i.set_var :c, c
|
27
|
+
i.set_var :b, b
|
28
|
+
i.set_var :w, w
|
29
|
+
puts <<~'EOT'
|
30
|
+
# Example calls:
|
31
|
+
c.set_option_value "nu", false, {}
|
32
|
+
w.set_option :nu, :rnu
|
33
|
+
puts w.index
|
34
|
+
puts b[w.line]
|
35
|
+
b[w.line] += ["----"]
|
36
|
+
b.map! w.line do |x| x << "!" end
|
37
|
+
c.call_function "setreg", ["a", "hello\nbye", "l"]
|
38
|
+
EOT
|
39
|
+
i.run
|
40
|
+
end
|
41
|
+
c.command "qa!"
|
42
|
+
rescue Remote::Disconnected
|
43
|
+
puts "done."
|
44
|
+
end
|
45
|
+
|
46
|
+
end
|
47
|
+
|
@@ -0,0 +1,36 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
#
|
4
|
+
# demo_remote.rb -- Demo for plain handlers
|
5
|
+
#
|
6
|
+
|
7
|
+
require "neovim"
|
8
|
+
|
9
|
+
|
10
|
+
if $stdin.tty? then
|
11
|
+
puts <<~EOT
|
12
|
+
" How to run this from inside Neovim:
|
13
|
+
let chan = jobstart(['ruby','#$0'], { 'rpc': v:true })
|
14
|
+
call rpcrequest(chan, 'rb_add', 7)
|
15
|
+
call rpcrequest(chan, 'rb_raise')
|
16
|
+
call jobstop(chan)
|
17
|
+
EOT
|
18
|
+
exit 1
|
19
|
+
end
|
20
|
+
|
21
|
+
|
22
|
+
counter = 0
|
23
|
+
|
24
|
+
Neovim.start_remote do |dsl|
|
25
|
+
|
26
|
+
dsl.register_handler "rb_add" do |client,n|
|
27
|
+
counter += n
|
28
|
+
client.command "echo 'Counter value now is: '..#{counter}..'.'"
|
29
|
+
end
|
30
|
+
|
31
|
+
dsl.register_handler "rb_raise" do |client|
|
32
|
+
raise "Ouch!"
|
33
|
+
end
|
34
|
+
|
35
|
+
end
|
36
|
+
|
@@ -0,0 +1,47 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
#
|
4
|
+
# examples/demo_remote_inside_block.rb -- Demo for plain handlers
|
5
|
+
#
|
6
|
+
|
7
|
+
require "neovim"
|
8
|
+
|
9
|
+
|
10
|
+
if $stdin.tty? then
|
11
|
+
puts <<~EOT
|
12
|
+
" How to run this from inside Neovim:
|
13
|
+
let chan = jobstart(['ruby','#$0', 'counter.log', 100], { 'rpc': v:true })
|
14
|
+
echo rpcrequest(chan, 'rb_add', 7)
|
15
|
+
echo jobstop(chan)
|
16
|
+
EOT
|
17
|
+
exit 1
|
18
|
+
end
|
19
|
+
|
20
|
+
|
21
|
+
logname, counter = *$*
|
22
|
+
logname ||= "counter.log"
|
23
|
+
counter = counter.to_i
|
24
|
+
|
25
|
+
File.open logname, "w" do |log|
|
26
|
+
|
27
|
+
log.puts "I was called with: #{$*.inspect}"
|
28
|
+
log.flush
|
29
|
+
|
30
|
+
Neovim.start_remote do |dsl|
|
31
|
+
|
32
|
+
dsl.register_handler "rb_add" do |client,n|
|
33
|
+
counter += n
|
34
|
+
client.command "echo 'Counter value now is: '..#{counter}..'.'"
|
35
|
+
log.puts "Counter: #{counter}"
|
36
|
+
log.flush
|
37
|
+
nil
|
38
|
+
end
|
39
|
+
|
40
|
+
end
|
41
|
+
|
42
|
+
ensure
|
43
|
+
log.puts "Bye from counter at #{counter}."
|
44
|
+
log.flush
|
45
|
+
|
46
|
+
end
|
47
|
+
|
data/examples/demo_sub
ADDED
@@ -0,0 +1,30 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
#
|
4
|
+
# demo_sub -- Descend to a Neovim session with some text
|
5
|
+
#
|
6
|
+
|
7
|
+
require "neovim/host"
|
8
|
+
|
9
|
+
|
10
|
+
data = <<~EOT
|
11
|
+
Name: John Doe
|
12
|
+
Mail: jdoe@example.com
|
13
|
+
Password: verysecret
|
14
|
+
EOT
|
15
|
+
|
16
|
+
Neovim::Remote.run_sub do |dsl|
|
17
|
+
dsl.setup do |client|
|
18
|
+
d = data.split "\n"
|
19
|
+
client.put d, "l", false, false
|
20
|
+
client.command "autocmd BufUnload <buffer=%d> call rpcrequest(%d,'rb_yield_data',getline(1,'$'))" %
|
21
|
+
[ client.get_current_buf.number, client.channel_id]
|
22
|
+
end
|
23
|
+
dsl.register_handler "rb_yield_data" do |client,l|
|
24
|
+
data = l.join "\n"
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
puts $?.inspect
|
29
|
+
puts "data =", data
|
30
|
+
|
data/examples/dump_api
ADDED
@@ -0,0 +1,99 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
#
|
4
|
+
# dump_api -- Dump NeoVim's API
|
5
|
+
#
|
6
|
+
|
7
|
+
usage = <<~EOT
|
8
|
+
#$0 | nvim - +'set ft=yaml' '+$' # dump as YAML
|
9
|
+
#$0 -a | nvim - +'set ft=yaml' '+$' # dump by "--api-info" option
|
10
|
+
#$0 -j | nvim - +'set ft=json' '+$' # dump as JSON
|
11
|
+
|
12
|
+
Or just source it from Neovim:
|
13
|
+
|
14
|
+
:let g:ruby_api_info="yaml"
|
15
|
+
:rubyfile #$0
|
16
|
+
|
17
|
+
EOT
|
18
|
+
|
19
|
+
|
20
|
+
if $vim then # We're getting called from inside a Neovim.
|
21
|
+
|
22
|
+
a = $vim.get_api_info
|
23
|
+
t = ($vim.get_var "ruby_api_info") rescue "yaml"
|
24
|
+
a = case t
|
25
|
+
when "yaml" then require "yaml" ; a.to_yaml
|
26
|
+
when "json" then require "json" ; JSON.pretty_generate a
|
27
|
+
end
|
28
|
+
a = a.split $/
|
29
|
+
$vim.command "vnew"
|
30
|
+
$vim.set_options ft: t, buftype: "nofile"
|
31
|
+
$vim.put a, "l", false, false
|
32
|
+
|
33
|
+
|
34
|
+
else
|
35
|
+
|
36
|
+
$:.unshift "../lib"
|
37
|
+
require "neovim/remote"
|
38
|
+
|
39
|
+
|
40
|
+
include Neovim
|
41
|
+
|
42
|
+
|
43
|
+
class DumpApi
|
44
|
+
|
45
|
+
def get json: nil, alt: nil
|
46
|
+
if json then
|
47
|
+
as_json
|
48
|
+
else
|
49
|
+
if alt then
|
50
|
+
alternative_yaml
|
51
|
+
else
|
52
|
+
as_yaml
|
53
|
+
end
|
54
|
+
end
|
55
|
+
end
|
56
|
+
|
57
|
+
private
|
58
|
+
|
59
|
+
def api_info
|
60
|
+
Remote.open ConnectionChild, "-u", "NONE", "-n" do |s|
|
61
|
+
ch, ai = s.request :nvim_get_api_info
|
62
|
+
ai
|
63
|
+
end
|
64
|
+
end
|
65
|
+
|
66
|
+
def as_json
|
67
|
+
require "json"
|
68
|
+
JSON.pretty_generate api_info
|
69
|
+
end
|
70
|
+
|
71
|
+
def as_yaml
|
72
|
+
require "yaml"
|
73
|
+
api_info.to_yaml
|
74
|
+
end
|
75
|
+
|
76
|
+
def alternative_yaml
|
77
|
+
require "neovim/foreign/mplight"
|
78
|
+
require "yaml"
|
79
|
+
t = MPLight::Types.new
|
80
|
+
t.extend MPLight::Unpacker
|
81
|
+
IO.popen %w(nvim --api-info) do |r|
|
82
|
+
t.init_input r
|
83
|
+
return t.get.to_yaml
|
84
|
+
end
|
85
|
+
end
|
86
|
+
|
87
|
+
end
|
88
|
+
|
89
|
+
|
90
|
+
if $*.delete '-h' then
|
91
|
+
puts usage
|
92
|
+
exit
|
93
|
+
end
|
94
|
+
|
95
|
+
output = DumpApi.new.get json: ($*.delete '-j'), alt: ($*.delete '-a')
|
96
|
+
puts output
|
97
|
+
|
98
|
+
end
|
99
|
+
|
data/examples/passwords
ADDED
@@ -0,0 +1,78 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
#
|
4
|
+
# examples/passwords -- Manage a file containing your passwords
|
5
|
+
#
|
6
|
+
|
7
|
+
# (C) 2025 Bertram Scharpf <software@bertram-scharpf.de>
|
8
|
+
|
9
|
+
require "neovim/host"
|
10
|
+
|
11
|
+
|
12
|
+
class Passwords
|
13
|
+
|
14
|
+
PW_FILE = File.expand_path "~/.config/mypasswords.asc"
|
15
|
+
RECIPIENT = "jdoe@example.com"
|
16
|
+
|
17
|
+
def initialize debug: false
|
18
|
+
@debug = debug
|
19
|
+
end
|
20
|
+
|
21
|
+
def run
|
22
|
+
contents = get_contents.split $/
|
23
|
+
Neovim::Remote.run_sub do |pw_dsl|
|
24
|
+
pw_dsl.setup do |client|
|
25
|
+
client.set_option shadafile: "NONE"
|
26
|
+
client.set_option filetype: "dosini"
|
27
|
+
client.put contents, "l", true, false
|
28
|
+
client.command "1"
|
29
|
+
client.get_current_line.empty? and client.del_current_line
|
30
|
+
{
|
31
|
+
"Save" => "rb_save",
|
32
|
+
"Totp" => "rb_totp",
|
33
|
+
}.each { |cmd,fn|
|
34
|
+
client.command "command -buffer -nargs=0 %s call rpcrequest(%d,'%s')" % [ cmd, client.channel_id, fn]
|
35
|
+
}
|
36
|
+
end
|
37
|
+
pw_dsl.register_handler "rb_save" do |client|
|
38
|
+
File.rename PW_FILE, "#{PW_FILE}.bak" rescue nil
|
39
|
+
IO.popen %W(gpg -a -r #{RECIPIENT} --encrypt -o #{PW_FILE}), "w" do |gpg|
|
40
|
+
gpg.puts client.get_current_buf[1..]
|
41
|
+
end
|
42
|
+
File.chmod 0600, PW_FILE
|
43
|
+
end
|
44
|
+
pw_dsl.register_handler "rb_totp" do |client|
|
45
|
+
require "potp"
|
46
|
+
require "neovim/tools/copy"
|
47
|
+
p = client.call_function "expand", [ "<cword>"]
|
48
|
+
key = (POTP::TOTP.new p).now if p.notempty? and p.length % 4 == 0
|
49
|
+
client.echo [ [ key]], true, {}
|
50
|
+
xsel key
|
51
|
+
rescue
|
52
|
+
client.err_writeln "No OTP under cursor?"
|
53
|
+
rescue ScriptError
|
54
|
+
client.err_writeln $!.message
|
55
|
+
end
|
56
|
+
end
|
57
|
+
end
|
58
|
+
|
59
|
+
def get_contents
|
60
|
+
r = IO.popen %W(gpg -d #{PW_FILE}), "r" do |gpg| gpg.read end
|
61
|
+
r.notempty? or <<~EOT
|
62
|
+
# Move the cursor to the OTP keyword and give the command `:Totp`.
|
63
|
+
# The TOTP key will be displayed and further copied to the clipboard.
|
64
|
+
|
65
|
+
[account "dummy"]
|
66
|
+
name = John Doe
|
67
|
+
password = very$ecret
|
68
|
+
optauth = GYS5L3N3E4AAYNMN562LW76TMWHQBJ4A
|
69
|
+
|
70
|
+
# As soon as you have set the `RECIPIENT` constant in the executable,
|
71
|
+
# you may save this file calling the command `:Save`.
|
72
|
+
EOT
|
73
|
+
end
|
74
|
+
|
75
|
+
new.run
|
76
|
+
|
77
|
+
end
|
78
|
+
|
data/lib/neovim/client.rb
CHANGED
@@ -25,7 +25,7 @@ module Neovim
|
|
25
25
|
def initialize comm, channel_id
|
26
26
|
@comm, @channel_id = comm, channel_id
|
27
27
|
@functions = {}
|
28
|
-
@objfuncs =
|
28
|
+
@objfuncs = {}
|
29
29
|
end
|
30
30
|
|
31
31
|
def inspect
|
@@ -36,10 +36,16 @@ module Neovim
|
|
36
36
|
list.each { |fn|
|
37
37
|
next if fn[ "deprecated_since"] && self.class.strict
|
38
38
|
n = fn[ "name"]
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
39
|
+
if (b = n.starts_with? "nvim_") then
|
40
|
+
@functions[ n[ b...].to_sym] = n
|
41
|
+
end
|
42
|
+
prefixes.each { |t,p|
|
43
|
+
if (b = n.starts_with? p) then
|
44
|
+
@objfuncs[ t] ||= {}
|
45
|
+
@objfuncs[ t][ n[ b...].to_sym] = n
|
46
|
+
break
|
47
|
+
end
|
48
|
+
}
|
43
49
|
}
|
44
50
|
end
|
45
51
|
|
@@ -58,7 +64,6 @@ module Neovim
|
|
58
64
|
end
|
59
65
|
|
60
66
|
|
61
|
-
|
62
67
|
def method_missing sym, *args
|
63
68
|
call_api sym, *args
|
64
69
|
rescue UnknownApiFunction
|
@@ -78,17 +83,24 @@ module Neovim
|
|
78
83
|
s
|
79
84
|
end
|
80
85
|
|
86
|
+
def functions
|
87
|
+
@functions.keys
|
88
|
+
end
|
89
|
+
|
81
90
|
|
82
91
|
def has_obj_function? obj, name
|
83
92
|
@objfuncs[ obj.type][ name.to_sym].to_bool
|
84
93
|
end
|
85
94
|
|
95
|
+
def obj_classes
|
96
|
+
RemoteObject.subclasses.select { |c| @objfuncs[ c.type] rescue nil }
|
97
|
+
end
|
98
|
+
|
86
99
|
def obj_functions obj
|
87
100
|
@objfuncs[ obj.type].keys
|
88
101
|
end
|
89
102
|
|
90
103
|
|
91
|
-
|
92
104
|
def message str
|
93
105
|
call_api :out_write, str
|
94
106
|
str.end_with? $/ or call_api :out_write, $/
|
@@ -100,6 +112,7 @@ module Neovim
|
|
100
112
|
|
101
113
|
def command arg ; call_api :command, arg ; end
|
102
114
|
|
115
|
+
# Be aware that #eval was a private instance method from module Kernel.
|
103
116
|
def evaluate expr ; call_api :eval, expr ; end
|
104
117
|
|
105
118
|
end
|
data/lib/neovim/connection.rb
CHANGED
@@ -40,7 +40,7 @@ module Neovim
|
|
40
40
|
prefixes = {}
|
41
41
|
api_info[ "types"].each do |type,info|
|
42
42
|
type = type.to_sym
|
43
|
-
prefixes[ type] =
|
43
|
+
prefixes[ type] = info[ "prefix"]
|
44
44
|
register_type type, info[ "id"]
|
45
45
|
end
|
46
46
|
@client.add_functions api_info[ "functions"], prefixes
|
@@ -69,10 +69,19 @@ module Neovim
|
|
69
69
|
|
70
70
|
class ConnectionTcp < Connection
|
71
71
|
class <<self
|
72
|
-
def open_files host, port
|
72
|
+
def open_files host, port, timeout: nil
|
73
|
+
due = Time.now + timeout if timeout
|
73
74
|
require "socket"
|
74
|
-
|
75
|
-
|
75
|
+
begin
|
76
|
+
TCPSocket.open host, port do |socket|
|
77
|
+
due = nil
|
78
|
+
yield (new socket, socket)
|
79
|
+
end
|
80
|
+
rescue Errno::ECONNREFUSED
|
81
|
+
if due then
|
82
|
+
sleep 0.1
|
83
|
+
retry
|
84
|
+
end
|
76
85
|
end
|
77
86
|
end
|
78
87
|
end
|
@@ -80,10 +89,19 @@ module Neovim
|
|
80
89
|
|
81
90
|
class ConnectionUnix < Connection
|
82
91
|
class <<self
|
83
|
-
def open_files path
|
92
|
+
def open_files path, timeout: nil
|
93
|
+
due = Time.now + timeout if timeout
|
84
94
|
require "socket"
|
85
|
-
|
86
|
-
|
95
|
+
begin
|
96
|
+
UNIXSocket.open path do |socket|
|
97
|
+
due = nil
|
98
|
+
yield (new socket, socket)
|
99
|
+
end
|
100
|
+
rescue Errno::ENOENT
|
101
|
+
if due then
|
102
|
+
sleep 0.1
|
103
|
+
retry
|
104
|
+
end
|
87
105
|
end
|
88
106
|
end
|
89
107
|
end
|
@@ -38,6 +38,10 @@ rescue LoadError
|
|
38
38
|
self
|
39
39
|
end
|
40
40
|
end
|
41
|
+
def starts_with? oth ; o = oth.to_str ; o.length if start_with? o ; end
|
42
|
+
def ends_with? oth ; o = oth.to_str ; length - o.length if end_with? o ; end
|
43
|
+
alias starts_with starts_with?
|
44
|
+
alias ends_with ends_with?
|
41
45
|
end
|
42
46
|
end
|
43
47
|
|
data/lib/neovim/handler.rb
CHANGED
data/lib/neovim/host.rb
CHANGED
@@ -8,6 +8,32 @@ require "neovim/handler"
|
|
8
8
|
|
9
9
|
module Neovim
|
10
10
|
|
11
|
+
class Remote
|
12
|
+
|
13
|
+
class <<self
|
14
|
+
|
15
|
+
def run_remote *args, **kwargs, &block
|
16
|
+
plugins = { remote: (DslRemote.open &block), }
|
17
|
+
start plugins, *args, **kwargs do |i|
|
18
|
+
i.start
|
19
|
+
i.run
|
20
|
+
end
|
21
|
+
rescue Remote::Disconnected
|
22
|
+
end
|
23
|
+
|
24
|
+
def run_sub socket: nil, timeout: nil, &block
|
25
|
+
socket ||= "/tmp/nvim-sub-#$$.sock"
|
26
|
+
f = fork { exec *%w(nvim --listen), socket }
|
27
|
+
Remote.run_remote ConnectionUnix, socket, timeout: timeout||1, &block
|
28
|
+
ensure
|
29
|
+
Process.waitpid f
|
30
|
+
end
|
31
|
+
|
32
|
+
end
|
33
|
+
|
34
|
+
end
|
35
|
+
|
36
|
+
|
11
37
|
class Provider < Remote
|
12
38
|
|
13
39
|
class <<self
|
@@ -21,6 +47,7 @@ module Neovim
|
|
21
47
|
def run plugins
|
22
48
|
$stdin.tty? and raise "This program expects to be called by Neovim. It can't run interactively."
|
23
49
|
start plugins do |h|
|
50
|
+
log :info, "Starting event loop."
|
24
51
|
h.run
|
25
52
|
nil
|
26
53
|
rescue Remote::Disconnected
|
@@ -28,8 +55,13 @@ module Neovim
|
|
28
55
|
nil
|
29
56
|
rescue SignalException
|
30
57
|
n = $!.signm.notempty? || $!.class.to_s
|
31
|
-
|
32
|
-
|
58
|
+
if n =~ /\A(?:SIG)?TERM\z/ then
|
59
|
+
log :info, "Exiting after terminate signal."
|
60
|
+
nil
|
61
|
+
else
|
62
|
+
log :fatal, "Signal was caught: #{n}"
|
63
|
+
1
|
64
|
+
end
|
33
65
|
rescue Exception
|
34
66
|
log_exception :fatal
|
35
67
|
2
|
@@ -47,7 +79,6 @@ module Neovim
|
|
47
79
|
@plugins[ :base] = DslPlain.open do |dsl|
|
48
80
|
dsl.plain "poll" do
|
49
81
|
start
|
50
|
-
@plugins.each_value { |p| p.setup @conn.client }
|
51
82
|
"ok"
|
52
83
|
end
|
53
84
|
dsl.plain "specs", nargs: 1 do |source|
|
data/lib/neovim/info.rb
CHANGED
@@ -1,10 +1,10 @@
|
|
1
1
|
require "neovim/meta.rb"
|
2
2
|
Neovim::INFO = Neovim::Meta.new "nvim",
|
3
|
-
version: "1.
|
3
|
+
version: "1.5.1",
|
4
4
|
license: "BSD-2-Clause+",
|
5
5
|
authors: ["Bertram Scharpf"],
|
6
6
|
email: "software@bertram-scharpf.de",
|
7
7
|
summary: "Yet another Ruby client for Neovim",
|
8
8
|
description: "A simple Ruby client for Neovim.\nClean code, minimal dependecies, no frills, no wokeness.",
|
9
9
|
homepage: "https://github.com/BertramScharpf/ruby-nvim",
|
10
|
-
commit: "
|
10
|
+
commit: "3508371"
|
data/lib/neovim/logging.rb
CHANGED
@@ -234,8 +234,8 @@ module Neovim
|
|
234
234
|
**kwargs
|
235
235
|
end
|
236
236
|
|
237
|
-
def log_exception level
|
238
|
-
Logging.put level, "Exception: #$!",
|
237
|
+
def log_exception level = nil
|
238
|
+
Logging.put level||:error, "Exception: #$!",
|
239
239
|
sender: self, caller: (caller 1, 1).first,
|
240
240
|
exception: $!.class
|
241
241
|
$@.each { |b|
|
data/lib/neovim/remote.rb
CHANGED
@@ -120,20 +120,20 @@ module Neovim
|
|
120
120
|
end
|
121
121
|
end
|
122
122
|
|
123
|
-
def start plugins, *args
|
123
|
+
def start plugins, *args, **kwargs
|
124
124
|
open_logfile do
|
125
|
-
log :
|
126
|
-
open_conn *args do |conn|
|
125
|
+
log :debug1, "Starting", args: $*
|
126
|
+
open_conn *args, **kwargs do |conn|
|
127
127
|
i = new plugins, conn
|
128
128
|
yield i
|
129
129
|
end
|
130
130
|
ensure
|
131
|
-
log :
|
131
|
+
log :debug1, "Leaving"
|
132
132
|
end
|
133
133
|
end
|
134
134
|
|
135
|
-
def start_client *args
|
136
|
-
start nil, *args do |i|
|
135
|
+
def start_client *args, **kwargs
|
136
|
+
start nil, *args, **kwargs do |i|
|
137
137
|
yield i.start
|
138
138
|
end
|
139
139
|
end
|
@@ -154,7 +154,7 @@ module Neovim
|
|
154
154
|
l.map! { |p| p.type }
|
155
155
|
l.uniq!
|
156
156
|
name = l.join "-"
|
157
|
-
log :
|
157
|
+
log :debug1, "Client Name", name: name
|
158
158
|
"ruby-#{name}-host"
|
159
159
|
else
|
160
160
|
"ruby-client"
|
@@ -175,6 +175,7 @@ module Neovim
|
|
175
175
|
|
176
176
|
def start
|
177
177
|
@conn.start self
|
178
|
+
@plugins.each_value { |p| p.setup @conn.client }
|
178
179
|
@conn.client
|
179
180
|
end
|
180
181
|
|
@@ -209,7 +210,7 @@ module Neovim
|
|
209
210
|
if @conn.client or not h.needs_client? then
|
210
211
|
p.call
|
211
212
|
else
|
212
|
-
log :
|
213
|
+
log :debug1, "Deferred handler for", name: message.method_name
|
213
214
|
@deferred ||= []
|
214
215
|
@deferred.push p
|
215
216
|
end
|
@@ -265,7 +266,7 @@ module Neovim
|
|
265
266
|
@plugins.each_value do |plugin|
|
266
267
|
h = plugin.get_handler name
|
267
268
|
if h then
|
268
|
-
log :
|
269
|
+
log :debug1, "Found handler", name: name
|
269
270
|
return h
|
270
271
|
end
|
271
272
|
end
|
data/lib/neovim/remote_object.rb
CHANGED
data/lib/neovim/ruby_provider.rb
CHANGED
@@ -19,20 +19,19 @@ end
|
|
19
19
|
# The VIM module as documented in ":h ruby".
|
20
20
|
module Vim
|
21
21
|
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
end
|
22
|
+
Buffer = ::Neovim::Buffer
|
23
|
+
class <<Buffer
|
24
|
+
def current ; $vim.get_current_buf ; end
|
25
|
+
def count ; $vim.list_bufs.size ; end
|
26
|
+
def [] i ; $vim.list_bufs[ i] ; end
|
28
27
|
end
|
29
28
|
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
29
|
+
Window = ::Neovim::Window
|
30
|
+
class <<Window
|
31
|
+
def current ; $vim.get_current_win ; end
|
32
|
+
def count ; $vim.get_current_tabpage.list_wins.size ; end
|
33
|
+
def [] i ; $vim.get_current_tabpage.list_wins[ i] ; end
|
34
|
+
self
|
36
35
|
end
|
37
36
|
|
38
37
|
class <<self
|
@@ -163,13 +162,14 @@ module Neovim
|
|
163
162
|
# This is called by the +:ruby+ command.
|
164
163
|
dsl.rpc :ruby_execute do |client,code,fst,lst|
|
165
164
|
code.rstrip!
|
166
|
-
if
|
165
|
+
if code =~ /\A\|?(-)?\z/ then # | is a workaround because Neovim doesn't allow empty code (the ultimate Quine).
|
166
|
+
no_out = $1
|
167
167
|
set_global_client client do
|
168
168
|
client.command "#{lst}"
|
169
169
|
code = (get_lines client, fst..lst).join $/
|
170
170
|
WriteBuf.redirect client do
|
171
171
|
r = script_binding.eval code, "ruby_run"
|
172
|
-
unless r.nil? then
|
172
|
+
unless no_out or r.nil? then
|
173
173
|
script_binding.local_variable_set :_, r
|
174
174
|
puts "#=> #{r.inspect}"
|
175
175
|
end
|
@@ -16,11 +16,16 @@ module Neovim
|
|
16
16
|
case r
|
17
17
|
when BigDecimal then
|
18
18
|
r = r.to_s "F"
|
19
|
-
|
20
|
-
(@sep||$1) + ($2.to_s.ljust @decs, "0")
|
19
|
+
if @decs.nonzero? then
|
20
|
+
r.sub! /(\.)(\d+)\z/ do (@sep||$1) + ($2.to_s.ljust @decs, "0") end
|
21
|
+
else
|
22
|
+
r.slice! /\.0+\z/
|
21
23
|
end
|
22
24
|
when Integer then
|
23
25
|
r = r.to_s
|
26
|
+
if @decs.nonzero? then
|
27
|
+
r << (@sep||".") << "0"*@decs
|
28
|
+
end
|
24
29
|
end
|
25
30
|
r
|
26
31
|
end
|
@@ -31,11 +36,13 @@ module Neovim
|
|
31
36
|
|
32
37
|
def decs= d ; @decs = Integer d ; end
|
33
38
|
|
34
|
-
def dot! ; @sep =
|
39
|
+
def dot! ; @sep = "." ; end
|
35
40
|
def dot? ; @sep == "." ; end
|
36
|
-
def comma! ; @sep =
|
41
|
+
def comma! ; @sep = "," ; end
|
37
42
|
def comma? ; @sep == "," ; end
|
38
|
-
def
|
43
|
+
def colon! ; @sep = ":" ; end
|
44
|
+
def colon? ; @sep == ":" ; end
|
45
|
+
def auto! ; @sep = nil ; end
|
39
46
|
|
40
47
|
def add line
|
41
48
|
line = line.chomp
|
@@ -43,9 +50,11 @@ module Neovim
|
|
43
50
|
if $& =~ /!(\w+)/ then
|
44
51
|
case $1
|
45
52
|
when "c", "comma", "k", "komma" then comma!
|
53
|
+
when "l", "colon" then colon!
|
46
54
|
when "d", "dot", "p", "point" then dot!
|
47
55
|
when "a", "auto" then auto!
|
48
|
-
when /\A\d+\z/ then @decs =
|
56
|
+
when /\A\d+\z/ then @decs = $&.to_i
|
57
|
+
when "all", "full", "places" then @decs = nil
|
49
58
|
end
|
50
59
|
end
|
51
60
|
line.slice! /^.*:/
|
data/lib/neovim.rb
CHANGED
data/nvim.gemspec
ADDED
@@ -0,0 +1,31 @@
|
|
1
|
+
#
|
2
|
+
# nvim.gemspec -- Gem specification
|
3
|
+
#
|
4
|
+
|
5
|
+
system *%w(rake infofile)
|
6
|
+
|
7
|
+
$:.unshift "./lib"
|
8
|
+
require "neovim/info"
|
9
|
+
|
10
|
+
|
11
|
+
Gem::Specification.new do |spec|
|
12
|
+
Neovim::INFO.mk_gemspec spec
|
13
|
+
spec.required_ruby_version = Gem::Requirement.new ">= 3.1.0"
|
14
|
+
|
15
|
+
spec.files = Dir[ "lib/**/*.rb"] + Dir[ "bin/*"]
|
16
|
+
|
17
|
+
spec.require_paths = %w(lib)
|
18
|
+
spec.bindir = "bin"
|
19
|
+
spec.executables = %w(neovim-ruby-host)
|
20
|
+
|
21
|
+
spec.extra_rdoc_files = %w(INFO.yaml LICENSE README.md)
|
22
|
+
spec.extra_rdoc_files += %w(Rakefile nvim.gemspec)
|
23
|
+
spec.extra_rdoc_files += Dir[ "examples/*"]
|
24
|
+
|
25
|
+
if false then
|
26
|
+
spec.add_dependency "supplement", "~> 2.18"
|
27
|
+
spec.add_dependency "mplight", "~> 1.0"
|
28
|
+
end
|
29
|
+
|
30
|
+
end
|
31
|
+
|
metadata
CHANGED
@@ -1,28 +1,46 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: nvim
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.
|
4
|
+
version: 1.5.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Bertram Scharpf
|
8
|
-
autorequire:
|
9
8
|
bindir: bin
|
10
9
|
cert_chain: []
|
11
|
-
date:
|
10
|
+
date: 2025-01-14 00:00:00.000000000 Z
|
12
11
|
dependencies: []
|
13
|
-
description:
|
14
12
|
email: software@bertram-scharpf.de
|
15
13
|
executables:
|
16
14
|
- neovim-ruby-host
|
17
15
|
extensions: []
|
18
|
-
extra_rdoc_files:
|
16
|
+
extra_rdoc_files:
|
17
|
+
- INFO.yaml
|
18
|
+
- LICENSE
|
19
|
+
- README.md
|
20
|
+
- Rakefile
|
21
|
+
- nvim.gemspec
|
22
|
+
- examples/demo.rb
|
23
|
+
- examples/demo_attach
|
24
|
+
- examples/demo_intar
|
25
|
+
- examples/demo_remote.rb
|
26
|
+
- examples/demo_remote_inside_block.rb
|
27
|
+
- examples/demo_sub
|
28
|
+
- examples/dump_api
|
29
|
+
- examples/passwords
|
19
30
|
files:
|
20
31
|
- INFO.yaml
|
21
32
|
- LICENSE
|
22
33
|
- README.md
|
23
34
|
- Rakefile
|
24
|
-
- TODO
|
25
35
|
- bin/neovim-ruby-host
|
36
|
+
- examples/demo.rb
|
37
|
+
- examples/demo_attach
|
38
|
+
- examples/demo_intar
|
39
|
+
- examples/demo_remote.rb
|
40
|
+
- examples/demo_remote_inside_block.rb
|
41
|
+
- examples/demo_sub
|
42
|
+
- examples/dump_api
|
43
|
+
- examples/passwords
|
26
44
|
- lib/neovim.rb
|
27
45
|
- lib/neovim/client.rb
|
28
46
|
- lib/neovim/connection.rb
|
@@ -43,11 +61,11 @@ files:
|
|
43
61
|
- lib/neovim/tools/calculator.rb
|
44
62
|
- lib/neovim/tools/copy.rb
|
45
63
|
- lib/neovim/vimscript_provider.rb
|
64
|
+
- nvim.gemspec
|
46
65
|
homepage: https://github.com/BertramScharpf/ruby-nvim
|
47
66
|
licenses:
|
48
67
|
- BSD-2-Clause+
|
49
68
|
metadata: {}
|
50
|
-
post_install_message:
|
51
69
|
rdoc_options: []
|
52
70
|
require_paths:
|
53
71
|
- lib
|
@@ -55,15 +73,14 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
55
73
|
requirements:
|
56
74
|
- - ">="
|
57
75
|
- !ruby/object:Gem::Version
|
58
|
-
version: 3.
|
76
|
+
version: 3.1.0
|
59
77
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
60
78
|
requirements:
|
61
79
|
- - ">="
|
62
80
|
- !ruby/object:Gem::Version
|
63
81
|
version: '0'
|
64
82
|
requirements: []
|
65
|
-
rubygems_version: 3.
|
66
|
-
signing_key:
|
83
|
+
rubygems_version: 3.6.2
|
67
84
|
specification_version: 4
|
68
85
|
summary: Yet another Ruby client for Neovim
|
69
86
|
test_files: []
|