やりたいこと
- pythonをvimを閉じずに実行する
- 実行結果を新しいバッファに表示する
できたもの
- pythonファイルの場合のみ
<F5>
を押すと実行される - 実行結果が新しいバッファに表示される
- 複数回実行した場合は追記される
- 複数のpythonファイルが開かれていいる場合カーソルがあるファイルが実行される
やったこと
素朴な方法
:!python %
Exコマンド:! hoge
はcmdhoge
を実行してくれます.これを<F5>
へ割り当てます.
autocmd BufRead,BufNewFile *.py inoremap <F5><Esc>:w<CR>:! python %<CR>
autocmd BufRead,BufNewFile *.py nnoremap <F5>:w<CR>:! python %<CR>
これで<F5>
を押すことで開いているファイルを実行できます.
問題点
実行結果がENTER
を押すことで消えてしまう.
新しいバッファを開く方法
上記の問題を解決するため新しいバッファを開くように設定しました.ただし、既に開いている場合を除かないと<F5>
を押すたびに増殖するのでこれを解決するために場合分けが必要です.長くなったのでPyexe()
という関数を作りました.
このとき、先程使った:! hoge
は実行するだけなので出力を文字列として得られるsystem(hoge)
を使います.
"関数を定義function Pyexe()"結果を出力用のバッファに入力後戻ってくる準備"カーソルの現在位置を取得:let pos=getpos(".")"現在のウィンドウのidを取得:let cwinid=win_getid()"現在のウィンドウのバッファのファイル名を取得:let fileName=expand('%')"出力用のバッファの設定"表示するファイル名を決定:let outFileName="~pyOut""既に出力用のウィンドが開かれているか確認する準備"出力用のバッファが存在している場合バッファ番号を得る.存在しない場合-1.:let bnr=bufnr(outFileName)"出力用のバッファのウィンドウidを取得(リスト形式).存在しない場合は空のリスト.:let wids=win_findbuf(bnr)"出力用のバッファが存在する場合ウィンドウidをoutWindidへ.存在しない場合作る.if bnr ==-1|| len(wids)==0"存在しない場合"ウィンドウを分割して出力用のバッファを作る:verticalrightbelownew~pyOut
"ウィンドウのサイズを調整:verticalresize70"出力用のバッファがウィンドウidを取得:let outWinid=win_getid()"出力用のバッファバッファ番号を得る:let bnr=bufnr(outFileName)else"存在する場合"出力用のバッファのウィンドウidをリストから取り出す:let outWinid=wids[0]endif"出力"出力用のバッファのウィンドウへ移動:call win_gotoid(outWinid)"出力用のバッファの末行へ移動:call setpos(bnr,"$")"cmdを呼び出してpythonを実行:let @r=system('python '.fileName)"出力用のバッファへプットする:putr"再描写:redraw!"開始位置へ戻る"pythonファイルのウィンドウへ移動:call win_gotoid(cwinid)"開始位置へカーソルを移動:call setpos(".",pos)endfunction
あとはこれをpythonの場合のみ<F5>
へ割り当てます.
"pythonファイルの場合のみ<F5>キーを押すことで実行できるようにする
autocmd BufRead,BufNewFile *.py inoremap <F5><Esc>:w<CR>:call Pyexe()<CR>
autocmd BufRead,BufNewFile *.py nnoremap <F5>:w<CR>:call Pyexe()<CR>