您的位置:首页 > 编程语言 > Java开发

VIM:简化的单语言项目脚本──对Java项目开发的支持

2009-01-02 16:56 513 查看
本插件属于ftplugin,并且依赖于shellinsidevim.vim

本插件使得你可以直接在vim编译和运行带有包的java类,并且如果改类属于一个java项目,它会自动检测项目环境(不要求你一定位于项目文件夹下),并且生成正确的编译参数。这些参数包括:classpath、sourcepath、输出目录、参数文件。以上参数的意义请自行参考javac文档。

如果上述参数不够,你可以直接在命令模式输入:Javac ,后跟参数。注意,这个参数是对上述的补充,你不用在额外指定上述参数。并且,每次输入的参数都将自动保存,直到重启vim或者在Javac命令后输入“:”再接参数。

Java命令同上。

此脚本可以方便的修改,使得应用于其他的语言环境,比如flex。

此插件的功能比较简单,更强大的脚本还在测试中。

"Vim global plugin for running java project
" Version: 2.0
" Maintainer: WarGrey <yoshua@gmail.com>
" Last change: 2008 Dec 22
"

" This groups of variables are used to generating the options for compiling
let s:LibraryOption="-classpath LO"
let s:SourcepathOption="-sourcepath SO"
let s:DistinationOption="-d DO"
let s:ArgumentFileOption="@AFO"
let s:ExtraCompileOptions=""
let s:ExtraExecuteOptions=""

" Commands for compiling and executing
let s:Compiler="javac"
let s:Interpretor="java"
let s:Executor=""

" This groups of variables are referencing to the folds that really exists base on the next groups
let s:ProjectRoot=''
let s:SourcePath=''
let s:DistinationPath=''
let s:LibraryPath=''
let s:ArgumentFile=''

" This groups of variables are used to detecting the environment
if !exists("g:Java_Sources")
let g:Java_Sources="src:java_src"
endif
if !exists("g:Java_Distinations")
let g:Java_Distinations="classes:java_classes"
endif
if !exists("g:Java_Libraries")
let g:Java_Libraries="lib:java_lib"
endif
if !exists("g:Java_ArgumentFiles")
let g:Java_ArgumentFiles="classpath.javac:argument.javac:source.javac"
endif

" Ex command which take 0 or more ( up to 20 ) parameters
command! -complete=file -nargs=* Javac call s:CLCompile(<f-args>)
command! -complete=file -nargs=* Java call s:CLExecute(<f-args>)

" Map keys to function calls
map <unique> <buffer> <F5> :call <SID>Compile()<CR>
map <unique> <buffer> <M-F5> :Javac
map <unique> <buffer> <F6> :call <SID>Execute()<CR>
map <unique> <buffer> <M-F6> :Java
map <unique> <buffer> <F9> :call <SID>ToggleExecutor()<CR>

imap <unique> <buffer> <F5> <ESC><F5>
imap <unique> <buffer> <M-F5> <ESC><M-F5>
imap <unique> <buffer> <F6> <ESC><F6>
imap <unique> <buffer> <M-F6> <ESC><M-F6>
imap <unique> <buffer> <F9> <ESC><F9>

function! s:InitEnvironment()
if s:IsJavaFile()==0 | return 0 | endif

let cprt=s:ProjectRoot
let s:Executor=s:GetFullClassName()
let tail='/'.substitute(s:Executor,'/.','/','g')
let src=fnamemodify(bufname("%"),":p:r")
if (match(src,tail) + strlen(tail))==strlen(src)
let src=substitute(src,tail,'','g')
else
call g:EchoErrorMsg("This class has an incorrect package!")
endif
let s:ProjectRoot=src

let isProject=0
let srcs=split(g:Java_Sources,":")
let dists=split(g:Java_Distinations,":")
while src!=fnamemodify(src,":h")
for sd in srcs
if (strlen(sd)+match(src,sd))==strlen(src)
let root=substitute(src,"/".sd,"","g")
for did in dists
let dist=fnamemodify(root."/".did,":p")
let csrc=fnamemodify(root."/".sd,":p")
if isdirectory(dist) && isdirectory(sd)

let s:ProjectRoot=root
let s:DistinationPath=dist
let isProject=1
break
endif
endfor
if isProject==1 | break | endif
endif
endfor
if isProject==1 | break | endif
let src=fnamemodify(src,":h")
endwhile

if isProject==1
let s:SourcePath=s:PreparePath(g:Java_Sources,0)
let s:LibraryPath=s:PreparePath(g:Java_Libraries,0)
let s:ArgumentFile=s:PreparePath(g:Java_ArgumentFiles,1)
else
let s:DistinationPath=s:ProjectRoot
let s:LibraryPath=s:ProjectRoot
endif

if cprt!=s:ProjectRoot
call g:EchoMoreMsg("The project root is ".s:ProjectRoot)
if cprt!=''
call g:EchoWarningMsg("This project is not the original one!")
endif
endif
endfunction

function! s:ToggleExecutor()
if s:IsJavaFile()==0 | return 0 | endif

let cer=s:Executor
call s:InitEnvironment()
if s:Executor==cer
call g:EchoWarningMsg(s:Executor.' is no longer the executor.')
let s:Executor=""
else
call g:EchoMoreMsg(s:Executor.' is set as the executor.')
let main="//s*//(//(public//|static//)//s//+//)//{2}void//s//+main(String"
let para1=main."//(//(//s*//(//.//{3}//|[]//)//s*//)//w//+//s*//))"
let para2=main."//(//s//+//w//+//s*[]//s*//))"
if search(para1)+search(para2)==0
call g:EchoWarningMsg(s:Executor.' does not have the main method!')
endif
endif
endfunction

function! s:Compile()
wall
echo "All open files are saved."
execute "compiler! ".s:Compiler

let argfiles=s:GetArgumentFiles(s:ArgumentFile)
if strlen(argfiles)>0
call g:ExecuteCommand(&makeprg,argfiles,";")
else
call s:InitEnvironment()
let dist=substitute(s:DistinationOption,"DO",s:DistinationPath,"")
let cp=substitute(s:LibraryOption,"LO",s:GetClassPath(s:LibraryPath,s:DistinationPath),"")
let sp=substitute(s:SourcepathOption,"SO",s:SourcePath,"")
call g:ExecuteCommand(&makeprg,dist,cp,sp,s:ExtraCompileOptions,bufname("%"),";")
endif
endfunction

function! s:Execute()
if s:Executor=="" | call s:ToggleExecutor() | endif

let cp=substitute(s:LibraryOption,"LO",s:GetClassPath(s:LibraryPath,s:DistinationPath),"g")
if !filereadable(g:VIM_STD_IN_FILE)
call writefile([""],g:VIM_STD_IN_FILE)
endif
call g:ExecuteCommand(">",s:Interpretor,cp,s:ExtraExecuteOptions,s:Executor)
endfunction

function! s:CLCompile(...)
let index=1
let eoption=""
while index<=a:0
execute 'let eoption=eoption." ".g:Trim(a:'.index.')'
let index=index+1
endwhile
if match(eoption,"^ :")==-1
let s:ExtraCompileOptions=s:ExtraCompileOptions.eoption
else
let s:ExtraCompileOptions=strpart(eoption,2)
endif
call s:Compile()
endfunction

function! s:CLExecute(...)
let index=1
let eoption=""
while index<=a:0
execute 'let eoption=eoption." ".g:Trim(a:'.index.')'
let index=index+1
endwhile
if match(eoption,"^ :")==-1
let s:ExtraExecuteOptions=s:ExtraExecuteOptions.eoption
else
let s:ExtraExecuteOptions=strpart(eoption,2)
endif
call s:Execute()
endfunction

" Other useful functions
function! s:PreparePath(srcs,isfile)
let result=""
for src in split(a:srcs,":")
let source=s:ProjectRoot."/".src
if (a:isfile==0 && isdirectory(source)) || (a:isfile==1 && filereadable(source))
let result=s:AddPathTo(result,source,":","after")
endif
endfor
return result
endfunction

function! s:AddPathTo(src,dir,sep,pos)
let path=s:CleanPath(a:dir)
if a:src==""
return path
elseif match(a:src,path)>=0
return s:src
else
if a:pos=='after'
return a:src.a:sep.path
else
return path.a:sep.a:src
endif
endif
endfunction

function! s:CleanPath(path)
let paths=split(fnamemodify(a:path,":p"),"/")
let result=[]
let n=len(paths)-1
let skip=0
while n>=0
if paths
==".."
let skip=skip+1
elseif skip==0
call insert(result,paths
,0)
else
let skip=skip-1
endif
let n=n-1
endwhile
let path="/".join(result,"/")
if match(path," ")>0
let path='"'.path.'"'
endif
return path
endfunction

function! s:IsJavaFile()
let filename=bufname("%")
if fnamemodify(filename,":e")!="java"
call s:EchoWarningMsg(filename." is not the expect one!")
return 0
endif
return 1
endfunction

function! s:GetPackage()
let cur=getpos(".")
let package=""
call setpos(".",[0,1,1,0])
let line=search('package','')
if line>0
try
let package=split(split(getline(line))[1],';')[0]
catch /.*/
call g:EchoErrorMsg("The package definition may incorrect!")
endtry
endif
call setpos(".",cur)
return package
endfunction

function! s:GetFullClassName()
if s:IsJavaFile()==0 | return "" | endif

let package=s:GetPackage()
let class=fnamemodify(bufname("%"),":t:r")
if strlen(package)>0
return package.'.'.class
else
return class
endif
endfunction

function! s:GetClassPath(libraries,distination)
let classpath=substitute($CLASSPATH,"//.///:","","g")
let libffixes=['jar','JAR','zip','ZIP']
for lib in split(a:libraries,":")
for suffix in libffixes
let findlib=substitute(glob(lib."/*".suffix),"/n",":","g")
if strlen(findlib)>0
let classpath=s:AddPathTo(classpath,findlib,":","before")
endif
endfor
endfor
return s:AddPathTo(classpath,a:distination,":","before")
endfunction

function! s:GetArgumentFiles(ArgumentFile)
let argfiles=""
for af in split(a:ArgumentFile,":")
let argfiles=argfiles." ".substitute(s:ArgumentFileOption,"AFO",af,"g")
endfor
return argfiles
endfunction
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: