如何执行文件我正在编辑(六)

如何在Vi(m)中执行我正在编辑的文件并在分割窗口中获取输出(如在SciTE中)?

当然,我可以这样执行:

:!scriptname 

但避免编写脚本名称,以及如何在分割窗口而不是在屏幕底部输出输出是否可行呢?

make命令。 它运行makeprg选项中设置的命令。 使用%作为当前文件名的占位符。 例如,如果你正在编辑一个python脚本:

 :set makeprg=python\ % 

是的,你需要逃离这个空间。 之后,你可以简单地运行:

 :make 

如果你愿意,你可以设置autowrite选项,它会在运行makeprg之前自动保存:

 :set autowrite 

这解决了执行部分。 不知道有什么方法可以将输出转换到不涉及redirect到文件的拆分窗口。

要访问当前缓冲区的文件名,请使用% 。 要把它变成一个variables,你可以使用expand()函数。 要用新缓冲区打开新窗口,请使用:new:vnew 。 要将输出从命令input到当前缓冲区,请使用:.! 。 把它放在一起:

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

显然用你想要的任何命令取代ruby 。 我使用execute所以我可以用引号包围文件名,所以它会工作,如果文件名中有空格。

Vim有! (“bang”)命令,它直接从VIM窗口执行shell命令。 此外,它允许启动与pipe道连接并读取标准输出的命令序列。

例如:

 ! 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),并将输出redirect到.tmp.xyz,然后创build一个新选项卡,读取该文件并将其删除。

打破它:

 :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 

对于我使用的Shell脚本

 :set makeprg=% :make 

我通过地图使用了一个稍微更侵入式的机制:

 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中打开你的(任何具有#!解释器的语言脚本)来testing它并运行

 :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”。

我知道这是一个古老的问题,但我希望这可以帮助那里的人。 我一直在参加Coursera的启动工程课程,Palaji教授使用Emacs,而我不喜欢Emacs。

基于@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来执行你的脚本和发球到你的输出文件。

我还将脚本名称添加到输出文件名,以便您可以同时将它用于多个脚本。

@xorpaul

我一直在寻找这个脚本(python/ Windows)很长一段时间。 由于Windows中没有“tee”,我将其更改为:

 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> 

谢谢

.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改变之后,你将再次运行相同的命令,这个函数不会再创build新的窗口,它会在前一个(相同的)分割的窗口中显示结果。