0

So, to begin, this is similar to Pipe shell command into buffer in real-time.

The difference is that the top answer there pipes the output to a new buffer. How do I pipe the output to the editor itself in real time?

For example, I have this open in my vim (with line numbers on for illustration):

1 for num in "a" "b" "c"; do echo "${num}"; sleep 1; done
2
3
4

What I want is to be able to run a command that execute that line (something like yyp!!bash), and get these in the editor in the interval of 1 second:

1 for num in "a" "b" "c"; do echo "${num}"; sleep 1; done
2 a
3
4

then

1 for num in "a" "b" "c"; do echo "${num}"; sleep 1; done
2 a
3 b
4

then

1 for num in "a" "b" "c"; do echo "${num}"; sleep 1; done
2 a
3 b
4 c

Is this possible to do in vim?

Currently yyp!!bash will print the output only after the whole command is finished (i.e., only gets the output after three seconds).

Update

If that's not possible (as hinted in the comments), alternatively I would be interested in an editable terminal, essentially being able to edit the output (and the input) of :term.

  • For vim 8 we have :terminal command. Also :read !bash should works. :help read for explanations. I'm not sure is asynchronous input possible in vim. – Alex Kroll Mar 20 at 12:13
  • You should read the entire file :help channel.txt. Perhaps it is doable. – Ralf Mar 20 at 12:57
  • You are just trying to mimic an interactive shell behavior. But assuming you have recent enough neo/vim, you can just use another split for :h :terminal. Otherwise, r !cmd would write the output of cmd after the command is finished. – klaus Mar 20 at 14:47
  • Yeah, essentially it's mimicking interactive shell behavior, but with editable command prompt and output buffer. I saw my friend doing this in emacs, so I also would like to do the same in vim (too costly to change to emacs now...), as I find it useful to run short commands and make sure the outputs are logged. At the very least, then, how to go to insert mode while in terminal opened by :term? – justhalf Mar 20 at 15:23
  • maybe you can do it in python line by line(using subprocess) and use the vim lib for running commands (like insert) that will output it at real time. – eyal karni Mar 20 at 16:52
1

You've clarified in the comments that your need would be satisfied if you could edit the output buffer and current command prompt when in a :terminal buffer.

You can achieve the latter by using your shell's "edit in an editor" function. In bash, this is called edit-and-execute-command and is usually bound to Ctrl-XCtrl-E (make sure your EDITOR variable is set). Other shells have similar features, although I haven't tested these.

Amazingly, this even works inside a :terminal buffer, spawning a new instance of Vim inside Vim.

Unfortunately, unless I'm misreading :help terminal.txt, it's not possible to edit the contents of a Vim terminal window.

Before looking into rolling your own solution, you might like to look into the Conque plugin. Whilst development on it has ceased, it's always worked well for me. To use it to run a bash shell you run the command:

:ConqueTerm bash

The new shell starts in insert mode. You can escape to normal mode by pressing Esc as usual, after which you can edit any output using regular Vim commands.

Entering insert mode while on the command line will return you to typing into the prompt, but you can still use edit-and-execute-command to edit the current command as I described above. The one proviso is that when you are in the Vim-inside-a-Vim in Conque, pressing Esc will exit insert mode of the outer instance of Vim. The easiest way to exit insert mode in the inner Vim is to press Ctrl-C instead, but setting up a mapping would also work.

All the above applies to Vim. I don't know what the situation is like in Neovim, which has it's own similar-but-different implementation of a terminal window.

1

Well looking at your comments... Try to reuse built in :terminal either by manually copy-pasting to it or using plugin https://github.com/habamax/vim-sendtoterm

It might look like:

enter image description here

  • When you say "manually copy-pasting to it", are you referring to the OS copy? Or vim copy? How do you do that? – justhalf Mar 22 at 15:43
  • I don't do it, I use plugin. But if I did I would use barebone vim copy paste like yy<C-w>w<C-r>", this is not tested though ;) – Maxim Kim Mar 22 at 16:52
  • so, vim help tells me that it should be yy<C-w>w<C-w>"". Where yy copy current line to anonymous register, <C-w>w switch to next window (terminal in our case) then <C-w>"" insert contents of anonymous " register. – Maxim Kim Mar 22 at 17:00
  • :h t_CTRL-W_quote – Maxim Kim Mar 22 at 17:01
  • neovim is easier -- it is just p to paste – Maxim Kim Mar 22 at 17:03

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.