现在的位置: 首页 > 综合 > 正文

VIM2:在VIM中添加一键编译和一键运行

2018年03月18日 ⁄ 综合 ⁄ 共 3987字 ⁄ 字号 评论关闭

事先声明,此处使用的VIM完全是基于终端的,而不是gvim或vim-x11。因为后两者不具有平台移植性,花哨的目录和鼠标点击并非必须。

在vim中编程,退出来再敲命令编译是一件痛苦的事情。如果能够像VC那样一键编译和一键运行就爽了。
事实上,在vim中实现这种功能并不困难,所需要的只是在配置文件~/.vimrc(ubuntu12.04中是/etc/vin/vimrc中加一些过程,然后将这些过程与某些快捷键进行绑定即可。
第一步,写编译函数。
事实上,vim的配置脚本完全可以称得上一门语言,因此定制一些功能是完全没问题的。

 

func! CompileGcc()
    exec "w"
    let compilecmd="!gcc "
    let compileflag="-o %< "
    if search("mpi/.h") != 0
        let compilecmd = "!mpicc "
    endif
    if search("glut/.h") != 0
        let compileflag .= " -lglut -lGLU -lGL "
    endif
    if search("cv/.h") != 0
        let compileflag .= " -lcv -lhighgui -lcvaux "
    endif
    if search("omp/.h") != 0
        let compileflag .= " -fopenmp "
    endif
    if search("math/.h") != 0
        let compileflag .= " -lm "
    endif
    exec compilecmd." % ".compileflag
endfunc
func! CompileGpp()
    exec "w"
    let compilecmd="!g++ "
    let compileflag="-o %< "
    if search("mpi/.h") != 0
        let compilecmd = "!mpic++ "
    endif
    if search("glut/.h") != 0
        let compileflag .= " -lglut -lGLU -lGL "
    endif
    if search("cv/.h") != 0
        let compileflag .= " -lcv -lhighgui -lcvaux "
    endif
    if search("omp/.h") != 0
        let compileflag .= " -fopenmp "
    endif
    if search("math/.h") != 0
        let compileflag .= " -lm "
    endif
    exec compilecmd." % ".compileflag
endfunc

 

这样就定义两个函数,分别编译C和C++,其含义应该是比较明显的了。注意,这里用到的两个变量compilecmd和compileflag都是局部变量。search函数用来搜索字符串,我根据源码的头文件来判断编译所需要的库。连接两个字符串的运行符是一个句点。%为内部变量,表示文件名,而%<表示没有后缀的文件名。
上面的函数只是定义了C/C++语言的编译,如果需要编译其它语言,则也需要编写对应的函数。而把这些不同语言的函数组合到一起则还需要另外一个函数。
第二步,组合成一个函数

func! CompileCode()
        exec "w"
        if &filetype == "cpp"
                exec "call CompileGpp()"
        elseif &filetype == "c"
                exec "call CompileGcc()"
        endif
endfunc

该函数根据文件类别来选定不同的编译函数。&filetype是一个内部变量,前缀&起标识内部变量的作用。
filetype不光是cpp和c,还可以是python,java等等。
第三步,键绑定

map <F5> :call CompileCode()<CR>
imap <F5> <ESC>:call CompileCode()<CR>
vmap <F5> <ESC>:call CompileCode()<CR>

 

这里绑定了三次,分别对应普通模式,插入模式和可视模式。显然<ESC>起到的作用是从这些模式中退出来,而<CR>表示carriage return,即敲命令时的回车。
现在,大功告成了,你只需要按F5键,源码就会自动保存,然后进行编译。运行可执行文件做法也是一样的。
下面贴出我的完整的解决方案,除了C/C++,还涉及到java和python。并且按F6就能执行编译生成的可执行文件。

func! CompileGcc()
    exec "w"
    let compilecmd="!gcc "
    let compileflag="-o %< "
    if search("mpi/.h") != 0
        let compilecmd = "!mpicc "
    endif
    if search("glut/.h") != 0
        let compileflag .= " -lglut -lGLU -lGL "
    endif
    if search("cv/.h") != 0
        let compileflag .= " -lcv -lhighgui -lcvaux "
    endif
    if search("omp/.h") != 0
        let compileflag .= " -fopenmp "
    endif
    if search("math/.h") != 0
        let compileflag .= " -lm "
    endif
    exec compilecmd." % ".compileflag
endfunc
func! CompileGpp()
    exec "w"
    let compilecmd="!g++ "
    let compileflag="-o %< "
    if search("mpi/.h") != 0
        let compilecmd = "!mpic++ "
    endif
    if search("glut/.h") != 0
        let compileflag .= " -lglut -lGLU -lGL "
    endif
    if search("cv/.h") != 0
        let compileflag .= " -lcv -lhighgui -lcvaux "
    endif
    if search("omp/.h") != 0
        let compileflag .= " -fopenmp "
    endif
    if search("math/.h") != 0
        let compileflag .= " -lm "
    endif
    exec compilecmd." % ".compileflag
endfunc

func! RunPython()
        exec "!python %"
endfunc
func! CompileJava()
    exec "!javac %"
endfunc

func! CompileCode()
        exec "w"
        if &filetype == "cpp"
                exec "call CompileGpp()"
        elseif &filetype == "c"
                exec "call CompileGcc()"
        elseif &filetype == "python"
                exec "call RunPython()"
        elseif &filetype == "java"
                exec "call CompileJava()"
        endif
endfunc

func! RunResult()
        exec "w"
        if search("mpi/.h") != 0
            exec "!mpirun -np 4 ./%<"
        elseif &filetype == "cpp"
            exec "! ./%<"
        elseif &filetype == "c"
            exec "! ./%<"
        elseif &filetype == "python"
            exec "call RunPython"
        elseif &filetype == "java"
            exec "!java %<"
        endif
endfunc

map <F5> :call CompileCode()<CR>
imap <F5> <ESC>:call CompileCode()<CR>
vmap <F5> <ESC>:call CompileCode()<CR>

map <F6> :call RunResult()<CR>

抱歉!评论已关闭.