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

该 Vim 插件可直接在 Vim 中编译和运行带包的 Java 类,适用于单个 Java 文件或整个项目。插件自动检测项目环境并生成正确的编译参数。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

本插件属于ftplugin,并且依赖于 shellinsidevim.vim

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

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

Java命令同上。


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

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

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


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


  13. " Commands for compiling and executing
  14. let s:Compiler="javac"
  15. let s:Interpretor="java"
  16. let s:Executor=""


  17. " This groups of variables are referencing to the folds that really exists base on the next groups
  18. let s:ProjectRoot=''
  19. let s:SourcePath=''
  20. let s:DistinationPath=''
  21. let s:LibraryPath=''
  22. let s:ArgumentFile=''


  23. " This groups of variables are used to detecting the environment
  24. if !exists("g:Java_Sources")
  25.     let g:Java_Sources="src:java_src"
  26. endif
  27. if !exists("g:Java_Distinations")
  28.     let g:Java_Distinations="classes:java_classes"
  29. endif
  30. if !exists("g:Java_Libraries")
  31.     let g:Java_Libraries="lib:java_lib"
  32. endif
  33. if !exists("g:Java_ArgumentFiles")
  34.     let g:Java_ArgumentFiles="classpath.javac:argument.javac:source.javac"
  35. endif


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


  39. " Map keys to function calls
  40. map <unique> <buffer> <F5> :call <SID>Compile()<CR>
  41. map <unique> <buffer> <M-F5> :Javac 
  42. map <unique> <buffer> <F6> :call <SID>Execute()<CR>
  43. map <unique> <buffer> <M-F6> :Java 
  44. map <unique> <buffer> <F9> :call <SID>ToggleExecutor()<CR>


  45. imap <unique> <buffer> <F5> <ESC><F5>
  46. imap <unique> <buffer> <M-F5> <ESC><M-F5>
  47. imap <unique> <buffer> <F6> <ESC><F6>
  48. imap <unique> <buffer> <M-F6> <ESC><M-F6>
  49. imap <unique> <buffer> <F9> <ESC><F9>


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

  52.     let cprt=s:ProjectRoot
  53.     let s:Executor=s:GetFullClassName()
  54.     let tail='/'.substitute(s:Executor,'/.','/','g')
  55.     let src=fnamemodify(bufname("%"),":p:r")
  56.     if (match(src,tail) + strlen(tail))==strlen(src)
  57.         let src=substitute(src,tail,'','g')
  58.     else
  59.         call g:EchoErrorMsg("This class has an incorrect package!")
  60.     endif
  61.     let s:ProjectRoot=src

  62.     let isProject=0
  63.     let srcs=split(g:Java_Sources,":")
  64.     let dists=split(g:Java_Distinations,":")
  65.     while src!=fnamemodify(src,":h")
  66.         for sd in srcs
  67.             if (strlen(sd)+match(src,sd))==strlen(src)
  68.                 let root=substitute(src,"/".sd,"","g")
  69.                 for did in dists
  70.                     let dist=fnamemodify(root."/".did,":p")
  71.                     let csrc=fnamemodify(root."/".sd,":p")
  72.                     if isdirectory(dist) && isdirectory(sd)
  73.                         let s:ProjectRoot=root
  74.                         let s:DistinationPath=dist
  75.                         let isProject=1
  76.                         break
  77.                     endif
  78.                 endfor
  79.                 if isProject==1 | break | endif
  80.             endif
  81.         endfor
  82.         if isProject==1 | break | endif
  83.         let src=fnamemodify(src,":h")
  84.     endwhile

  85.     if isProject==1
  86.         let s:SourcePath=s:PreparePath(g:Java_Sources,0)
  87.         let s:LibraryPath=s:PreparePath(g:Java_Libraries,0)
  88.         let s:ArgumentFile=s:PreparePath(g:Java_ArgumentFiles,1)
  89.     else
  90.         let s:DistinationPath=s:ProjectRoot
  91.         let s:LibraryPath=s:ProjectRoot
  92.     endif

  93.     if cprt!=s:ProjectRoot
  94.         call g:EchoMoreMsg("The project root is ".s:ProjectRoot)
  95.         if cprt!=''
  96.             call g:EchoWarningMsg("This project is not the original one!")
  97.         endif
  98.     endif
  99. endfunction


  100. function! s:ToggleExecutor()
  101.     if s:IsJavaFile()==0 | return 0 | endif
  102.     
  103.     let cer=s:Executor
  104.     call s:InitEnvironment()
  105.     if s:Executor==cer
  106.         call g:EchoWarningMsg(s:Executor.' is no longer the executor.')
  107.         let s:Executor=""
  108.     else
  109.         call g:EchoMoreMsg(s:Executor.' is set as the executor.')
  110.         let main="//s*//(//(public//|static//)//s//+//)//{2}void//s//+main(String"
  111.         let para1=main."//(//(//s*//(//.//{3}//|[]//)//s*//)//w//+//s*//))"
  112.         let para2=main."//(//s//+//w//+//s*[]//s*//))"
  113.         if search(para1)+search(para2)==0
  114.             call g:EchoWarningMsg(s:Executor.' does not have the main method!')
  115.         endif
  116.     endif
  117. endfunction


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

  122.     let argfiles=s:GetArgumentFiles(s:ArgumentFile)
  123.     if strlen(argfiles)>0
  124.         call g:ExecuteCommand(&makeprg,argfiles,";")
  125.     else
  126.         call s:InitEnvironment()
  127.         let dist=substitute(s:DistinationOption,"DO",s:DistinationPath,"")
  128.         let cp=substitute(s:LibraryOption,"LO",s:GetClassPath(s:LibraryPath,s:DistinationPath),"")
  129.         let sp=substitute(s:SourcepathOption,"SO",s:SourcePath,"")
  130.         call g:ExecuteCommand(&makeprg,dist,cp,sp,s:ExtraCompileOptions,bufname("%"),";")
  131.     endif
  132. endfunction


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

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


  141. function! s:CLCompile(...)
  142.     let index=1
  143.     let eoption=""
  144.     while index<=a:0
  145.         execute 'let eoption=eoption." ".g:Trim(a:'.index.')'
  146.         let index=index+1
  147.     endwhile
  148.     if match(eoption,"^ :")==-1
  149.         let s:ExtraCompileOptions=s:ExtraCompileOptions.eoption
  150.     else
  151.         let s:ExtraCompileOptions=strpart(eoption,2)
  152.     endif
  153.     call s:Compile()
  154. endfunction


  155. function! s:CLExecute(...)
  156.     let index=1
  157.     let eoption=""
  158.     while index<=a:0
  159.         execute 'let eoption=eoption." ".g:Trim(a:'.index.')'
  160.         let index=index+1
  161.     endwhile
  162.     if match(eoption,"^ :")==-1
  163.         let s:ExtraExecuteOptions=s:ExtraExecuteOptions.eoption
  164.     else
  165.         let s:ExtraExecuteOptions=strpart(eoption,2)
  166.     endif
  167.     call s:Execute()
  168. endfunction

  1. " Other useful functions
  2. function! s:PreparePath(srcs,isfile)
  3.     let result=""
  4.     for src in split(a:srcs,":")
  5.         let source=s:ProjectRoot."/".src
  6.         if (a:isfile==0 && isdirectory(source)) || (a:isfile==1 && filereadable(source))
  7.             let result=s:AddPathTo(result,source,":","after")
  8.         endif
  9.     endfor
  10.     return result
  11. endfunction

  12. function! s:AddPathTo(src,dir,sep,pos)
  13.     let path=s:CleanPath(a:dir)
  14.     if a:src==""
  15.         return path
  16.     elseif match(a:src,path)>=0
  17.         return s:src
  18.     else
  19.         if a:pos=='after'
  20.             return a:src.a:sep.path
  21.         else
  22.             return path.a:sep.a:src
  23.         endif
  24.     endif
  25. endfunction

  26. function! s:CleanPath(path)
  27.     let paths=split(fnamemodify(a:path,":p"),"/")
  28.     let result=[]
  29.     let n=len(paths)-1
  30.     let skip=0
  31.     while n>=0
  32.         if paths[n]==".."
  33.             let skip=skip+1
  34.         elseif skip==0
  35.             call insert(result,paths[n],0)
  36.         else
  37.             let skip=skip-1
  38.         endif
  39.         let n=n-1
  40.     endwhile
  41.     let path="/".join(result,"/")
  42.     if match(path," ")>0
  43.         let path='"'.path.'"'
  44.     endif
  45.     return path
  46. endfunction

  47. function! s:IsJavaFile()
  48.     let filename=bufname("%")
  49.     if fnamemodify(filename,":e")!="java"
  50.         call s:EchoWarningMsg(filename." is not the expect one!")
  51.         return 0
  52.     endif
  53.     return 1
  54. endfunction

  55. function! s:GetPackage()
  56.     let cur=getpos(".")
  57.     let package=""
  58.     call setpos(".",[0,1,1,0])
  59.     let line=search('package','')
  60.     if line>0
  61.         try
  62.             let package=split(split(getline(line))[1],';')[0]
  63.         catch /.*/
  64.             call g:EchoErrorMsg("The package definition may incorrect!")
  65.         endtry
  66.     endif
  67.     call setpos(".",cur)
  68.     return package
  69. endfunction

  70. function! s:GetFullClassName()
  71.     if s:IsJavaFile()==0 | return "" | endif
  72.     let package=s:GetPackage()
  73.     let class=fnamemodify(bufname("%"),":t:r")
  74.     if strlen(package)>0
  75.         return package.'.'.class
  76.     else
  77.         return class
  78.     endif
  79. endfunction

  80. function! s:GetClassPath(libraries,distination)
  81.     let classpath=substitute($CLASSPATH,"//.///:","","g")
  82.     let libffixes=['jar','JAR','zip','ZIP']
  83.     for lib in split(a:libraries,":")
  84.         for suffix in libffixes
  85.             let findlib=substitute(glob(lib."/*".suffix),"/n",":","g")
  86.             if strlen(findlib)>0
  87.                 let classpath=s:AddPathTo(classpath,findlib,":","before")
  88.             endif
  89.         endfor
  90.     endfor
  91.     return s:AddPathTo(classpath,a:distination,":","before")
  92. endfunction

  93. function! s:GetArgumentFiles(ArgumentFile)
  94.     let argfiles=""
  95.     for af in split(a:ArgumentFile,":")
  96.         let argfiles=argfiles." ".substitute(s:ArgumentFileOption,"AFO",af,"g")
  97.     endfor
  98.     return argfiles
  99. endfunction
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值