Answers:
:silent exec "!command"
注意,在执行命令时,vim会话仍将被占用。这是由于Vim具有同步特性。您仍然可以通过按CTRL + z(将Vim发送到后台)返回外壳,然后fg
像往常一样使用命令恢复vim 。
要异步执行操作,请看一下Tim Pope的插件vim-dispatch或项目NeoVim,它具有对异步命令执行的本机支持,您可以使用插件NeoMake轻松利用它。Vim的最新版本还支持异步任务。
:silent !ls
)...它也不会不会在非0的退出代码上提供正确的输出...因此,我担心它比仅仅使用它会涉及更多:silent
……
:silent exec "!ls"
没有:silent !ls
显示任何输出。
要执行命令而不触发Enter消息,例如:
按ENTER或键入命令以继续
请尝试以下简单示例:
:silent !echo Hello
然后,在返回Vim时按Ctrl+ L(或:redraw!
)刷新屏幕。
为了避免刷新,您可以定义自己的自定义命令,例如:
:command! -nargs=1 Silent execute ':silent !'.<q-args> | execute ':redraw!'
现在,您可以使用新的Vim命令运行shell命令(注意:不带!且带大写字母S):
:Silent ps
来源:避免在Vim Wikia网站上出现“单击ENTER以继续”提示
:Silent ctags -R . > /dev/null &
后台运行的命令。将stdout发送到/ dev / null可以防止输出出现在vim缓冲区中。
这可以在后台启动一个过程:
:!slow_command_here > /tmp/output 2>&1 &
但是Vim需要一种方法来确定过程何时完成以及如何完成,所以让我们使用标记文件:
:!(rm -f /tmp/finished; slow_command_here > /tmp/output 2>&1; echo "$?" > /tmp/finished) &
现在,我们可以要求Vim经常检查该过程是否已完成:
:augroup WaitForCompletion
:autocmd!
:autocmd CursorHold * if filereadable('/tmp/finished') | exec "augroup WaitForCompletion" | exec "au!" | exec "augroup END" | echo "Process completed with exit code ".readfile('/tmp/finished')[0] | end
:augroup END
嘿,这不漂亮,但是有点奏效!
不幸的是,直到您移动光标,上面的autocmd才会触发。而且,如果您想一次运行多个后台进程,则需要向这些文件以及autocmd组名称添加唯一的ID。
因此,如果您可以处理额外的依赖关系,则最好使用经过反复测试的解决方案,例如另一个答案中提到的vim-dispatch插件。
如果您要查看流程的输出,而不仅仅是出口代码,则将echo
上面的最终代码替换为:
silent botright pedit /tmp/output
这将打开预览窗口。要改用quickfix错误列表:
silent cget /tmp/output | copen
快速修复列表使您可以使用轻松导航至错误:cnext
。但是,copen
当光标打开时,将光标移到quickfix窗口中,这可能令人惊讶/烦恼。
(A为解决方法是打开与QF窗口:copen
当最初开始的过程,所以你不会需要在结束调用它。)
我正在运行的命令被阻塞了一段时间,而我实际上并不关心输出。可以通过启动不是附加到终端/仿真器而是附加到系统的进程并将所有输出重定向到/ dev / null来解决此问题。例如:
:silent exec "!(espeak 'speaking in background'&) > /dev/null"
在(...&)
运行时,它在后台和> /dev/null
重定向所有输出/dev/null
(无)。
括号将输出捕获到子shell(或类似的东西)中,但是它确实具有未附加到当前shell的副作用(没什么大不了的)。
我只是意识到,如果实际上是在映射它,则可以执行以下操作
nnoremap <silent> <leader>e :!$(espeak 'speaking in the background'&) > /dev/null
上面的命令不会在命令栏中显示任何内容,此外,在vim之外的终端中也不会显示任何内容。它会被映射到<leader>
e,这是\ e默认。
(另一种编辑-也许是最整洁的一种)。如果您选择以下命令,它将显示命令的输出:
放入新标签:
silent exec "!(echo 'hello. I'm a process! :)') > /tmp/vim_process" | :tabedit /tmp/vim_process
在垂直分割内:
silent exec "!(echo 'hello. I'm a process :)') > /tmp/vim_process" | :vs /tmp/vim_process
在水平分割内:
silent exec "!(echo 'hello. I'm a process :)') > /tmp/vim_process" | :sp /tmp/vim_process
... 做你想做的
如果您不在乎退出代码,则可以执行以下操作:
:call system('/usr/bin/zathura using-docker.pdf &')
v:shell_error
变量将告诉您
不知道这是否满足您的需求((不像处理中的后台进程foo &
–不确定这是否意味着您在“后台”)),但是可以在以下情况中使用自定义命令:
fun! s:PraeceptumTacet(cmd)
silent let f = systemlist(a:cmd)
if v:shell_error
echohl Error
echom "ERROR #" . v:shell_error
echohl WarningMsg
for e in f
echom e
endfor
echohl None
endif
endfun
command! -nargs=+ PT call s:PraeceptumTacet(<q-args>)
然后使用例如:
:PT ls -l
:PT foobar
ERROR #127
/bin/bash: foobar: command not found
如果您不需要/想要一个简单的错误消息 system()
就足够了,然后v:shell_error
通过例如进行检查并报告echo Error!
。
从帮助v:shell_error:
v:shell_error shell_error-variable
v:shell_error Result of the last shell command. When non-zero, the last
shell command had an error. When zero, there was no problem.
This only works when the shell returns the error code to Vim.
The value -1 is often used when the command could not be
executed. Read-only.
Example: >
:!mv foo bar
:if v:shell_error
: echo 'could not rename "foo" to "bar"!'
:endif
"shell_error" also works, for backwards compatibility.
foo &
”。从整个Q文本中,我将其解释为“或”。或者“执行外部命令AKA背景”或“执行外部命令_and_作为后台进程。”。我主要根据Q等标题回答-并在“不确定...”上添加了评论-并将其留给OP来说明是或否。
我使用以下代码:
command! -nargs=1 Silent call SilentExec(<q-args>)
function! SilentExec(cmd)
let cmd = substitute(a:cmd, '^!', '', '')
let cmd = substitute(cmd, '%', shellescape(expand('%')), '')
call system(cmd)
endfunction
现在您可以输入以下内容
:Silent !your_command
silent !
除了大写字母外,这几乎类似于Vim的内置命令S
。它甚至允许可选!
,使其看起来更加相似。调用system()
使shell命令真正静音:没有屏幕闪烁,也没有重绘。
(如果您需要状态码,则可以检查该v:shell_error
变量,有关更多信息,请参见帮助)