Vi(m)で編集しているファイルを実行し、(SciTEのように)分割ウィンドウで出力を取得する方法は?
もちろん、そのように実行できます。
:!scriptname
しかし、スクリプト名の記述を避け、画面のすぐ下ではなく分割ウィンドウで出力を取得する方法はありますか?
:!"%:p"
空白に対処する。
Vi(m)で編集しているファイルを実行し、(SciTEのように)分割ウィンドウで出力を取得する方法は?
もちろん、そのように実行できます。
:!scriptname
しかし、スクリプト名の記述を避け、画面のすぐ下ではなく分割ウィンドウで出力を取得する方法はありますか?
:!"%:p"
空白に対処する。
回答:
make
コマンドがあります。makeprg
オプションで設定したコマンドを実行します。%
現在のファイル名のプレースホルダーとして使用します。たとえば、Pythonスクリプトを編集している場合:
:set makeprg=python\ %
はい、あなたはスペースを脱出する必要があります。この後、単に実行できます:
:make
必要に応じて、autowrite
オプションを設定すると、実行前に自動的に保存されますmakeprg
。
:set autowrite
これにより、実行部分が解決されます。ファイルへのリダイレクトを含まない分割ウィンドウにその出力を取得する方法がわからない。
:copen
実行して生成された「エラーリスト」を開くために使用し:make
ます。残念ながら、出力を適切にフォーマットするには、errorformat
オプションの調整が必要です。そうでない場合、出力はgccが出力する形式であると想定されます。
:let f=expand("%")|vnew|execute '.!ruby "' . f . '"'
)は謎めいたように見えますが、質問の作成者が尋ねたとおりに機能します。
現在のバッファのファイル名にアクセスするには、を使用します%
。これを変数に入れるには、expand()
関数を使用できます。新しいバッファで新しいウィンドウを開くには、:new
またはを使用します:vnew
。コマンドからの出力を現在のバッファーにパイプするには、を使用します:.!
。すべてを一緒に入れて:
:let f=expand("%")|vnew|execute '.!ruby "' . f . '"'
明らかにruby
あなたが望むどんなコマンドでも置き換えます。私execute
はファイル名を引用符で囲むことができるように使用したので、ファイル名にスペースが含まれていれば機能します。
:command! R let f=expand("%")|vnew|execute '.!ruby "' . f . '"'
を使用:R
してコマンドを実行できる
Vimには!
、VIMウィンドウから直接シェルコマンドを実行する(「bang」)コマンドがあります。さらに、パイプに接続され、標準出力を読み取るコマンドのシーケンスを起動できます。
例えば:
! node %
コマンドプロンプトウィンドウを開いてコマンドを起動することと同じです。
cd my_current_directory
node my_current_file
詳細については、「Vimのヒント:外部コマンドの操作」を参照してください。
私は私の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
:w<CR>:silent !chmod +x %:p<CR>:silent !%:p 2>&1 | tee ~/.vim/output<CR>:split ~/.vim/output<CR>:redraw!<CR>
—これはstdoutとstderrの両方を一時ファイルにリダイレクトします。これを行う前に、すべてをstdoutに出力するので、スクリプトの実行に時間がかかる場合、実際に機能していることがわかります。また、それはディレクトリに依存しません(絶対パスでファイルを開くときにエラーが発生しました)。ただし、スクリプトをインタラクティブに実行することはできません。そのための方法が見つかりませんでした。
私が使用したシェルスクリプト
:set makeprg=%
:make
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.
私はマップを通してもう少し侵入的なメカニズムを使用します:
map ;e :w<CR>:exe ":!python " . getreg("%") . "" <CR>
作るだけなので、保存する必要はありません。ただ行く。
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のスタートアップエンジニアリングコースを受講しているときにも、同じ問題を抱えています。
@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を使用してスクリプトを実行し、出力ファイルにティーします。
また、スクリプト名を出力ファイル名に追加したので、これを同時に複数のスクリプトに使用できます。
あなたに.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
例のように変更した後、同じコマンドを再度実行すると、この関数は新しいウィンドウを再度作成せず、前の(同じ)分割ウィンドウに結果を表示します。
@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>