Question

If you compile a recent version of Vim with +ruby, you can use the :ruby command inside Vim.

What's happening 'under the hood' when I run some asynchronous Ruby code?

For example:

:ruby <<EOS
print 'hello'
Thread.new do
  sleep 1
  print 'world'
end
EOS
# hello

:ruby print 'foo'
# world
# foo

This immediately prints 'hello', as expected. However, 'world' doesn't print until I run another :ruby command. Does Vim only support one thread, and push new threads onto some sort of queue for run on the next :ruby command?

I've tried looking through Vim's source for this in src/if_ruby.c, but my Ruby C-Extension reading skills aren't the greatest.

I'm asking, because I'd like to write some Ruby that polls every few seconds and updates a Vim window.

Was it helpful?

Solution

Vim itself is single-threaded. But there are some exceptions or workarounds:

  1. Python threads are working, though not on ARM for some reason. I can’t say though I can predict what would happen if you run vim.* method from non-main thread. I saw it used in some plugins, but without vim.* in threads.
  2. Python multiprocessing module is working perfectly (though you will want to disable all vim signal handlers). I personally use this solution in my aurum plugin. I guess ruby equivalent will work, but AFAIR it is just a fork() call with simple bytes pipe as the only communication, nothing so complicated as multiprocessing.Pipe (pipe that passes a limited set of python objects), multiprocessing.Queue (wrapper around a pipe that implements objects queue), multiprocessing.Value (shared memory storing fixed-sized values with object interface) or multiprocessing.Lock (dunno what it is, but name says for itself about the purpose). At least not in standard library or core.

AFAIK some older ruby versions used green threads thus (from the OS point of view) were single-threaded while newer ruby is now using POSIX threads. You can try to update, maybe this will work. Though you’d better choose something other as the test (like modifying some variable in a separate thread), not a thing that calls vim. Any current python version you can find on users systems is using POSIX threads, this may be the root of the reason why ruby threads do not work while python ones do.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top