如何在Vi(m)中执行我正在编辑的文件

时间:2009-06-04 22:13:47

标签: vim exec

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

当然我可以这样执行:

:!scriptname

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

13 个答案:

答案 0 :(得分:107)

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

:set makeprg=python\ %

是的,你需要逃离这个空间。在此之后,您只需运行:

:make

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

:set autowrite

这解决了执行部分。不知道如何将该输出转换为不涉及重定向到文件的拆分窗口。

答案 1 :(得分:28)

要访问当前缓冲区的文件名,请使用%。要将其转换为变量,您可以使用expand()函数。要使用新缓冲区打开新窗口,请使用:new:vnew。要将命令的输出传递到当前缓冲区,请使用:.!。把它们放在一起:

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

显然用你想要的任何命令替换ruby。我使用execute所以我可以用引号括起文件名,所以如果文件名中有空格,它就会起作用。

答案 2 :(得分:21)

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

例如:

! node %

相当于打开命令提示符窗口并启动命令:

cd my_current_directory 
node my_current_file

有关详细信息,请参阅"Vim tips: Working with external commands"

答案 3 :(得分:11)

我的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,然后创建一个新选项卡,读取该文件然后将其删除。 / p>

打破它:

: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

答案 4 :(得分:4)

对于Shell脚本,我使用了

:set makeprg=%

:make

答案 5 :(得分:1)

我通过地图使用了一种更具侵入性的机制:

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

只是这样做,所以我没有保存,然后去。去吧。

答案 6 :(得分:1)

您可以使用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 ..

答案 7 :(得分:1)

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.

答案 8 :(得分:0)

基于@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执行脚本和T恤到输出文件。

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

答案 9 :(得分:0)

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

答案 10 :(得分:0)

.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中的更改为例,您将再次运行相同的命令,此函数不会再次创建新窗口,它将在先前(相同)的分割窗口中显示结果。

答案 11 :(得分:0)

只需使用冒号和感叹号,如下所示

:!<脚本名称>

答案 12 :(得分:0)

我建议使用插件quickrun。它配置快速,简单。这是一个小示范: enter image description here