You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
436 lines
15 KiB
VimL
436 lines
15 KiB
VimL
11 years ago
|
"============================================================================
|
||
|
"File: javac.vim
|
||
|
"Description: Syntax checking plugin for syntastic.vim
|
||
|
"Maintainer: Jochen Keil <jochen.keil at gmail dot com>
|
||
|
" Dmitry Geurkov <d.geurkov at gmail dot com>
|
||
|
"License: This program is free software. It comes without any warranty,
|
||
|
" to the extent permitted by applicable law. You can redistribute
|
||
|
" it and/or modify it under the terms of the Do What The Fuck You
|
||
|
" Want To Public License, Version 2, as published by Sam Hocevar.
|
||
|
" See http://sam.zoy.org/wtfpl/COPYING for more details.
|
||
|
"============================================================================
|
||
|
|
||
11 years ago
|
if exists('g:loaded_syntastic_java_javac_checker')
|
||
11 years ago
|
finish
|
||
|
endif
|
||
|
let g:loaded_syntastic_java_javac_checker = 1
|
||
11 years ago
|
let g:syntastic_java_javac_maven_pom_tags = ['build', 'properties']
|
||
11 years ago
|
let g:syntastic_java_javac_maven_pom_properties = {}
|
||
|
let s:has_maven = 0
|
||
|
|
||
|
" Global Options
|
||
11 years ago
|
if !exists('g:syntastic_java_javac_executable')
|
||
11 years ago
|
let g:syntastic_java_javac_executable = 'javac'
|
||
|
endif
|
||
|
|
||
11 years ago
|
if !exists('g:syntastic_java_maven_executable')
|
||
11 years ago
|
let g:syntastic_java_maven_executable = 'mvn'
|
||
|
endif
|
||
|
|
||
11 years ago
|
if !exists('g:syntastic_java_javac_options')
|
||
11 years ago
|
let g:syntastic_java_javac_options = '-Xlint'
|
||
|
endif
|
||
|
|
||
11 years ago
|
if !exists('g:syntastic_java_maven_options')
|
||
|
let g:syntastic_java_maven_options = ''
|
||
|
endif
|
||
|
|
||
|
if !exists('g:syntastic_java_javac_classpath')
|
||
11 years ago
|
let g:syntastic_java_javac_classpath = ''
|
||
|
endif
|
||
|
|
||
11 years ago
|
if !exists('g:syntastic_java_javac_delete_output')
|
||
11 years ago
|
let g:syntastic_java_javac_delete_output = 1
|
||
|
endif
|
||
|
|
||
|
let s:save_cpo = &cpo
|
||
|
set cpo&vim
|
||
|
|
||
|
function! s:CygwinPath(path)
|
||
11 years ago
|
return substitute(system('cygpath -m ' . syntastic#util#shescape(a:path)), "\n", '', 'g')
|
||
11 years ago
|
endfunction
|
||
|
|
||
11 years ago
|
if !exists('g:syntastic_java_javac_temp_dir')
|
||
11 years ago
|
if has('win32') || has('win64')
|
||
11 years ago
|
let g:syntastic_java_javac_temp_dir = $TEMP . syntastic#util#Slash() . 'vim-syntastic-javac'
|
||
11 years ago
|
elseif has('win32unix')
|
||
|
let g:syntastic_java_javac_temp_dir = s:CygwinPath('/tmp/vim-syntastic-javac')
|
||
11 years ago
|
elseif $TMPDIR != ''
|
||
|
let g:syntastic_java_javac_temp_dir = $TMPDIR . '/vim-syntastic-javac'
|
||
11 years ago
|
else
|
||
|
let g:syntastic_java_javac_temp_dir = '/tmp/vim-syntastic-javac'
|
||
|
endif
|
||
|
endif
|
||
|
|
||
11 years ago
|
if !exists('g:syntastic_java_javac_autoload_maven_classpath')
|
||
11 years ago
|
let g:syntastic_java_javac_autoload_maven_classpath = 1
|
||
|
endif
|
||
|
|
||
|
if !exists('g:syntastic_java_javac_config_file_enabled')
|
||
|
let g:syntastic_java_javac_config_file_enabled = 0
|
||
|
endif
|
||
|
|
||
|
if !exists('g:syntastic_java_javac_config_file')
|
||
|
let g:syntastic_java_javac_config_file = '.syntastic_javac_config'
|
||
|
endif
|
||
|
|
||
|
if !exists('g:syntastic_java_javac_custom_classpath_command')
|
||
|
let g:syntastic_java_javac_custom_classpath_command = ''
|
||
|
endif
|
||
|
|
||
11 years ago
|
if !exists('g:syntastic_java_javac_maven_pom_ftime')
|
||
11 years ago
|
let g:syntastic_java_javac_maven_pom_ftime = {}
|
||
|
endif
|
||
|
|
||
11 years ago
|
if !exists('g:syntastic_java_javac_maven_pom_classpath')
|
||
11 years ago
|
let g:syntastic_java_javac_maven_pom_classpath = {}
|
||
|
endif
|
||
|
|
||
|
function! s:RemoveCarriageReturn(line)
|
||
11 years ago
|
return substitute(a:line, "\r", '', 'g')
|
||
11 years ago
|
endfunction
|
||
|
|
||
|
" recursively remove directory and all it's sub-directories
|
||
|
function! s:RemoveDir(dir)
|
||
|
if isdirectory(a:dir)
|
||
|
for f in split(globpath(a:dir, '*'), "\n")
|
||
|
call s:RemoveDir(f)
|
||
|
endfor
|
||
11 years ago
|
silent! call system('rmdir ' . syntastic#util#shescape(a:dir))
|
||
11 years ago
|
else
|
||
|
silent! call delete(a:dir)
|
||
|
endif
|
||
|
endfunction
|
||
|
|
||
11 years ago
|
function! s:ClassSep()
|
||
|
return (syntastic#util#isRunningWindows() || has('win32unix')) ? ';' : ':'
|
||
|
endfunction
|
||
|
|
||
11 years ago
|
function! s:AddToClasspath(classpath, path)
|
||
|
if a:path == ''
|
||
|
return a:classpath
|
||
|
endif
|
||
11 years ago
|
return (a:classpath != '') ? a:classpath . s:ClassSep() . a:path : a:path
|
||
11 years ago
|
endfunction
|
||
|
|
||
|
function! s:SplitClasspath(classpath)
|
||
11 years ago
|
return split(a:classpath, s:ClassSep())
|
||
11 years ago
|
endfunction
|
||
|
|
||
|
function! s:LoadConfigFile()
|
||
11 years ago
|
if filereadable(expand(g:syntastic_java_javac_config_file))
|
||
|
exe 'source ' . fnameescape(expand(g:syntastic_java_javac_config_file))
|
||
11 years ago
|
endif
|
||
|
endfunction
|
||
|
|
||
|
function! s:SaveClasspath()
|
||
|
" build classpath from lines
|
||
|
let path = ''
|
||
|
let lines = getline(1, line('$'))
|
||
|
for l in lines
|
||
|
let path = s:AddToClasspath(path, l)
|
||
|
endfor
|
||
|
" save classpath to config file
|
||
|
if g:syntastic_java_javac_config_file_enabled
|
||
11 years ago
|
if filereadable(expand(g:syntastic_java_javac_config_file))
|
||
11 years ago
|
" load lines from config file
|
||
11 years ago
|
let lines = readfile(expand(g:syntastic_java_javac_config_file))
|
||
11 years ago
|
" strip g:syntastic_java_javac_classpath options from config file lines
|
||
|
let i = 0
|
||
|
while i < len(lines)
|
||
|
if match(lines[i], 'g:syntastic_java_javac_classpath') != -1
|
||
|
call remove(lines, i)
|
||
11 years ago
|
else
|
||
|
let i += 1
|
||
11 years ago
|
endif
|
||
|
endwhile
|
||
|
else
|
||
|
let lines = []
|
||
|
endif
|
||
|
" add new g:syntastic_java_javac_classpath option to config
|
||
11 years ago
|
call add(lines, 'let g:syntastic_java_javac_classpath = ' . string(path))
|
||
11 years ago
|
" save config file lines
|
||
11 years ago
|
call writefile(lines, expand(g:syntastic_java_javac_config_file))
|
||
11 years ago
|
endif
|
||
|
" set new classpath
|
||
|
let g:syntastic_java_javac_classpath = path
|
||
|
let &modified = 0
|
||
|
endfunction
|
||
|
|
||
|
function! s:EditClasspath()
|
||
|
let command = 'syntastic javac classpath'
|
||
|
let winnr = bufwinnr('^' . command . '$')
|
||
|
if winnr < 0
|
||
|
let path = []
|
||
|
let pathlines = split(g:syntastic_java_javac_classpath, "\n")
|
||
|
for p in pathlines
|
||
11 years ago
|
call extend(path, s:SplitClasspath(p))
|
||
11 years ago
|
endfor
|
||
|
execute (len(path) + 5) . 'sp ' . fnameescape(command)
|
||
|
|
||
|
augroup syntastic
|
||
|
autocmd BufWriteCmd <buffer> call s:SaveClasspath() | bwipeout
|
||
|
augroup END
|
||
|
|
||
|
setlocal buftype=acwrite bufhidden=wipe nobuflisted noswapfile nowrap number
|
||
|
for p in path
|
||
|
call append(line('$') - 1, p)
|
||
|
endfor
|
||
|
let &modified = 0
|
||
|
else
|
||
|
execute winnr . 'wincmd w'
|
||
|
endif
|
||
|
endfunction
|
||
|
|
||
|
function! s:SaveConfig()
|
||
|
" get lines
|
||
|
let lines = getline(1, line('$'))
|
||
|
if g:syntastic_java_javac_config_file_enabled
|
||
|
" save config file lines
|
||
11 years ago
|
call writefile(lines, expand(g:syntastic_java_javac_config_file))
|
||
11 years ago
|
endif
|
||
|
let &modified = 0
|
||
|
endfunction
|
||
|
|
||
|
function! s:EditConfig()
|
||
|
let command = 'syntastic javac config'
|
||
|
let winnr = bufwinnr('^' . command . '$')
|
||
|
if winnr < 0
|
||
|
let lines = []
|
||
11 years ago
|
if filereadable(expand(g:syntastic_java_javac_config_file))
|
||
|
let lines = readfile(expand(g:syntastic_java_javac_config_file))
|
||
11 years ago
|
endif
|
||
|
execute (len(lines) + 5) . 'sp ' . fnameescape(command)
|
||
|
|
||
|
augroup syntastic
|
||
|
autocmd BufWriteCmd <buffer> call s:SaveConfig() | bwipeout
|
||
|
augroup END
|
||
|
|
||
|
setlocal ft=vim buftype=acwrite bufhidden=wipe nobuflisted noswapfile nowrap number
|
||
|
for l in lines
|
||
|
call append(line('$') - 1, l)
|
||
|
endfor
|
||
|
let &modified = 0
|
||
|
else
|
||
|
execute winnr . 'wincmd w'
|
||
|
endif
|
||
|
endfunction
|
||
|
|
||
|
function! s:GetMavenProperties()
|
||
|
let mvn_properties = {}
|
||
11 years ago
|
let pom = findfile('pom.xml', '.;')
|
||
11 years ago
|
if s:has_maven && filereadable(pom)
|
||
|
if !has_key(g:syntastic_java_javac_maven_pom_properties, pom)
|
||
11 years ago
|
let mvn_cmd = syntastic#util#shexpand(g:syntastic_java_maven_executable) .
|
||
|
\ ' -f ' . syntastic#util#shescape(pom) .
|
||
|
\ ' ' . g:syntastic_java_maven_options
|
||
11 years ago
|
let mvn_is_managed_tag = 1
|
||
|
let mvn_settings_output = split(system(mvn_cmd . ' help:effective-pom'), "\n")
|
||
|
let current_path = 'project'
|
||
|
for line in mvn_settings_output
|
||
|
let matches = matchlist(line, '\m^\s*<\([a-zA-Z0-9\-\.]\+\)>\s*$')
|
||
|
if mvn_is_managed_tag && !empty(matches)
|
||
|
let mvn_is_managed_tag = index(g:syntastic_java_javac_maven_pom_tags, matches[1]) >= 0
|
||
|
let current_path .= '.' . matches[1]
|
||
|
else
|
||
|
let matches = matchlist(line, '\m^\s*</\([a-zA-Z0-9\-\.]\+\)>\s*$')
|
||
|
if !empty(matches)
|
||
|
let mvn_is_managed_tag = index(g:syntastic_java_javac_maven_pom_tags, matches[1]) < 0
|
||
11 years ago
|
let current_path = substitute(current_path, '\m\.' . matches[1] . '$', '', '')
|
||
11 years ago
|
else
|
||
|
let matches = matchlist(line, '\m^\s*<\([a-zA-Z0-9\-\.]\+\)>\(.\+\)</[a-zA-Z0-9\-\.]\+>\s*$')
|
||
|
if mvn_is_managed_tag && !empty(matches)
|
||
|
let mvn_properties[current_path . '.' . matches[1]] = matches[2]
|
||
|
endif
|
||
|
endif
|
||
|
endif
|
||
|
endfor
|
||
|
let g:syntastic_java_javac_maven_pom_properties[pom] = mvn_properties
|
||
|
endif
|
||
|
return g:syntastic_java_javac_maven_pom_properties[pom]
|
||
|
endif
|
||
|
return mvn_properties
|
||
|
endfunction
|
||
|
|
||
|
command! SyntasticJavacEditClasspath call s:EditClasspath()
|
||
|
|
||
|
if g:syntastic_java_javac_config_file_enabled
|
||
|
command! SyntasticJavacEditConfig call s:EditConfig()
|
||
|
endif
|
||
|
|
||
|
function! s:GetMavenClasspath()
|
||
11 years ago
|
let pom = findfile('pom.xml', '.;')
|
||
11 years ago
|
if s:has_maven && filereadable(pom)
|
||
|
if !has_key(g:syntastic_java_javac_maven_pom_ftime, pom) || g:syntastic_java_javac_maven_pom_ftime[pom] != getftime(pom)
|
||
11 years ago
|
let mvn_cmd = syntastic#util#shexpand(g:syntastic_java_maven_executable) .
|
||
|
\ ' -f ' . syntastic#util#shescape(pom) .
|
||
|
\ ' ' . g:syntastic_java_maven_options
|
||
11 years ago
|
let mvn_classpath_output = split(system(mvn_cmd . ' dependency:build-classpath'), "\n")
|
||
|
let mvn_classpath = ''
|
||
|
let class_path_next = 0
|
||
|
|
||
|
for line in mvn_classpath_output
|
||
|
if class_path_next == 1
|
||
|
let mvn_classpath = s:RemoveCarriageReturn(line)
|
||
|
break
|
||
|
endif
|
||
|
if stridx(line, 'Dependencies classpath:') >= 0
|
||
|
let class_path_next = 1
|
||
|
endif
|
||
|
endfor
|
||
|
|
||
|
let mvn_properties = s:GetMavenProperties()
|
||
|
|
||
|
let output_dir = 'target/classes'
|
||
|
if has_key(mvn_properties, 'project.build.outputDirectory')
|
||
|
let output_dir = mvn_properties['project.build.outputDirectory']
|
||
|
endif
|
||
|
let mvn_classpath = s:AddToClasspath(mvn_classpath, output_dir)
|
||
|
|
||
|
let test_output_dir = 'target/test-classes'
|
||
|
if has_key(mvn_properties, 'project.build.testOutputDirectory')
|
||
|
let test_output_dir = mvn_properties['project.build.testOutputDirectory']
|
||
|
endif
|
||
|
let mvn_classpath = s:AddToClasspath(mvn_classpath, test_output_dir)
|
||
|
|
||
|
let g:syntastic_java_javac_maven_pom_ftime[pom] = getftime(pom)
|
||
|
let g:syntastic_java_javac_maven_pom_classpath[pom] = mvn_classpath
|
||
|
endif
|
||
|
return g:syntastic_java_javac_maven_pom_classpath[pom]
|
||
|
endif
|
||
|
return ''
|
||
|
endfunction
|
||
|
|
||
|
function! SyntaxCheckers_java_javac_IsAvailable() dict
|
||
|
let s:has_maven = executable(expand(g:syntastic_java_maven_executable))
|
||
|
return executable(expand(g:syntastic_java_javac_executable))
|
||
|
endfunction
|
||
|
|
||
|
function! s:MavenOutputDirectory()
|
||
11 years ago
|
let pom = findfile('pom.xml', '.;')
|
||
11 years ago
|
if s:has_maven && filereadable(pom)
|
||
|
let mvn_properties = s:GetMavenProperties()
|
||
|
let output_dir = getcwd()
|
||
|
if has_key(mvn_properties, 'project.properties.build.dir')
|
||
|
let output_dir = mvn_properties['project.properties.build.dir']
|
||
|
endif
|
||
11 years ago
|
if stridx(expand( '%:p:h' ), 'src.main.java') >= 0
|
||
11 years ago
|
let output_dir .= '/target/classes'
|
||
|
if has_key(mvn_properties, 'project.build.outputDirectory')
|
||
|
let output_dir = mvn_properties['project.build.outputDirectory']
|
||
|
endif
|
||
|
endif
|
||
11 years ago
|
if stridx(expand( '%:p:h' ), 'src.test.java') >= 0
|
||
11 years ago
|
let output_dir .= '/target/test-classes'
|
||
|
if has_key(mvn_properties, 'project.build.testOutputDirectory')
|
||
|
let output_dir = mvn_properties['project.build.testOutputDirectory']
|
||
|
endif
|
||
|
endif
|
||
|
|
||
|
if has('win32unix')
|
||
11 years ago
|
let output_dir = s:CygwinPath(output_dir)
|
||
11 years ago
|
endif
|
||
|
return output_dir
|
||
|
endif
|
||
|
return '.'
|
||
|
endfunction
|
||
|
|
||
|
function! SyntaxCheckers_java_javac_GetLocList() dict
|
||
|
let javac_opts = g:syntastic_java_javac_options
|
||
|
|
||
11 years ago
|
let output_dir = ''
|
||
11 years ago
|
if g:syntastic_java_javac_delete_output
|
||
|
let output_dir = g:syntastic_java_javac_temp_dir
|
||
11 years ago
|
let javac_opts .= ' -d ' . syntastic#util#shescape(output_dir)
|
||
11 years ago
|
endif
|
||
|
|
||
|
" load classpath from config file
|
||
|
if g:syntastic_java_javac_config_file_enabled
|
||
|
call s:LoadConfigFile()
|
||
|
endif
|
||
|
|
||
|
let javac_classpath = ''
|
||
|
|
||
|
" add classpathes to javac_classpath
|
||
11 years ago
|
for path in split(g:syntastic_java_javac_classpath, s:ClassSep())
|
||
11 years ago
|
if path != ''
|
||
|
try
|
||
|
let ps = glob(path, 0, 1)
|
||
|
catch
|
||
|
let ps = split(glob(path, 0), "\n")
|
||
|
endtry
|
||
|
if type(ps) == type([])
|
||
|
for p in ps
|
||
|
let javac_classpath = s:AddToClasspath(javac_classpath, p)
|
||
|
endfor
|
||
|
else
|
||
|
let javac_classpath = s:AddToClasspath(javac_classpath, ps)
|
||
|
endif
|
||
|
endif
|
||
|
endfor
|
||
|
|
||
|
if s:has_maven && g:syntastic_java_javac_autoload_maven_classpath
|
||
|
if !g:syntastic_java_javac_delete_output
|
||
11 years ago
|
let javac_opts .= ' -d ' . syntastic#util#shescape(s:MavenOutputDirectory())
|
||
11 years ago
|
endif
|
||
|
let javac_classpath = s:AddToClasspath(javac_classpath, s:GetMavenClasspath())
|
||
|
endif
|
||
|
|
||
|
" load custom classpath
|
||
|
if g:syntastic_java_javac_custom_classpath_command != ''
|
||
|
let lines = system(g:syntastic_java_javac_custom_classpath_command)
|
||
11 years ago
|
if syntastic#util#isRunningWindows() || has('win32unix')
|
||
11 years ago
|
let lines = substitute(lines, "\r\n", "\n", 'g')
|
||
|
endif
|
||
|
for l in split(lines, "\n")
|
||
|
let javac_classpath = s:AddToClasspath(javac_classpath, l)
|
||
|
endfor
|
||
|
endif
|
||
|
|
||
|
if javac_classpath != ''
|
||
11 years ago
|
let javac_opts .= ' -cp ' . syntastic#util#shexpand(javac_classpath)
|
||
11 years ago
|
endif
|
||
|
|
||
11 years ago
|
let fname = expand('%:p:h') . syntastic#util#Slash() . expand ('%:t')
|
||
11 years ago
|
|
||
|
if has('win32unix')
|
||
11 years ago
|
let fname = s:CygwinPath(fname)
|
||
11 years ago
|
endif
|
||
|
|
||
|
let makeprg = self.makeprgBuild({
|
||
|
\ 'args': javac_opts,
|
||
11 years ago
|
\ 'fname': syntastic#util#shescape(fname) })
|
||
11 years ago
|
|
||
|
" unashamedly stolen from *errorformat-javac* (quickfix.txt) and modified to include error types
|
||
|
let errorformat =
|
||
|
\ '%E%f:%l:\ error:\ %m,'.
|
||
|
\ '%W%f:%l:\ warning:\ %m,'.
|
||
|
\ '%A%f:%l:\ %m,'.
|
||
|
\ '%+Z%p^,'.
|
||
|
\ '%+C%.%#,'.
|
||
|
\ '%-G%.%#'
|
||
|
|
||
|
if g:syntastic_java_javac_delete_output
|
||
|
silent! call mkdir(output_dir, 'p')
|
||
|
endif
|
||
|
let errors = SyntasticMake({
|
||
|
\ 'makeprg': makeprg,
|
||
|
\ 'errorformat': errorformat,
|
||
|
\ 'postprocess': ['cygwinRemoveCR'] })
|
||
|
|
||
|
if g:syntastic_java_javac_delete_output
|
||
|
call s:RemoveDir(output_dir)
|
||
|
endif
|
||
|
return errors
|
||
|
|
||
|
endfunction
|
||
|
|
||
|
call g:SyntasticRegistry.CreateAndRegisterChecker({
|
||
|
\ 'filetype': 'java',
|
||
|
\ 'name': 'javac'})
|
||
|
|
||
|
let &cpo = s:save_cpo
|
||
|
unlet s:save_cpo
|
||
|
|
||
|
" vim: set et sts=4 sw=4:
|