On a Linux platform I see this difference of behavior between running a shell command with :!{cmd}
(which just runs the command directly) and with :w !{cmd}
(which passes the buffer as standard input to the command.)
Running :!{cmd}
will switch back from the alternate screen back to the main screen, which means the Vim buffer and UI are hidden and the screen on the shell where I ran Vim are presented back, then the command output is printed and the "hit return" prompt is issued.
If I start vim
, then run :!echo hello
, the result I see is:
$ vim
hello
Press ENTER or type command to continue
That text is also present after I exit Vim, since it's been output into the main screen, not the alternate screen that Vim is managing.
On the other hand, if I run the same command with :w !{cmd}
, Vim simply prints the output of the command below the Ex command-line. For :w !echo hello
, what I end up seeing is:
~
~
~
[No Name] 0,0-1 All
:w !echo hello
hello
Press ENTER or type command to continue
You'll recognize the ~
s as Vim's empty lines at the end of the buffer, and the [No Name]
line as Vim's status line. The Ex command is also not cleared.
Why the difference?
The documentation isn't very clear about it. The closest thing mentioned in :help :!
is that "Vim redraws the screen after the command is finished, because it may have printed any text", but that doesn't really explain why it needs to switch back to the main screen. It also mentions using :silent
to prevent redrawing, but that prevents any output altogether.
Documentation in :help :write_c
doesn't help much either, it says *"{cmd}
is executed like with :!{cmd}
", but it's actually referring to how !
s are special in the command itself...
Is there a way to make :!{cmd}
behave like :w !{cmd}
, without switching back from the alternate screen?
Or is there another way to run an external command on the alternate screen, that doesn't involve passing it lines from the current buffer as standard input?
is there another way to run an external command on the alternate screen, that doesn't involve passing it lines from the current buffer as standard input?
try to remove^[[?1049h
from&t_ti
and^[[?1049l
from&t_te
(0x0.st/iQDw.txt ). Look at xterm's documentation, in particular the sequenceCSI ? Pm h
, and the line starting withPs = 1 0 4 9
.set t_ti=
explicitly, I looked for it again and found it was vim-flake8. It's on a slightly different context (using'grepprg'
) but still related. Not sure if this is a more widespread practice or not... Do you know of other examples (or have you written any plugins yourself) which use this same technique?if (addr_count == 0) do_in = do_out = FALSE;
and thendo_filter(...); apply_autocmds(...);
instead of that whole "if" block - everything looks fine).