Vi(m)で編集しているファイルを実行する方法


101

Vi(m)で編集しているファイルを実行し、(SciTEのように)分割ウィンドウで出力を取得する方法は?

もちろん、そのように実行できます。

:!scriptname

しかし、スクリプト名の記述を避け、画面のすぐ下ではなく分割ウィンドウで出力を取得する方法はありますか?


21
:!%を使用すると、「スクリプト名」の記述を回避できます。以下の解決策はより良いですが、あなたが決める場合のために私はこれについて言及したいと思いました:!%で十分です。
overthink

11
もう1つの注意として、現在のファイルの絶対パスを参照するには、%の代わりに%:pを使用できます。これは、現在のディレクトリが別の場所にある場合に必要になることがあります。
アンディ09/06/05

4
rubyスクリプトを実行するには:!ruby%がうまくいきます
Alexis Perrier '10

1
@andy:!%:pは、ディレクトリが$ PATHにないことも解決します
MayTheSForceBeWithYou

2
そして:!"%:p"空白に対処する。
OJFord 2017年

回答:


109

makeコマンドがあります。makeprgオプションで設定したコマンドを実行します。%現在のファイル名のプレースホルダーとして使用します。たとえば、Pythonスクリプトを編集している場合:

:set makeprg=python\ %

はい、あなたはスペースを脱出する必要があります。この後、単に実行できます:

:make

必要に応じて、autowriteオプションを設定すると、実行前に自動的に保存されますmakeprg

:set autowrite

これにより、実行部分が解決されます。ファイルへのリダイレクトを含まない分割ウィンドウにその出力を取得する方法がわからない。


5
実際には、ソリューションは出力を分割ウィンドウに送ります。独自のウィンドウで。を:copen実行して生成された「エラーリスト」を開くために使用し:makeます。残念ながら、出力を適切にフォーマットするには、errorformatオプションの調整が必要です。そうでない場合、出力はgccが出力する形式であると想定されます。
目立つコンパイラ

2
「フォーマットする」エラーフォーマットについては間違いない。それは私が見たいくつかのperlコードのように見えます...
R.マルティーニョフェルナンデス

1
この機能は、vimからプロジェクトの「make」に使用できます(vimにIDEのような機能を提供します)。ブライアンカーパーの解決策(:let f=expand("%")|vnew|execute '.!ruby "' . f . '"')は謎めいたように見えますが、質問の作成者が尋ねたとおりに機能します。
AjayKumarBasuthkar 14

29

現在のバッファのファイル名にアクセスするには、を使用します%。これを変数に入れるには、expand()関数を使用できます。新しいバッファで新しいウィンドウを開くには、:newまたはを使用します:vnew。コマンドからの出力を現在のバッファーにパイプするには、を使用します:.!。すべてを一緒に入れて:

:let f=expand("%")|vnew|execute '.!ruby "' . f . '"'

明らかにrubyあなたが望むどんなコマンドでも置き換えます。私executeはファイル名を引用符で囲むことができるように使用したので、ファイル名にスペースが含まれていれば機能します。


3
@baboonWorksFine Use :command! R let f=expand("%")|vnew|execute '.!ruby "' . f . '"'を使用:Rしてコマンドを実行できる
xorpaul

実行中にユーザー入力を必要とするスクリプトを使用してこれを実行することは可能でしょうか?
ilstam 2015年

23

Vimには!、VIMウィンドウから直接シェルコマンドを実行する(「bang」)コマンドがあります。さらに、パイプに接続され、標準出力を読み取るコマンドのシーケンスを起動できます。

例えば:

! node %

コマンドプロンプトウィンドウを開いてコマンドを起動することと同じです。

cd my_current_directory 
node my_current_file

詳細については、「Vimのヒント:外部コマンドの操作」を参照してください。


11

私は私のvimrcにそのショートカットがあります:

nmap <F6> :w<CR>:silent !chmod 755 %<CR>:silent !./% > .tmp.xyz<CR>
     \ :tabnew<CR>:r .tmp.xyz<CR>:silent !rm .tmp.xyz<CR>:redraw!<CR>

これにより、現在のバッファーが書き込まれ、現在のファイルが実行可能になり(UNIXのみ)、それが実行され(UNIXのみ)、出力が.tmp.xyzにリダイレクトされ、新しいタブが作成され、ファイルが読み取られてから削除されます。

それを分解する:

:w<CR>                             write current buffer
:silent !chmod 755 %<CR>           make file executable
:silent !./% > .tmp.xyz<CR>        execute file, redirect output
:tabnew<CR>                        new tab
:r .tmp.xyz<CR>                    read file in new tab
:silent !rm .tmp.xyz<CR>           remove file
:redraw!<CR>                       in terminal mode, vim get scrambled
                                   this fixes it

2
私はあなたの解決策をとても気に入っており、それを使用してしばらくすると、改善できると感じました。これが私の見解です::w<CR>:silent !chmod +x %:p<CR>:silent !%:p 2>&1 | tee ~/.vim/output<CR>:split ~/.vim/output<CR>:redraw!<CR>—これはstdoutとstderrの両方を一時ファイルにリダイレクトします。これを行う前に、すべてをstdoutに出力するので、スクリプトの実行に時間がかかる場合、実際に機能していることがわかります。また、それはディレクトリに依存しません(絶対パスでファイルを開くときにエラーが発生しました)。ただし、スクリプトをインタラクティブに実行することはできません。そのための方法が見つかりませんでした。
Kirill G

1
fyi-@Cyrilのソリューションでは、パイプ記号をエスケープする必要がありました:| -> \ |
mpettis 2013年


3

Vim 8には対話型ターミナルが組み込まれています。分割ペインで現在のbashスクリプトを実行するには:

:terminal bash %

または略して

:ter bash %

% 現在のファイル名に展開されます。

から:help terminal

The terminal feature is optional, use this to check if your Vim has it:
    echo has('terminal')
If the result is "1" you have it.

1

私はマップを通してもう少し侵入的なメカニズムを使用します:

map ;e :w<CR>:exe ":!python " . getreg("%") . "" <CR>

作るだけなので、保存する必要はありません。ただ行く。


1
自動書き込みオプションを設定した場合、:makeを実行すると、自動保存されます。
R.マルティーニョフェルナンデス

1

vimのプラグインbexecを使用できます。私の知る限り、最新バージョンは0.5です。

次に:

$ mkdir -p ~/.vim/plugin
$ mv bexec-0.5.vba ~/.vim/plugin
$ vim ~/.vim/plugin/bexec-0.5.vba

.vbaファイルの編集中にvim自体の内部で次を実行します。

:so %

いくつかの出力は、bexec.vimがドキュメントなどと同様に記述されていることを通知して表示されます。

これで、vimで(#!インタープリターが適切に動作している言語スクリプト)を開いてテストすることができます。

:Bexec 

注:分割を水平ではなく垂直にしたかったので、次のようにしました。

$ grep -i -n split ~/.vim/plugin/bexec.vim | grep -i hor
102:    let bexec_splitdir = "hor" " hor|ver
261:        exec {"ver":"vsp", "hor":"sp"}[g:bexec_splitdir]

の値を「hor」から「ver」に変更しました。

私はそれが古い質問であることを知っていますが、これがそこにいる誰かを助けることを願っています。パラジ教授がEmacsを使用しており、Emacsが好きではないCourseraのスタートアップエンジニアリングコースを受講しているときにも、同じ問題を抱えています。


ローカルの.vimrcの設定に関連する設定を変更する必要があります。bexecは "let bexec_splitdir = 'hor'"設定を提供し、プラグインコードを変更せずにこれを行うことができます。
Saurabh Hirani 2014年

0

@SethKriticosと@Cyrilの回答に基づいて、以下を使用します。

function! Setup_ExecNDisplay()
  execute "w"
  execute "silent !chmod +x %:p"
  let n=expand('%:t')
  execute "silent !%:p 2>&1 | tee ~/.vim/output_".n
  " I prefer vsplit
  "execute "split ~/.vim/output_".n
  execute "vsplit ~/.vim/output_".n
  execute "redraw!"
  set autoread
endfunction

function! ExecNDisplay()
  execute "w"
  let n=expand('%:t')
  execute "silent !%:p 2>&1 | tee ~/.vim/output_".n
  " I use set autoread
  "execute "1 . 'wincmd e'"
endfunction

:nmap <F9> :call Setup_ExecNDisplay()<CR>
:nmap <F2> :call ExecNDisplay()<CR>

F9を使用して新しいウィンドウをセットアップし、F2を使用してスクリプトを実行し、出力ファイルにティーします。

また、スクリプト名を出力ファイル名に追加したので、これを同時に複数のスクリプトに使用できます。


0

あなたに.vimrcこの関数を貼り付けることができます

function! s:ExecuteInShell(command)
  let command = join(map(split(a:command), 'expand(v:val)'))
  let winnr = bufwinnr('^' . command . '$')
  silent! execute ':w'
  silent! execute  winnr < 0 ? 'vnew ' . fnameescape(command) : winnr . 'wincmd w'
  setlocal buftype=nowrite bufhidden=wipe nobuflisted noswapfile nowrap number
  silent! execute 'silent %!'. command
  silent! redraw
  silent! execute 'au BufUnload <buffer> execute bufwinnr(' . bufnr('#') . ') . ''wincmd w'''
  silent! execute 'nnoremap <silent> <buffer> <LocalLeader>r :call <SID>ExecuteInShell(''' . command . ''')<CR>'
  silent! execute 'wincmd w'
  " echo 'Shell command ' . command . ' executed.'
endfunction
command! -complete=shellcmd -nargs=+ Shell call s:ExecuteInShell(<q-args>)
cabbrev shell Shell

その後、例としてvimコマンド:shell python ~/p.pyを実行します。そして、分割されたウィンドウで出力を取得します。+ p.py例のように変更した後、同じコマンドを再度実行すると、この関数は新しいウィンドウを再度作成せず、前の(同じ)分割ウィンドウに結果を表示します。


これは素晴らしいです、ありがとう!バッファーが再度書き込まれたときに再実行するように変更するにはどうすればよいですか?
elzi

0

@xorpaul

私はかなり前からこのスクリプト(python / Windows)を探していました。Windowsには「ティー」がないため、次のように変更しました。

function! Setup_ExecNDisplay()
  execute "w"
  let n=expand('%:t')
  execute "silent ! python % > d:\\temp\\output_".n ." 2>&1"
  execute "vsplit d:\\temp\\output_".n
  execute "redraw!"
  set autoread
endfunction

function! ExecNDisplay()
  execute "w"
  let n=expand('%:t')
  execute "silent ! python % > d:\\temp\\output_".n . " 2>&1"
endfunction

:nmap <F9> :call Setup_ExecNDisplay()<CR>
:nmap <F2> :call ExecNDisplay()<CR>

0

以下に示すように、コロンと感嘆符を使用するだけです

:!<script_name>


弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.