Skip to content

Commit

Permalink
Introduce Server#connect!
Browse files Browse the repository at this point in the history
  • Loading branch information
AndrewRadev committed Apr 21, 2013
1 parent 4a858c4 commit 0cc331e
Show file tree
Hide file tree
Showing 4 changed files with 83 additions and 12 deletions.
12 changes: 11 additions & 1 deletion README.md
Expand Up @@ -68,14 +68,24 @@ Vim instance, check out the [`Client`
documentation](http://rubydoc.info/gems/vimrunner/Vimrunner/Client).

If you already have a remote-capable Vim server running, you can connect
Vimrunner to it directly by using `Vimrunner.connect` like so:
Vimrunner to it directly by using `Vimrunner.connect` or `Vimrunner.connect!`
like so:

```ruby
# Assuming a running Vim server called FOO...
vim = Vimrunner.connect("FOO")
if vim
vim.insert("Hello world!")
end

# Or, if you're confident there's a running server...
vim = Vimrunner.connect!("FOO")
vim.insert("Hello world!")
```

In case of failure to find the server `FOO`, the first form will return `nil`,
while the second form will raise an exception.

## Testing

If you're using Vimrunner for testing vim plugins, take a look at the
Expand Down
20 changes: 18 additions & 2 deletions lib/vimrunner.rb
Expand Up @@ -49,7 +49,8 @@ def self.start_gvim(&blk)
Server.new(:executable => Platform.gvim).start(&blk)
end

# Public: Connect to an existing Vim process by name.
# Public: Connect to an existing Vim process by name. Returns nil in case of
# failure.
#
# name - The String name of the Vim server to connect to.
#
Expand All @@ -60,6 +61,21 @@ def self.start_gvim(&blk)
#
# Returns a Client for the named server.
def self.connect(name)
Server.new(:name => name).connect(:spawn => true)
Server.new(:name => name).connect
end

# Public: Connect to an existing Vim process by name. Raises an exception in
# case of failure.
#
# name - The String name of the Vim server to connect to.
#
# Examples
#
# client = Vimrunner.connect("FOO")
# # => #<Vimrunner::Client>
#
# Returns a Client for the named server.
def self.connect!(name)
Server.new(:name => name).connect!
end
end
43 changes: 35 additions & 8 deletions lib/vimrunner/server.rb
Expand Up @@ -28,6 +28,11 @@ class Server
# (default: Platform.vim).
# :name - The String name of the Vim server (optional)
# (default: "VIMRUNNER#{rand}").
# :vimrc - The String vimrc file to source in the client (optional)
# (default: Server::VIMRC).
# :foreground - Boolean, whether to start Vim with the -f option (optional)
# (default: true).
#
def initialize(options = {})
@executable = options.fetch(:executable) { Platform.vim }
@name = options.fetch(:name) { "VIMRUNNER#{rand}" }
Expand All @@ -50,28 +55,50 @@ def initialize(options = {})
# Yields a new Client instance initialized with this Server.
def start
@r, @w, @pid = spawn

if block_given?
begin
@result = yield(connect)
@result = yield(connect!)
ensure
@r.close
@w.close
Process.kill(9, @pid) rescue Errno::ESRCH
end
@result
else
connect
connect!
end
end

# Public: Connects to the running server by name, blocking if need be.
# Returns nil if no server was found in the given time.
#
# options - An optional Hash. For now, only used for specifying a timeout
# (default: {}):
#
# :timeout - The Integer timeout to wait for a running server (optional)
# (default: 5).
#
# Returns a new Client instance initialized with this Server.
def connect(options = {})
if !running? && options[:spawn]
@r, @w, @pid = spawn
end
wait_until_started
connect!(options)
rescue TimeoutError
nil
end

# Public: Connects to the running server by name, blocking if need be.
# Raises a TimeoutError if no server was found in the given time in
# seconds.
#
# options - An optional Hash. For now, only used for specifying a timeout
# (default: {}):
#
# :timeout - The Integer timeout to wait for a running server
# (default: 5).
#
# Returns a new Client instance initialized with this Server.
def connect!(options = {})
wait_until_running(options[:timeout] || 5)

client = new_client
client.source(VIMRUNNER_RC)
Expand Down Expand Up @@ -145,8 +172,8 @@ def spawn
PTY.spawn("#{executable} #{foreground_option} --servername #{name} -u #{vimrc}")
end

def wait_until_started
Timeout.timeout(5, TimeoutError) do
def wait_until_running(seconds)
Timeout.timeout(seconds, TimeoutError) do
sleep 0.1 while !running?
end
end
Expand Down
20 changes: 19 additions & 1 deletion spec/vimrunner/server_spec.rb
Expand Up @@ -51,7 +51,7 @@ module Vimrunner
end
end

describe "#connect" do
describe "connecting to an existing server" do
before(:each) do
server.start
end
Expand All @@ -60,10 +60,28 @@ module Vimrunner

it "returns a client" do
second_server.connect.should be_a(Client)
second_server.connect!.should be_a(Client)
end

it "returns a client connected to the named server" do
second_server.connect.server.should eq(second_server)
second_server.connect!.server.should eq(second_server)
end

describe "#connect" do
it "returns nil if no server is found in :timeout seconds" do
server = Server.new(:name => 'NONEXISTENT')
server.connect(:timeout => 0.1).should be_nil
end
end

describe "#connect!" do
it "raises an error if no server is found in :timeout seconds" do
server = Server.new(:name => 'NONEXISTENT')
expect {
server.connect!(:timeout => 0.1)
}.to raise_error(TimeoutError)
end
end
end

Expand Down

0 comments on commit 0cc331e

Please sign in to comment.