vimrunner 0.0.2 → 0.0.3
Sign up to get free protection for your applications and to get access to all the features.
- data/README.md +53 -11
- data/bin/vimrunner +1 -1
- data/lib/vimrunner.rb +16 -1
- data/lib/vimrunner/client.rb +109 -0
- data/lib/vimrunner/errors.rb +6 -0
- data/lib/vimrunner/server.rb +151 -0
- data/lib/vimrunner/shell.rb +3 -11
- data/lib/vimrunner/version.rb +1 -1
- metadata +14 -13
- data/lib/vimrunner/runner.rb +0 -158
data/README.md
CHANGED
@@ -2,8 +2,60 @@ Using Vim's client/server functionality, this library exposes a way to spawn a
|
|
2
2
|
Vim instance and control it programatically. Apart from being a fun party
|
3
3
|
trick, this could be used to do integration testing on vimscript.
|
4
4
|
|
5
|
+
This is still fairly experimental, so use with caution. Any issue reports or
|
6
|
+
contributions are very welcome on the
|
7
|
+
[github issue tracker](https://github.com/AndrewRadev/Vimrunner/issues)
|
8
|
+
|
9
|
+
## Usage
|
10
|
+
|
11
|
+
There are two objects that can be used to control Vim, a "server" and a
|
12
|
+
"client". The server takes care of spawning a server vim instance that will be
|
13
|
+
controlled, and the client is its interface.
|
14
|
+
|
15
|
+
A server can be started in two ways:
|
16
|
+
|
17
|
+
- `Vimrunner::Server.start`: Starts a terminal instance. Since it's
|
18
|
+
"invisible", it's nice for use in automated tests. If it's impossible to
|
19
|
+
start a terminal instance due to missing requirements for the `vim` binary
|
20
|
+
(see "Requirements" below), a GUI instance will be started.
|
21
|
+
- `Vimrunner::Server.start(:gui => true)`: Starts a GUI instance of Vim. On
|
22
|
+
Linux, it'll be a `gvim`, on Mac it defaults to `mvim`.
|
23
|
+
|
24
|
+
Both methods return a `Server` instance. For a more comprehensive list of
|
25
|
+
options you can start the server with, check out
|
26
|
+
[the docs](http://rubydoc.info/gems/vimrunner/Vimrunner/Server).
|
27
|
+
|
28
|
+
To be able to send commands to the server, you need a client that knows some
|
29
|
+
details about it:
|
30
|
+
|
31
|
+
``` ruby
|
32
|
+
server = Vimrunner::Server.start
|
33
|
+
|
34
|
+
client = Vimrunner::Client.new(server)
|
35
|
+
# or,
|
36
|
+
client = server.new_client
|
37
|
+
```
|
38
|
+
|
39
|
+
There are also two convenience methods that start a server and return a
|
40
|
+
connected client -- `Vimrunner.start_vim` and `Vimrunner.start_gui_vim`.
|
41
|
+
|
42
|
+
For a full list of methods you can invoke on the remote vim instance, check out
|
43
|
+
the methods on the `Client` class in
|
44
|
+
[the docs](http://rubydoc.info/gems/vimrunner/Vimrunner/Client).
|
45
|
+
|
46
|
+
## Requirements
|
47
|
+
|
48
|
+
Vim needs to be compiled with `+clientserver`. This should be available with
|
49
|
+
the `normal`, `big` and `huge` featuresets. The client/server functionality
|
50
|
+
(regrettably) needs a running X server to function, even for a terminal vim.
|
51
|
+
This means that if you're using it for automated tests on a remote server,
|
52
|
+
you'll probably need to start it with xvfb.
|
53
|
+
|
54
|
+
## Experimenting
|
55
|
+
|
5
56
|
The `vimrunner` executable opens up an irb session with `$vim` set to a running
|
6
|
-
`gvim`
|
57
|
+
`gvim` (or `mvim`) client. You can use this for interactive experimentation. A
|
58
|
+
few things you can try:
|
7
59
|
|
8
60
|
``` ruby
|
9
61
|
$vim.edit 'some_file_name' # edit a file
|
@@ -12,13 +64,3 @@ $vim.normal 'T,' # go back to the nearest comma
|
|
12
64
|
$vim.type 'a<cr>' # append a newline after the comma
|
13
65
|
$vim.write # write file to disk
|
14
66
|
```
|
15
|
-
|
16
|
-
For more examples of what you can do, you could take a look at the specs, they
|
17
|
-
should be fairly readable.
|
18
|
-
|
19
|
-
Note that this should work on a Linux box, but probably won't on a Mac. I'm
|
20
|
-
assuming you'd need to change the binary to `mvim` at the very least.
|
21
|
-
|
22
|
-
This is still fairly experimental, so use with caution. Any issue reports or
|
23
|
-
contributions are very welcome on the
|
24
|
-
[github issue tracker](https://github.com/AndrewRadev/Vimrunner/issues)
|
data/bin/vimrunner
CHANGED
data/lib/vimrunner.rb
CHANGED
@@ -1 +1,16 @@
|
|
1
|
-
require 'vimrunner/
|
1
|
+
require 'vimrunner/client'
|
2
|
+
require 'vimrunner/server'
|
3
|
+
|
4
|
+
module Vimrunner
|
5
|
+
# Starts a new Server with a terminal vim instance and returns a client,
|
6
|
+
# connected to it.
|
7
|
+
def self.start_vim
|
8
|
+
Client.new(Server.start)
|
9
|
+
end
|
10
|
+
|
11
|
+
# Starts a new Server with a GUI vim instance and returns a client, connected
|
12
|
+
# to it.
|
13
|
+
def self.start_gui_vim
|
14
|
+
Client.new(Server.start(:gui => true))
|
15
|
+
end
|
16
|
+
end
|
@@ -0,0 +1,109 @@
|
|
1
|
+
require 'vimrunner/shell'
|
2
|
+
|
3
|
+
module Vimrunner
|
4
|
+
|
5
|
+
# A Client is simply a proxy to a Vim server. It's initialized with a Server
|
6
|
+
# instance and sends commands, keys and signals to it.
|
7
|
+
class Client
|
8
|
+
def initialize(server)
|
9
|
+
@server = server
|
10
|
+
end
|
11
|
+
|
12
|
+
# Adds a plugin to Vim's runtime. Initially, Vim is started without
|
13
|
+
# sourcing any plugins to ensure a clean state. This method can be used to
|
14
|
+
# populate the instance's environment.
|
15
|
+
#
|
16
|
+
# dir - The base directory of the plugin, the one that contains
|
17
|
+
# its autoload, plugin, ftplugin, etc. directories.
|
18
|
+
# entry_script - The Vim script that's runtime'd to initialize the plugin.
|
19
|
+
# Optional.
|
20
|
+
#
|
21
|
+
# Example:
|
22
|
+
#
|
23
|
+
# vim.add_plugin 'rails', 'plugin/rails.vim'
|
24
|
+
#
|
25
|
+
def add_plugin(dir, entry_script = nil)
|
26
|
+
command("set runtimepath+=#{dir}")
|
27
|
+
command("runtime #{entry_script}") if entry_script
|
28
|
+
end
|
29
|
+
|
30
|
+
# Invokes one of the basic actions the Vim server supports, sending a key
|
31
|
+
# sequence. The keys are sent as-is, so it'd probably be better to use the
|
32
|
+
# wrapper methods, #normal, #insert and so on.
|
33
|
+
def type(keys)
|
34
|
+
invoke_vim '--remote-send', keys
|
35
|
+
end
|
36
|
+
|
37
|
+
# Executes the given command in the Vim instance and returns its output,
|
38
|
+
# stripping all surrounding whitespace.
|
39
|
+
def command(vim_command)
|
40
|
+
normal
|
41
|
+
|
42
|
+
expression = "VimrunnerEvaluateCommandOutput('#{vim_command.to_s}')"
|
43
|
+
|
44
|
+
invoke_vim('--remote-expr', expression).strip.tap do |output|
|
45
|
+
raise InvalidCommandError if output =~ /^Vim:E\d+:/
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
49
|
+
# Starts a search in Vim for the given text. The result is that the cursor
|
50
|
+
# is positioned on its first occurrence.
|
51
|
+
def search(text)
|
52
|
+
normal
|
53
|
+
type "/#{text}<cr>"
|
54
|
+
end
|
55
|
+
|
56
|
+
# Sets a setting in Vim. If +value+ is nil, the setting is considered to be
|
57
|
+
# a boolean.
|
58
|
+
#
|
59
|
+
# Examples:
|
60
|
+
#
|
61
|
+
# vim.set 'expandtab' # invokes ":set expandtab"
|
62
|
+
# vim.set 'tabstop', 3 # invokes ":set tabstop=3"
|
63
|
+
#
|
64
|
+
def set(setting, value = nil)
|
65
|
+
if value
|
66
|
+
command "set #{setting}=#{value}"
|
67
|
+
else
|
68
|
+
command "set #{setting}"
|
69
|
+
end
|
70
|
+
end
|
71
|
+
|
72
|
+
# Edits the file +filename+ with Vim.
|
73
|
+
#
|
74
|
+
# Note that this doesn't use the '--remote' Vim flag, it simply types in
|
75
|
+
# the command manually. This is necessary to avoid the Vim instance getting
|
76
|
+
# focus.
|
77
|
+
def edit(filename)
|
78
|
+
command "edit #{filename}"
|
79
|
+
end
|
80
|
+
|
81
|
+
# Writes the file being edited to disk. Note that you probably want to set
|
82
|
+
# the file's name first by using Runner#edit.
|
83
|
+
def write
|
84
|
+
command :write
|
85
|
+
end
|
86
|
+
|
87
|
+
# Switches Vim to insert mode and types in the given text.
|
88
|
+
def insert(text = '')
|
89
|
+
normal "i#{text}"
|
90
|
+
end
|
91
|
+
|
92
|
+
# Switches Vim to normal mode and types in the given keys.
|
93
|
+
def normal(keys = '')
|
94
|
+
type "<c-\\><c-n>#{keys}"
|
95
|
+
end
|
96
|
+
|
97
|
+
# Kills the server it's connected to.
|
98
|
+
def kill
|
99
|
+
@server.kill
|
100
|
+
end
|
101
|
+
|
102
|
+
private
|
103
|
+
|
104
|
+
def invoke_vim(*args)
|
105
|
+
args = [@server.vim_path, '--servername', @server.name, *args]
|
106
|
+
Shell.run *args
|
107
|
+
end
|
108
|
+
end
|
109
|
+
end
|
data/lib/vimrunner/errors.rb
CHANGED
@@ -0,0 +1,151 @@
|
|
1
|
+
require 'timeout'
|
2
|
+
require 'rbconfig'
|
3
|
+
require 'pty'
|
4
|
+
|
5
|
+
require 'vimrunner/errors'
|
6
|
+
require 'vimrunner/shell'
|
7
|
+
require 'vimrunner/client'
|
8
|
+
|
9
|
+
module Vimrunner
|
10
|
+
|
11
|
+
# The Server is a wrapper around the Vim server process that is controlled by
|
12
|
+
# clients. It will attempt to start the most appropriate Vim binary available
|
13
|
+
# on the system, though there are some options that can control this
|
14
|
+
# behaviour. See #initialize for more details.
|
15
|
+
class Server
|
16
|
+
class << self
|
17
|
+
|
18
|
+
# A convenience method that initializes a new server and starts it.
|
19
|
+
def start(options = {})
|
20
|
+
server = new(options)
|
21
|
+
server.start
|
22
|
+
end
|
23
|
+
|
24
|
+
# A convenience method that returns a new Client instance, connected to
|
25
|
+
# the server.
|
26
|
+
def new_client
|
27
|
+
Client.new(self)
|
28
|
+
end
|
29
|
+
|
30
|
+
# Retrieve a list of names of currently running Vim servers.
|
31
|
+
def list
|
32
|
+
%x[#{vim_path} --serverlist].strip.split "\n"
|
33
|
+
end
|
34
|
+
|
35
|
+
# The default path to use when starting a server with a terminal Vim. If
|
36
|
+
# the "vim" executable is not compiled with clientserver capabilities,
|
37
|
+
# the GUI version is started instead.
|
38
|
+
def vim_path
|
39
|
+
if clientserver_enabled? 'vim'
|
40
|
+
'vim'
|
41
|
+
else
|
42
|
+
gui_vim_path
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
# The default path to use when starting a server with the GUI version of
|
47
|
+
# Vim. Defaults to "mvim" on a mac and "gvim" on linux.
|
48
|
+
def gui_vim_path
|
49
|
+
if mac?
|
50
|
+
'mvim'
|
51
|
+
else
|
52
|
+
'gvim'
|
53
|
+
end
|
54
|
+
end
|
55
|
+
|
56
|
+
# The path to a vimrc file containing some required vimscript. The server
|
57
|
+
# is started with no settings or a vimrc, apart from this one.
|
58
|
+
def vimrc_path
|
59
|
+
File.join(File.expand_path('../../..', __FILE__), 'vim', 'vimrc')
|
60
|
+
end
|
61
|
+
|
62
|
+
# Returns true if the current operating system is Mac OS X.
|
63
|
+
def mac?
|
64
|
+
host_os =~ /darwin/
|
65
|
+
end
|
66
|
+
|
67
|
+
# Returns true if the given Vim binary is compiled with support for the
|
68
|
+
# client/server functionality.
|
69
|
+
def clientserver_enabled?(vim_path)
|
70
|
+
vim_version = %x[#{vim_path} --version]
|
71
|
+
vim_version.include? '+clientserver' and vim_version.include? '+xterm_clipboard'
|
72
|
+
end
|
73
|
+
|
74
|
+
private
|
75
|
+
|
76
|
+
def host_os
|
77
|
+
RbConfig::CONFIG['host_os']
|
78
|
+
end
|
79
|
+
end
|
80
|
+
|
81
|
+
attr_accessor :pid
|
82
|
+
attr_reader :name, :vim_path
|
83
|
+
|
84
|
+
# A Server is initialized with two options that control its behaviour:
|
85
|
+
#
|
86
|
+
# :gui - Whether or not to start Vim with a GUI, either 'gvim' or 'mvim'
|
87
|
+
# depending on the OS. The default is false, which means that
|
88
|
+
# the server will start itself as a terminal instance. Note
|
89
|
+
# that, if the terminal Vim doesn't have client/server
|
90
|
+
# support, a GUI version will be started anyway.
|
91
|
+
#
|
92
|
+
# :vim_path - A path to a custom Vim binary. If this option is not set,
|
93
|
+
# the server attempts to guess an appropriate one, given the
|
94
|
+
# :gui option and the current OS.
|
95
|
+
#
|
96
|
+
# Note that simply initializing a Server doesn't start the binary. You need
|
97
|
+
# to call the #start method to do that.
|
98
|
+
#
|
99
|
+
# Examples:
|
100
|
+
#
|
101
|
+
# server = Server.new # Will start a 'vim' if possible
|
102
|
+
# server = Server.new(:gui => true) # Will start a 'gvim' or 'mvim' depending on the OS
|
103
|
+
# server = Server.new(:vim_path => '/opt/bin/vim') # Will start a server with the given vim instance
|
104
|
+
#
|
105
|
+
def initialize(options = {})
|
106
|
+
@gui = options.fetch(:gui) { false }
|
107
|
+
@vim_path = options.fetch(:vim_path) { gui? ? Server.gui_vim_path : Server.vim_path }
|
108
|
+
|
109
|
+
@name = "VIMRUNNER#{rand.to_s}"
|
110
|
+
end
|
111
|
+
|
112
|
+
# Starts a Vim server.
|
113
|
+
def start
|
114
|
+
command = "#{vim_path} -f -u #{Server.vimrc_path} --noplugin --servername #{name}"
|
115
|
+
|
116
|
+
if gui?
|
117
|
+
@pid = Kernel.spawn(command, [:in, :out, :err] => :close)
|
118
|
+
else
|
119
|
+
_out, _in, @pid = PTY.spawn(command)
|
120
|
+
end
|
121
|
+
|
122
|
+
wait_until_started
|
123
|
+
self
|
124
|
+
end
|
125
|
+
|
126
|
+
# Returns true if the server was initialized with :gui => true. Note that
|
127
|
+
# this may not be consistent with the binary that was actually started. If
|
128
|
+
# a terminal Vim instance was attempted, but an appropriate one was not
|
129
|
+
# available, it may still have a GUI.
|
130
|
+
def gui?
|
131
|
+
@gui
|
132
|
+
end
|
133
|
+
|
134
|
+
# Kills the Vim instance in the background by sending it a TERM signal.
|
135
|
+
def kill
|
136
|
+
Shell.kill(@pid)
|
137
|
+
end
|
138
|
+
|
139
|
+
private
|
140
|
+
|
141
|
+
def wait_until_started
|
142
|
+
Timeout.timeout(5, TimeoutError) do
|
143
|
+
serverlist = Server.list
|
144
|
+
while serverlist.empty? or not serverlist.include? name
|
145
|
+
sleep 0.1
|
146
|
+
serverlist = Server.list
|
147
|
+
end
|
148
|
+
end
|
149
|
+
end
|
150
|
+
end
|
151
|
+
end
|
data/lib/vimrunner/shell.rb
CHANGED
@@ -12,18 +12,10 @@ module Vimrunner
|
|
12
12
|
IO.popen(command) { |io| io.read.strip }
|
13
13
|
end
|
14
14
|
|
15
|
-
# Sends a TERM signal to the given PID
|
16
|
-
#
|
15
|
+
# Sends a TERM signal to the given PID. Returns true if the process was
|
16
|
+
# found and killed, false otherwise.
|
17
17
|
def kill(pid)
|
18
|
-
Process.kill(
|
19
|
-
end
|
20
|
-
|
21
|
-
private
|
22
|
-
|
23
|
-
# Checks if the given PID corresponds to a running process
|
24
|
-
def running?(pid)
|
25
|
-
return false if pid.nil?
|
26
|
-
Process.getpgid(pid)
|
18
|
+
Process.kill('TERM', pid)
|
27
19
|
true
|
28
20
|
rescue Errno::ESRCH
|
29
21
|
false
|
data/lib/vimrunner/version.rb
CHANGED
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: vimrunner
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
4
|
+
version: 0.0.3
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -9,11 +9,11 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date:
|
12
|
+
date: 2012-04-22 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: rake
|
16
|
-
requirement: &
|
16
|
+
requirement: &23987740 !ruby/object:Gem::Requirement
|
17
17
|
none: false
|
18
18
|
requirements:
|
19
19
|
- - ! '>='
|
@@ -21,10 +21,10 @@ dependencies:
|
|
21
21
|
version: '0'
|
22
22
|
type: :development
|
23
23
|
prerelease: false
|
24
|
-
version_requirements: *
|
24
|
+
version_requirements: *23987740
|
25
25
|
- !ruby/object:Gem::Dependency
|
26
26
|
name: rdoc
|
27
|
-
requirement: &
|
27
|
+
requirement: &23987320 !ruby/object:Gem::Requirement
|
28
28
|
none: false
|
29
29
|
requirements:
|
30
30
|
- - ! '>='
|
@@ -32,10 +32,10 @@ dependencies:
|
|
32
32
|
version: '0'
|
33
33
|
type: :development
|
34
34
|
prerelease: false
|
35
|
-
version_requirements: *
|
35
|
+
version_requirements: *23987320
|
36
36
|
- !ruby/object:Gem::Dependency
|
37
37
|
name: rspec
|
38
|
-
requirement: &
|
38
|
+
requirement: &23986780 !ruby/object:Gem::Requirement
|
39
39
|
none: false
|
40
40
|
requirements:
|
41
41
|
- - ! '>='
|
@@ -43,7 +43,7 @@ dependencies:
|
|
43
43
|
version: 2.0.0
|
44
44
|
type: :development
|
45
45
|
prerelease: false
|
46
|
-
version_requirements: *
|
46
|
+
version_requirements: *23986780
|
47
47
|
description: ! " Using vim's client/server functionality, this library exposes
|
48
48
|
a way to\n spawn a vim instance and control it programatically. Apart from being
|
49
49
|
a fun\n party trick, this could be used to do integration testing on vimscript.\n"
|
@@ -54,11 +54,12 @@ executables:
|
|
54
54
|
extensions: []
|
55
55
|
extra_rdoc_files: []
|
56
56
|
files:
|
57
|
+
- lib/vimrunner.rb
|
58
|
+
- lib/vimrunner/errors.rb
|
57
59
|
- lib/vimrunner/shell.rb
|
60
|
+
- lib/vimrunner/server.rb
|
58
61
|
- lib/vimrunner/version.rb
|
59
|
-
- lib/vimrunner/
|
60
|
-
- lib/vimrunner/errors.rb
|
61
|
-
- lib/vimrunner.rb
|
62
|
+
- lib/vimrunner/client.rb
|
62
63
|
- vim/vimrc
|
63
64
|
- bin/vimrunner
|
64
65
|
- LICENSE
|
@@ -77,7 +78,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
77
78
|
version: '0'
|
78
79
|
segments:
|
79
80
|
- 0
|
80
|
-
hash: -
|
81
|
+
hash: -3146226263794770349
|
81
82
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
82
83
|
none: false
|
83
84
|
requirements:
|
@@ -86,7 +87,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
86
87
|
version: 1.3.6
|
87
88
|
requirements: []
|
88
89
|
rubyforge_project: vimrunner
|
89
|
-
rubygems_version: 1.8.
|
90
|
+
rubygems_version: 1.8.15
|
90
91
|
signing_key:
|
91
92
|
specification_version: 3
|
92
93
|
summary: Lets you control a vim instance through ruby
|
data/lib/vimrunner/runner.rb
DELETED
@@ -1,158 +0,0 @@
|
|
1
|
-
require 'vimrunner/shell'
|
2
|
-
require 'vimrunner/errors'
|
3
|
-
|
4
|
-
module Vimrunner
|
5
|
-
|
6
|
-
# The Runner class acts as the actual proxy to a vim instance. Upon
|
7
|
-
# initialization, a vim process is started in the background. The Runner
|
8
|
-
# instance's public methods correspond to actions the instance will perform.
|
9
|
-
#
|
10
|
-
# Use Runner#kill to manually destroy the background process.
|
11
|
-
class Runner
|
12
|
-
attr_reader :servername
|
13
|
-
|
14
|
-
class << self
|
15
|
-
def start_gvim
|
16
|
-
servername = "VIMRUNNER#{rand.to_s.gsub '.', ''}"
|
17
|
-
|
18
|
-
child_stdin, parent_stdin = IO::pipe
|
19
|
-
parent_stdout, child_stdout = IO::pipe
|
20
|
-
parent_stderr, child_stderr = IO::pipe
|
21
|
-
|
22
|
-
pid = Kernel.fork do
|
23
|
-
[parent_stdin, parent_stdout, parent_stderr].each { |io| io.close }
|
24
|
-
|
25
|
-
STDIN.reopen(child_stdin)
|
26
|
-
STDOUT.reopen(child_stdout)
|
27
|
-
STDERR.reopen(child_stderr)
|
28
|
-
|
29
|
-
[child_stdin, child_stdout, child_stderr].each { |io| io.close }
|
30
|
-
|
31
|
-
exec 'gvim', '-f', '-u', vimrc_path, '--noplugin', '--servername', servername
|
32
|
-
end
|
33
|
-
|
34
|
-
[child_stdin, child_stdout, child_stderr].each { |io| io.close }
|
35
|
-
|
36
|
-
new(pid, servername)
|
37
|
-
end
|
38
|
-
|
39
|
-
def vimrc_path
|
40
|
-
File.join(File.expand_path('../../..', __FILE__), 'vim', 'vimrc')
|
41
|
-
end
|
42
|
-
|
43
|
-
def serverlist
|
44
|
-
%x[vim --serverlist].strip.split "\n"
|
45
|
-
end
|
46
|
-
end
|
47
|
-
|
48
|
-
def initialize(pid, servername)
|
49
|
-
@pid = pid
|
50
|
-
@servername = servername
|
51
|
-
wait_until_started
|
52
|
-
end
|
53
|
-
|
54
|
-
# Adds a plugin to Vim's runtime. Initially, Vim is started without
|
55
|
-
# sourcing any plugins to ensure a clean state. This method can be used to
|
56
|
-
# populate the instance's environment.
|
57
|
-
#
|
58
|
-
# dir - The base directory of the plugin, the one that contains
|
59
|
-
# its autoload, plugin, ftplugin, etc. directories.
|
60
|
-
# entry_script - The vim script that's runtime'd to initialize the plugin.
|
61
|
-
#
|
62
|
-
# Example:
|
63
|
-
#
|
64
|
-
# vim.add_plugin 'rails', 'plugin/rails.vim'
|
65
|
-
#
|
66
|
-
def add_plugin(dir, entry_script)
|
67
|
-
command("set runtimepath+=#{dir}")
|
68
|
-
command("runtime #{entry_script}")
|
69
|
-
end
|
70
|
-
|
71
|
-
# Invokes one of the basic actions the vim server supports, sending a key
|
72
|
-
# sequence. The keys are sent as-is, so it'd probably be better to use the
|
73
|
-
# wrapper methods, #normal, #insert and so on.
|
74
|
-
def type(keys)
|
75
|
-
invoke_vim '--remote-send', keys
|
76
|
-
end
|
77
|
-
|
78
|
-
# Executes the given command in the vim instance and returns its output,
|
79
|
-
# stripping all surrounding whitespace.
|
80
|
-
def command(vim_command)
|
81
|
-
normal
|
82
|
-
|
83
|
-
expression = "VimrunnerEvaluateCommandOutput('#{vim_command.to_s}')"
|
84
|
-
|
85
|
-
invoke_vim('--remote-expr', expression).strip.tap do |output|
|
86
|
-
raise InvalidCommandError if output =~ /^Vim:E\d+:/
|
87
|
-
end
|
88
|
-
end
|
89
|
-
|
90
|
-
# Starts a search in vim for the given text. The result is that the cursor
|
91
|
-
# is positioned on its first occurrence.
|
92
|
-
def search(text)
|
93
|
-
normal
|
94
|
-
type "/#{text}<cr>"
|
95
|
-
end
|
96
|
-
|
97
|
-
# Sets a setting in vim. If +value+ is nil, the setting is considered to be
|
98
|
-
# a boolean.
|
99
|
-
#
|
100
|
-
# Examples:
|
101
|
-
#
|
102
|
-
# vim.set 'expandtab' # invokes ":set expandtab"
|
103
|
-
# vim.set 'tabstop', 3 # invokes ":set tabstop=3"
|
104
|
-
#
|
105
|
-
def set(setting, value = nil)
|
106
|
-
if value
|
107
|
-
command "set #{setting}=#{value}"
|
108
|
-
else
|
109
|
-
command "set #{setting}"
|
110
|
-
end
|
111
|
-
end
|
112
|
-
|
113
|
-
# Edits the file +filename+ with Vim.
|
114
|
-
#
|
115
|
-
# Note that this doesn't use the '--remote' vim flag, it simply types in
|
116
|
-
# the command manually. This is necessary to avoid the vim instance getting
|
117
|
-
# focus.
|
118
|
-
def edit(filename)
|
119
|
-
command "edit #{filename}"
|
120
|
-
end
|
121
|
-
|
122
|
-
# Writes the file being edited to disk. Note that you need to set the
|
123
|
-
# file's name first by using Runner#edit.
|
124
|
-
def write
|
125
|
-
command :write
|
126
|
-
end
|
127
|
-
|
128
|
-
# Switches vim to insert mode and types in the given text.
|
129
|
-
def insert(text = '')
|
130
|
-
normal "i#{text}"
|
131
|
-
end
|
132
|
-
|
133
|
-
# Switches vim to insert mode and types in the given keys.
|
134
|
-
def normal(keys = '')
|
135
|
-
type "<c-\\><c-n>#{keys}"
|
136
|
-
end
|
137
|
-
|
138
|
-
# Kills the vim instance in the background by sending it a TERM signal.
|
139
|
-
def kill
|
140
|
-
Shell.kill(@pid)
|
141
|
-
end
|
142
|
-
|
143
|
-
private
|
144
|
-
|
145
|
-
def invoke_vim(*args)
|
146
|
-
args = ['vim', '--servername', @servername, *args]
|
147
|
-
Shell.run *args
|
148
|
-
end
|
149
|
-
|
150
|
-
def wait_until_started
|
151
|
-
serverlist = Runner.serverlist
|
152
|
-
while serverlist.empty? or not serverlist.include? @servername
|
153
|
-
sleep 0.1
|
154
|
-
serverlist = Runner.serverlist
|
155
|
-
end
|
156
|
-
end
|
157
|
-
end
|
158
|
-
end
|