如何执行我正在Vi(m)中编辑的文件并在拆分窗口中获取输出(如在SciTE中)?
当然,我可以像这样执行它:
:!scriptname
但是是否可以避免编写脚本名称以及如何在拆分窗口而不是屏幕底部获取输出呢?
:!"%:p"
应付空白。
如何执行我正在Vi(m)中编辑的文件并在拆分窗口中获取输出(如在SciTE中)?
当然,我可以像这样执行它:
:!scriptname
但是是否可以避免编写脚本名称以及如何在拆分窗口而不是屏幕底部获取输出呢?
:!"%:p"
应付空白。
Answers:
有make
命令。它运行makeprg
选项中的命令集。使用%
作为当前文件名的占位符。例如,如果您正在编辑python脚本:
:set makeprg=python\ %
是的,您需要逃脱空间。之后,您可以简单地运行:
:make
如果需要,可以设置该autowrite
选项,它将在运行以下命令之前自动保存makeprg
:
:set autowrite
这解决了执行部分。不知道有什么方法可以将输出输出到不涉及文件重定向的拆分窗口中。
:copen
开放运行产生的“错误列表” :make
。在自己的窗口。不幸的是,要使输出正确格式化,errorformat
必须对选项进行一些调整。否则,将假定输出为gcc输出的格式。
:let f=expand("%")|vnew|execute '.!ruby "' . f . '"'
尽管布莱恩·卡珀(Brian Carper)的解决方案()看起来很神秘,但其功能完全符合问题作者的要求。
要访问当前缓冲区的文件名,请使用%
。要将其放入变量中,可以使用expand()
函数。要使用新缓冲区打开新窗口,请使用:new
或:vnew
。要将命令的输出通过管道传输到当前缓冲区,请使用:.!
。放在一起:
:let f=expand("%")|vnew|execute '.!ruby "' . f . '"'
显然替换ruby
为您想要的任何命令。我使用过,execute
所以我可以用引号将文件名引起来,因此如果文件名中有空格,它将可以使用。
:command! R let f=expand("%")|vnew|execute '.!ruby "' . f . '"'
它可以:R
执行命令
Vim具有!
(“ bang”)命令,可直接从VIM窗口执行shell命令。此外,它允许启动与管道连接并读取标准输出的命令序列。
例如:
! node %
相当于打开命令提示符窗口并启动命令:
cd my_current_directory
node my_current_file
有关详细信息,请参见“视频提示:使用外部命令”。
我在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都重定向到temp文件,并且在这样做之前,它将所有内容打印到stdout,因此,如果脚本需要很长时间才能运行,您实际上会看到它正在工作。另外,它与目录无关(按绝对路径打开文件时出现错误)。但是,它不会以交互方式运行脚本,而且我还没有找到一种方法来做到这一点。
我通过地图使用一种更具侵入性的机制:
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”。
我知道这是一个老问题,但是我希望这可以帮助某个人。我参加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执行脚本并进入输出文件。
我还将脚本名称添加到了输出文件名中,以便您可以同时将其用于多个脚本。
在您.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中没有“ 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>