web-dev-qa-db-ja.com

Vi(m)で編集中のファイルを実行する方法

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

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

:!scriptname

しかし、スクリプト名を書くことを避け、画面のすぐ下ではなく分割ウィンドウで出力を取得する方法は可能ですか?

94
Alex Bolotov

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

:set makeprg=python\ %

はい、スペースをエスケープする必要があります。この後、単純に実行できます:

:make

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

:set autowrite

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

107

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

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

明らかにRubyを必要なコマンドに置き換えます。ファイル名を引用符で囲むことができるようにexecuteを使用したため、ファイル名にスペースが含まれていても機能します。

28
Brian Carper

Vimには!( "bang")コマンドは、VIM window。から直接シェルコマンドを実行します。さらに、パイプで接続され、stdoutを読み取るコマンドのシーケンスを起動できます。

例えば:

! node %

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

cd my_current_directory 
node my_current_file

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

21

私の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
11

私が使用したシェルスクリプトの場合

:set makeprg=%

:make
4
Timur Fanshteyn

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
apostl3pol

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を使用しているコースラのスタートアップエンジニアリングコースを受講しているときに同じ問題を抱えていました。

1
Angie

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

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

保存するだけでいいので、行ってください。ただ行く。

1
Jack M.

@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
Jetrock

@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
xorpaul

.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を変更した後、同じコマンドを再度実行すると、この関数は新しいウィンドウを再度作成せず、前の(同じ)分割されたウィンドウに結果を表示します。

0
Igor Komar