回答:
:silent exec "!command"
コマンドの実行中は、vimセッションがまだ占有されていることに注意してください。これは、Vimの同期性によるものです。Ctrlキーを押しながらzキーを押して(Vimをバックグラウンドに送信する)シェルに戻りfg
、通常どおりコマンドでvimを再開できます。
非同期的に処理を行うには、Tim Popeのプラグインvim-dispatchまたは、NeoMakeプラグインを使用して簡単に活用できる非同期コマンド実行のネイティブサポートがあるプロジェクトNeoVimを見てください。Vimの最新バージョンは、非同期タスクもサポートしています。
:silent !ls
)... 「がtは非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を使用することができます(注意:なしシェルコマンドを実行するコマンド!と資本を持つ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
、カーソルが開いたらクイックフィックスウィンドウに移動します。これはおそらく驚くべきことです。
(そのための回避策は:copen
、プロセスを最初に開始するときにQFウィンドウを開くことであるため、最後に呼び出す必要はありません。)
少しの間ブロックするコマンドを実行していましたが、出力はあまり気にしませんでした。これは、端末/エミュレーターではなくシステムに接続されたプロセスを開始し、すべての出力を/ dev / nullにリダイレクトすることで対処できます。例えば:
:silent exec "!(espeak 'speaking in background'&) > /dev/null"
(...&)
バックグラウンドで実行され、それと> /dev/null
のすべての出力をリダイレクトします/dev/null
(何も)。
括弧は出力をサブシェル(またはそのようなもの)にトラップしますが、現在のシェルに接続されないという副作用があります(大したことではありません)。
あなたが実際にそれをマッピングしていれば、次のようなことができることに気付きました
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テキスト全体から、私はそれをorとして解釈しました。どちらの「外部コマンド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()
、シェルコマンドが本当にサイレントになります。画面のフラッシュや再描画は行われません。
(ステータスコードが必要な場合は、v:shell_error
変数を確認できます。詳細についてはヘルプを参照してください)
ASYNCRUNのプラグインが、このために設計されている場合、それはあなたがVim8 / NeoVimにバックグラウンドでシェルコマンドを実行するとのQuickFixウィンドウに出力を表示することができます。
!
コマンドの代替として:
:AsyncRun ls -la /
また、quickfixウィンドウで出力を完全に非表示にすることもできます。
:AsyncRun -mode=3 ls -la /
ジョブが終了すると、AsyncRunはオプションを渡すことで通知します-post
:
:AsyncRun -post=some_vim_script ls -la /
によって定義されたvimスクリプトは-post
、ジョブの終了後に実行されます。