Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

In Vim, can I "stream" the output of e.g. "w ! ruby" into a buffer, line by line as they're output?

Tags:

vim

I'm currently doing something like this:

redir => m
  silent w ! ruby
redir END
new
put=m

It executes the contents of the current buffer as Ruby code and puts the output in a new buffer.

But if the Ruby code I run is something like

puts "start"
sleep 10
puts "end"

then I will see no output for 10 seconds, then both "start" and "end" all at once.

Is there instead some way to "stream" the output to a buffer, line by line as it appears? So that I would see "start", then 10 seconds later I would see "end"? Similar to what happens if I just do

w ! ruby

and look at the output under the command line.

like image 779
Henrik N Avatar asked Nov 06 '22 01:11

Henrik N


1 Answers

Vim does not really expose primitives for this kind of I/O, but you can do it from one of the embedded language interfaces.

Here's a sketch using Python and subprocess (Ruby would look similar; see if_ruby):

python << EOF
import vim
import subprocess

def output_lines_to_buffer(cmd):
    """
    Append the given shell command's output linewise to the current buffer.
    """
    p = subprocess.Popen(cmd, stdout=subprocess.PIPE, shell=True)
    for line in iter(p.stdout.readline, ''):
        vim.current.buffer.append(line)
        vim.command('redraw')
EOF

To use:

:python output_lines_to_buffer('my command')

This will simply append each line of output to the end of the current buffer, as my command emits it. You can extend it fairly straightforwardly to support input and output ranges and so on, depending on what you need.

like image 171
Pi Delport Avatar answered Nov 15 '22 06:11

Pi Delport