Search code examples
rubybashjob-controlneovim

Neovim job control example with ruby


Neovim's job-control example in :help job-control works well for bash scripts. However, I am unable to make it work for ruby. Consider the following example:

set nocp
set buftype=nowrite

call jobstart('shell', 'bash', ['-c', 'for ((i = 0; i < 5; i++)); do sleep 2 && printf "Hello Bash!\n"; done'])
call jobstart('shell', 'ruby', ['-e', '5.times do sleep 2 and puts "Hello Ruby!" end'])

function JobHandler()
  if v:job_data[1] == 'exit'
    let str = v:job_data[0] . ' exited'
  else
    let str = join(v:job_data[2])
  endif

  call append(line('$'), str)
endfunction

au JobActivity shell* call JobHandler()

Running nvim -u NONE -S <filename> produces the following output:

Hello Bash!
Hello Bash!
Hello Bash!
Hello Bash!
Hello Bash!
1 exited
Hello Ruby! Hello Ruby! Hello Ruby! Hello Ruby! Hello Ruby!
2 exited

How do we make the ruby example work like that for bash?


Solution

  • It turns out that ruby's output is being buffered. One has to force it to be flushed in order to see the desired output.

    call jobstart('shell', 'ruby', ['-e', '$stdout.sync = true; 5.times do sleep 1 and puts "Hello Ruby!\n" end'])
    

    My original problem was to run a ruby test asynchronously. For it to work, I had to write $stdout.sync = true to a file and require it using -r:

    call jobstart('shell', 'ruby', ['-r', '/tmp/opts.rb', '-I', 'test', 'test/unit/user_test.rb'])