1
0
mirror of https://github.com/SpaceVim/SpaceVim.git synced 2025-02-03 09:50:04 +08:00
SpaceVim/bundle/vim-javacomplete2/autoload/javacomplete/server.vim
2022-11-02 00:34:34 +08:00

426 lines
13 KiB
VimL
Vendored

" Vim completion script for java
" Maintainer: artur shaik <ashaihullin@gmail.com>
"
" Java server bridge initiator and caller
let s:serverStartBlocked = 0
let s:autoRecompileCheckFlag = 0
function! s:Log(log)
let log = type(a:log) == type("") ? a:log : string(a:log)
call javacomplete#logger#Log("[server] ". log)
endfunction
function! javacomplete#server#BlockStart()
let s:serverStartBlocked = 1
endfunction
function! javacomplete#server#UnblockStart()
let s:serverStartBlocked = 0
endfunction
function! s:System(cmd, caller)
let t = reltime()
let res = system(a:cmd)
call s:Log(reltimestr(reltime(t)) . 's to exec "' . a:cmd . '" by ' . a:caller)
return res
endfunction
function! s:Poll()
let value = 0
JavacompletePy << EOPC
try:
vim.command("let value = '%d'" % bridgeState.poll())
except:
# we'll get here if the bridgeState variable was not defined or if it's None.
# In this case we stop the processing and return the default 0 value.
pass
EOPC
return value
endfunction
function! javacomplete#server#Terminate()
if s:Poll()
JavacompletePy bridgeState.terminateServer()
let pid = 0
JavacompletePy vim.command('let pid = %d' % bridgeState.pid())
if pid > 1
if g:JavaComplete_IsWindows
call system('taskkill /t /pid '. pid)
else
call system('kill '. (pid + 1))
endif
endif
endif
endfunction
function! s:ControlServerAppVersion()
let classpath =
\ s:GetJavaviClassPath(). g:PATH_SEP.
\ s:GetJavaviDeps(). g:PATH_SEP
let s:serverVersionOutput = []
call javacomplete#util#RunSystem(join(
\ [
\ javacomplete#server#GetJVMLauncher(), '-cp', classpath,
\ 'kg.ash.javavi.Javavi -version'
\ ]),
\ 'Javavi server version check',
\ 'javacomplete#server#CheckServerAccordance')
endfunction
function! javacomplete#server#CheckServerAccordance(data, event)
if a:event == 'exit'
if a:data == '0'
let serverVersion = join(s:serverVersionOutput)
if !javacomplete#version#CheckServerCompatibility(serverVersion)
call s:Log("server ". serverVersion. " is outdated, recompile")
call javacomplete#server#Compile()
endif
endif
unlet s:serverVersionOutput
elseif a:event == 'stdout'
call extend(s:serverVersionOutput, a:data)
endif
endfunction
function! javacomplete#server#Start()
if s:Poll() == 0 && s:serverStartBlocked == 0
if get(g:, 'JavaComplete_CheckServerVersionAtStartup', 1)
call s:ControlServerAppVersion()
endif
JavacompletePy import vim
let file = g:JavaComplete_Home. g:FILE_SEP. "autoload". g:FILE_SEP. "javavibridge.py"
call s:Log("executing python file: " . file)
execute "JavacompletePyfile ". file
let javaProps = []
if exists('g:JavaComplete_JavaviLogLevel')
call add(javaProps, '-Dlog.level='. g:JavaComplete_JavaviLogLevel)
endif
if !empty(g:JavaComplete_JavaviLogDirectory)
call add(javaProps, '-Dlog.directory='. g:JavaComplete_JavaviLogDirectory)
endif
JavacompletePy vim.command('let port = "%s"' % SERVER[1])
call add(javaProps, '-Ddaemon.port='. port)
let log4j2Config = join([g:JavaComplete_Home,'libs', 'javavi', 'target', 'classes', 'log4j2.xml'], g:FILE_SEP)
call add(javaProps, '-Dlog4j.configurationFile='. log4j2Config)
let classpath = substitute(javacomplete#server#GetClassPath(), '\\', '\\\\', 'g')
let sources = []
if exists('g:JavaComplete_SourcesPath')
let sources += ['-sources', s:ExpandAllPaths(g:JavaComplete_SourcesPath)]
endif
let args = javaProps + ['kg.ash.javavi.Javavi'] + sources
if g:JavaComplete_ServerAutoShutdownTime > 0
let args += ['-t', g:JavaComplete_ServerAutoShutdownTime]
endif
let args += ['-base', javacomplete#util#GetBase('')]
let args += ['-compiler', javacomplete#server#GetCompiler()]
if !empty(g:JavaComplete_ProjectKey)
let args += ['-project', g:JavaComplete_ProjectKey]
endif
call s:Log("server classpath: -cp ". classpath)
call s:Log("server arguments:". join(args, ' '))
JavacompletePy bridgeState = JavaviBridge()
JavacompletePy bridgeState.setupServer(vim.eval('javacomplete#server#GetJVMLauncher()'), vim.eval('args'), vim.eval('classpath'))
endif
endfunction
function! javacomplete#server#ShowPort()
if s:Poll()
JavacompletePy vim.command('echo "Javavi port: %d"' % bridgeState.port())
endif
endfunction
function! javacomplete#server#ShowPID()
if s:Poll()
JavacompletePy vim.command('echo "Javavi pid: %d"' % bridgeState.pid())
endif
endfunction
function! javacomplete#server#GetCompiler()
return exists('g:JavaComplete_JavaCompiler') && g:JavaComplete_JavaCompiler !~ '^\s*$' ? g:JavaComplete_JavaCompiler : 'javac'
endfunction
function! javacomplete#server#SetCompiler(compiler)
let g:JavaComplete_JavaCompiler = a:compiler
endfunction
function! javacomplete#server#GetJVMLauncher()
return exists('g:JavaComplete_JvmLauncher') && g:JavaComplete_JvmLauncher !~ '^\s*$' ? g:JavaComplete_JvmLauncher : 'java'
endfunction
function! javacomplete#server#SetJVMLauncher(interpreter)
if javacomplete#server#GetJVMLauncher() != a:interpreter
let g:JavaComplete_Cache = {}
endif
let g:JavaComplete_JvmLauncher = a:interpreter
endfunction
function! javacomplete#server#CompilationJobHandler(data, event)
if a:event == 'exit'
if a:data == "0"
JCserverStart
echo 'Javavi compilation finished '
else
echo 'Failed to compile javavi server'
endif
let s:compilationIsRunning = 0
elseif a:event == 'stderr'
echomsg join(a:data)
elseif a:event == 'stdout'
if g:JavaComplete_ShowExternalCommandsOutput
echomsg join(a:data)
endif
endif
endfunction
function! javacomplete#server#Compile()
call javacomplete#server#Terminate()
let javaviDir = g:JavaComplete_Home. g:FILE_SEP. join(['libs', 'javavi'], g:FILE_SEP). g:FILE_SEP
if isdirectory(javaviDir. join(['target', 'classes'], g:FILE_SEP))
call javacomplete#util#RemoveFile(javaviDir.join(['target', 'classes'], g:FILE_SEP))
endif
let s:compilationIsRunning = 1
if executable('mvn')
let command = ['mvn', '-B', '-f', javaviDir. g:FILE_SEP. 'pom.xml', 'compile']
else
call mkdir(javaviDir. join(['target', 'classes'], g:FILE_SEP), "p")
let deps = s:GetJavaviDeps()
let command = javacomplete#server#GetCompiler()
let command .= ' -d '. javaviDir. 'target'. g:FILE_SEP. 'classes -classpath '. javaviDir. 'target'. g:FILE_SEP. 'classes'. g:PATH_SEP. deps. ' -sourcepath '. javaviDir. 'src'. g:FILE_SEP. 'main'. g:FILE_SEP. 'java -g -nowarn -target 1.8 -source 1.8 -encoding UTF-8 '. javaviDir. join(['src', 'main', 'java', 'kg', 'ash', 'javavi', 'Javavi.java'], g:FILE_SEP)
endif
call javacomplete#util#RunSystem(command, "server compilation", "javacomplete#server#CompilationJobHandler")
endfunction
" Check if Javavi classes exists and return classpath directory.
" If not found, build Javavi library classes with maven or javac.
fu! s:GetJavaviClassPath()
let javaviDir = g:JavaComplete_Home. join(['', 'libs', 'javavi', ''], g:FILE_SEP)
if !isdirectory(javaviDir. "target". g:FILE_SEP. "classes")
call javacomplete#server#Compile()
endif
if !empty(javacomplete#util#GlobPathList(javaviDir. 'target'. g:FILE_SEP. 'classes', '**'. g:FILE_SEP. '*.class', 1, 0))
return javaviDir. "target". g:FILE_SEP. "classes"
else
if !get(s:, 'compilationIsRunning', 0)
echo "No Javavi library classes found, it means that we couldn't compile it. Do you have JDK8+ installed?"
endif
endif
endfu
" Function for server communication {{{2
function! javacomplete#server#Communicate(option, args, log)
if !s:Poll()
call javacomplete#server#Start()
endif
if s:Poll()
if !empty(a:args)
let args = ' "'. substitute(a:args, '"', '\\"', 'g'). '"'
else
let args = ''
endif
let cmd = a:option. args
call s:Log("communicate: ". cmd. " [". a:log. "]")
let result = ""
JavacompletePy << EOPC
vim.command('let result = "%s"' % bridgeState.send(vim.eval("cmd")).replace('"', '\\"'))
EOPC
call s:Log(result)
if result =~ '^message:'
echom result
return "[]"
endif
return result
endif
return ""
endfunction
function! javacomplete#server#GetClassPath()
let jars = s:GetExtraPath()
let path = s:GetJavaviClassPath() . g:PATH_SEP. s:GetJavaviDeps(). g:PATH_SEP
let path = path . join(jars, g:PATH_SEP) . g:PATH_SEP
if &ft == 'jsp'
let path .= s:GetClassPathOfJsp()
endif
if exists('b:classpath') && b:classpath !~ '^\s*$'
call s:Log(b:classpath)
return path . b:classpath
endif
if exists('s:classpath')
call s:Log(s:classpath)
return path . javacomplete#GetClassPath()
endif
if exists('g:java_classpath') && g:java_classpath !~ '^\s*$'
call s:Log(g:java_classpath)
return path . g:java_classpath
endif
if empty($CLASSPATH)
if g:JAVA_HOME == ''
let java = javacomplete#server#GetJVMLauncher()
let javaSettings = split(s:System(java. " -XshowSettings", "Get java settings"), '\n')
for line in javaSettings
if line =~ 'java\.home'
let g:JAVA_HOME = split(line, ' = ')[1]
endif
endfor
endif
return path. g:JAVA_HOME. g:FILE_SEP. 'lib'
endif
return path . $CLASSPATH
endfunction
function! s:ExpandAllPaths(path)
let result = ''
let list = javacomplete#util#uniq(sort(split(a:path, g:PATH_SEP)))
for l in list
let result = result. substitute(expand(l), '\\', '/', 'g') . g:PATH_SEP
endfor
return result
endfunction
function! s:GetJavaviDeps()
let deps = []
call add(deps, fnamemodify(g:JavaComplete_Home. join(['', 'libs', 'javaparser-core-3.5.20.jar'], g:FILE_SEP), ":p"))
call add(deps, fnamemodify(g:JavaComplete_Home. join(['', 'libs', 'javavi_log4j-api.jar'], g:FILE_SEP), ":p"))
call add(deps, fnamemodify(g:JavaComplete_Home. join(['', 'libs', 'javavi_log4j-core.jar'], g:FILE_SEP), ":p"))
let path = join(deps, g:PATH_SEP)
if exists('b:classpath') && b:classpath !~ '^\s*$'
return path . b:classpath
endif
if exists('s:classpath')
return path . s:GetClassPath()
endif
if exists('g:java_classpath') && g:java_classpath !~ '^\s*$'
return path . g:java_classpath
endif
return path
endfunction
function! s:GetExtraPath()
let jars = []
let extrapath = ''
if exists('g:JavaComplete_LibsPath')
let paths = split(g:JavaComplete_LibsPath, g:PATH_SEP)
for path in paths
let exp = s:ExpandPathToJars(path)
if empty(exp)
" ex: target/classes
call extend(jars, [path])
else
call extend(jars, exp)
endif
endfor
endif
return jars
endfunction
function! s:ExpandPathToJars(path, ...)
if isdirectory(a:path)
return javacomplete#util#GlobPathList(a:path, "**5/*.jar", 1, 0)
\ + javacomplete#util#GlobPathList(a:path, "**5/*.zip", 1, 0)
elseif index(['zip', 'jar'], fnamemodify(a:path, ':e')) != -1
return [a:path]
endif
return []
endfunction
fu! s:GetClassPathOfJsp()
if exists('b:classpath_jsp')
return b:classpath_jsp
endif
let b:classpath_jsp = ''
let path = expand('%:p:h')
while 1
if isdirectory(path . '/WEB-INF' )
if isdirectory(path . '/WEB-INF/classes')
let b:classpath_jsp .= g:PATH_SEP . path . '/WEB-INF/classes'
endif
if isdirectory(path . '/WEB-INF/lib')
let b:classpath_jsp .= g:PATH_SEP . path . '/WEB-INF/lib/*.jar'
endif
endif
return b:classpath_jsp
endif
let prev = path
let path = fnamemodify(path, ":p:h:h")
if path == prev
break
endif
endwhile
return ''
endfu
function! s:GetClassPath()
return exists('s:classpath') ? join(s:classpath, g:PATH_SEP) : ''
endfu
function! s:GetDebugLogPath()
return javacomplete#server#Communicate('-get-debug-log-path', '', '')
endfunction
function! javacomplete#server#EnableDebug()
let g:JavaComplete_JavaviLogLevel = "debug"
if s:Poll()
JCserverTerminate
JCserverStart
endif
endfunction
function! javacomplete#server#EnableTraceDebug()
let g:JavaComplete_JavaviLogLevel = "trace"
if s:Poll()
JCserverTerminate
JCserverStart
endif
endfunction
function! javacomplete#server#GetLogContent()
let bufferName = "__JCServer_Log_Buffer__"
let n = bufnr(bufferName)
if n != -1
execute "bwipeout! ". n
endif
let curWin = winnr("#")
execute 'silent! split '. bufferName
set modifiable
setlocal buftype=nofile
setlocal bufhidden=wipe
setlocal noswapfile
setlocal nowrap
setlocal nobuflisted
execute '.-1read '. s:GetDebugLogPath()
execute "normal! G"
set nomodified
nnoremap <buffer> <silent> q :bwipeout!<CR>
execute curWin. 'wincmd w'
endfunction
" vim:set fdm=marker sw=2 nowrap: