One of the features that made me switch to neovim was that at the time I was writing a plugin for vim and I was surprised that there was no easy way to do asynchronous calls.

Meaning that if your command was taking too long, it freezed the UI. A famous example of that is SQL client plugin, dbext, which will freeze vim when your sql request takes too long.

Remote plugins

Remote plugins are one of the best features of neovim. Neovim will spawn a separate process, and communicate with it via msgpack RPC API.

So now plugins can process stuff in the background without vim freezing.

neovim-ruby

neovim-ruby README is well writen and will get you started, you should read it if you’re going to write a remote plugin.

winds-up-client

I like kiteboarding, which depends on wind conditions. The thing is that its good to always have an eye on these conditions. There’s a very good website which is called winds-up

I had already written a ruby gem to get a ultrashort report from winds-up, here is what it looks like

$ winds-up-client --lpass --ultrashort
B3↓S1↘P2↘S13↘V2↘

The ultrashort report will contain all your favorite spots (first letter of each spot), the wind speed (in nautical knots) and the wind direction (an arrow),

For example S13↘ means that my spot ‘S’ has 13 knots comming from north-west.

writing the plugin

I’m installing it in the same repo as my gem, so that when it is installed via a plugin manager like vim-plug, it already has the gem embeded with it. Here is what it looks like:

rplugin/ruby/winds-up-client.rb

require 'neovim'
require_relative '../../lib/winds-up-client'
Neovim.plugin do |plug|
  client = WindsUpClient.new(lpass: true, ultrashort: true)
  last_check = nil
  plug.command(:WindsUp) do |nvim|
    if last_check.nil? or Time.new - last_check > 60 
      begin
        nvim.set_var "windsup", client.favorites_spots_text.chomp
      rescue Exception
      end
      last_check = Time.new
    end
  end
end

Let’s break it down.

I install it in rplugin/ruby/winds-up-client.rb which is the path which neovim uses to load ruby neovim plugin.

I require my ruby library (which is in the same repo):

require_relative '../../lib/winds-up-client'

Within my plugin context, I instantiate my client with the same arguments as the command line shown before:

Neovim.plugin do |plug|
  client = WindsUpClient.new(lpass: true, ultrashort: true)

I declare a variable which will contain the timestamp of the last call to my command.

  last_check = nil

Then I declare my command, which can now be invoked via :WindsUp It has an nvim client object to interract with neovim. I make sure it only gets called every 60 seconds, using last_check variable:

  plug.command(:WindsUp) do |nvim|
    if last_check.nil? or Time.new - last_check > 60 
      # ... do stuff
      last_check = Time.new
    end
  end

Then I call my command, and set a neovim variable (windsup) contents with my ultrashort report.

Here is more documentation on what you can do with nvim object

begin
  nvim.set_var "windsup", client.favorites_spots_text.chomp
rescue Exception
end

I also catch any exception, because I don’t want my plugin to echo its errors into vim (which it will do in case of exception). You should definitely not do that when you’re developing your plugin.

using it

I then use it in my tabbar vimscript (which is based on a fork of c98tabbar.vim), by calling my command

if exists(":WindsUp")
  :WindsUp
endif

end then retrieving the g:windup variable contents to display them.

if exists("g:windsup")
  let l:s .= g:windsup
endif

Here is the result:

tabbar

conclusion

So here was my very simple plugin, you can have a look at it here.

As you can see, neovim ruby plugins are really easy to write.

Hope it can help you if you want to write your own plugin !