mirror of
https://github.com/SpaceVim/SpaceVim.git
synced 2025-02-03 15:00:06 +08:00
232 lines
6.3 KiB
VimL
232 lines
6.3 KiB
VimL
|
" Vim completion script for java
|
|||
|
" Maintainer: artur shaik <ashaihullin@gmail.com>
|
|||
|
"
|
|||
|
" Simple parsing functions
|
|||
|
|
|||
|
" Search back from the cursor position till meeting '{' or ';'.
|
|||
|
" '{' means statement start, ';' means end of a previous statement.
|
|||
|
" Return: statement before cursor
|
|||
|
" Note: It's the base for parsing. And It's OK for most cases.
|
|||
|
function! javacomplete#scanner#GetStatement()
|
|||
|
if getline('.') =~ '^\s*\(import\|package\)\s\+'
|
|||
|
return strpart(getline('.'), match(getline('.'), '\(import\|package\)'), col('.')-1)
|
|||
|
endif
|
|||
|
|
|||
|
let lnum_old = line('.')
|
|||
|
let col_old = col('.')
|
|||
|
|
|||
|
call s:SkipBlock()
|
|||
|
|
|||
|
while 1
|
|||
|
if search('[{};]\|<%\|<%!', 'bW') == 0
|
|||
|
let lnum = 1
|
|||
|
let col = 1
|
|||
|
else
|
|||
|
if javacomplete#util#InCommentOrLiteral(line('.'), col('.'))
|
|||
|
continue
|
|||
|
endif
|
|||
|
|
|||
|
normal! w
|
|||
|
let lnum = line('.')
|
|||
|
let col = col('.')
|
|||
|
endif
|
|||
|
break
|
|||
|
endwhile
|
|||
|
|
|||
|
silent call cursor(lnum_old, col_old)
|
|||
|
return s:MergeLines(lnum, col, lnum_old, col_old)
|
|||
|
endfunction
|
|||
|
|
|||
|
function! s:SkipBlock()
|
|||
|
let pos = line('.') + 1
|
|||
|
let clbracket = 0
|
|||
|
let quoteFlag = 0
|
|||
|
while pos > 0
|
|||
|
let pos -= 1
|
|||
|
if pos == 0
|
|||
|
break
|
|||
|
endif
|
|||
|
|
|||
|
let line = getline(pos)
|
|||
|
let cursor = len(line)
|
|||
|
while cursor > 0
|
|||
|
if line[cursor] == '"'
|
|||
|
if quoteFlag == 0
|
|||
|
let quoteFlag = 1
|
|||
|
else
|
|||
|
let quoteFlag = 0
|
|||
|
endif
|
|||
|
endif
|
|||
|
|
|||
|
if quoteFlag
|
|||
|
let line = line[0 : cursor - 1]. line[cursor + 1 : -1]
|
|||
|
let cursor -= 1
|
|||
|
continue
|
|||
|
endif
|
|||
|
|
|||
|
if line[cursor] == '}'
|
|||
|
let clbracket += 1
|
|||
|
elseif line[cursor] == '(' && clbracket == 0
|
|||
|
call cursor(pos, cursor)
|
|||
|
break
|
|||
|
elseif line[cursor] == '{'
|
|||
|
if clbracket > 0
|
|||
|
let clbracket -= 1
|
|||
|
else
|
|||
|
break
|
|||
|
endif
|
|||
|
endif
|
|||
|
let cursor -= 1
|
|||
|
endwhile
|
|||
|
if clbracket == 0
|
|||
|
break
|
|||
|
endif
|
|||
|
endwhile
|
|||
|
endfunction
|
|||
|
|
|||
|
function! s:MergeLines(lnum, col, lnum_old, col_old)
|
|||
|
let lnum = a:lnum
|
|||
|
let col = a:col
|
|||
|
|
|||
|
let str = ''
|
|||
|
if lnum < a:lnum_old
|
|||
|
let str = javacomplete#util#Prune(strpart(getline(lnum), a:col-1))
|
|||
|
let lnum += 1
|
|||
|
while lnum < a:lnum_old
|
|||
|
let str .= javacomplete#util#Prune(getline(lnum))
|
|||
|
let lnum += 1
|
|||
|
endwhile
|
|||
|
let col = 1
|
|||
|
endif
|
|||
|
let lastline = strpart(getline(a:lnum_old), col-1, a:col_old-col)
|
|||
|
let str .= javacomplete#util#Prune(lastline, col)
|
|||
|
let str = javacomplete#util#RemoveBlockComments(str)
|
|||
|
" generic in JAVA 5+
|
|||
|
while match(str, g:RE_TYPE_ARGUMENTS) != -1
|
|||
|
let str = substitute(str, '\(' . g:RE_TYPE_ARGUMENTS . '\)', '\=repeat("", len(submatch(1)))', 'g')
|
|||
|
endwhile
|
|||
|
let str = substitute(str, '\s\s\+', ' ', 'g')
|
|||
|
if str !~ '.*'. g:RE_KEYWORDS. '.*'
|
|||
|
let str = substitute(str, '\([.()]\)[ \t]\+', '\1', 'g')
|
|||
|
let str = substitute(str, '[ \t]\+\([.()]\)', '\1', 'g')
|
|||
|
endif
|
|||
|
return javacomplete#util#Trim(str) . matchstr(lastline, '\s*$')
|
|||
|
endfunction
|
|||
|
|
|||
|
" Extract a clean expr, removing some non-necessary characters.
|
|||
|
function! javacomplete#scanner#ExtractCleanExpr(expr)
|
|||
|
if a:expr !~ '.*'. g:RE_KEYWORDS. '.*'
|
|||
|
let cmd = substitute(a:expr, '[ \t\r\n]\+\([.()[\]]\)', '\1', 'g')
|
|||
|
let cmd = substitute(cmd, '\([.()[\]]\)[ \t\r\n]\+', '\1', 'g')
|
|||
|
else
|
|||
|
let cmd = a:expr
|
|||
|
endif
|
|||
|
|
|||
|
let pos = strlen(cmd)-1
|
|||
|
while pos >= 0 && cmd[pos] =~ '[a-zA-Z0-9_.)\]:<>]'
|
|||
|
if cmd[pos] == ')'
|
|||
|
let pos = javacomplete#util#SearchPairBackward(cmd, pos, '(', ')')
|
|||
|
elseif cmd[pos] == ']'
|
|||
|
let pos = javacomplete#util#SearchPairBackward(cmd, pos, '[', ']')
|
|||
|
endif
|
|||
|
let pos -= 1
|
|||
|
endwhile
|
|||
|
|
|||
|
" try looking back for "new"
|
|||
|
let idx = match(strpart(cmd, 0, pos+1), '\<new[ \t\r\n]*$')
|
|||
|
|
|||
|
return strpart(cmd, idx != -1 ? idx : pos+1)
|
|||
|
endfunction
|
|||
|
|
|||
|
function! javacomplete#scanner#ParseExpr(expr)
|
|||
|
let items = []
|
|||
|
let s = 0
|
|||
|
" recognize ClassInstanceCreationExpr as a whole
|
|||
|
let e = matchend(a:expr, '^\s*new\s\+' . g:RE_QUALID . '\s*[([]')-1
|
|||
|
if e < 0
|
|||
|
let e = match(a:expr, '[.([:]')
|
|||
|
endif
|
|||
|
let isparen = 0
|
|||
|
while e >= 0
|
|||
|
if a:expr[e] == '.' || a:expr[e] == ':'
|
|||
|
let subexpr = strpart(a:expr, s, e-s)
|
|||
|
call extend(items, isparen ? s:ProcessParentheses(subexpr) : [subexpr])
|
|||
|
let isparen = 0
|
|||
|
if a:expr[e] == ':' && a:expr[e+1] == ':'
|
|||
|
let s = e + 2
|
|||
|
else
|
|||
|
let s = e + 1
|
|||
|
endif
|
|||
|
elseif a:expr[e] == '('
|
|||
|
let e = javacomplete#util#GetMatchedIndexEx(a:expr, e, '(', ')')
|
|||
|
let isparen = 1
|
|||
|
if e < 0
|
|||
|
break
|
|||
|
else
|
|||
|
let e = matchend(a:expr, '^\s*[.[]', e+1)-1
|
|||
|
continue
|
|||
|
endif
|
|||
|
elseif a:expr[e] == '['
|
|||
|
let e = javacomplete#util#GetMatchedIndexEx(a:expr, e, '[', ']')
|
|||
|
if e < 0
|
|||
|
break
|
|||
|
else
|
|||
|
let e = matchend(a:expr, '^\s*[.[]', e+1)-1
|
|||
|
continue
|
|||
|
endif
|
|||
|
endif
|
|||
|
let e = match(a:expr, '[.([:]', s)
|
|||
|
endwhile
|
|||
|
let tail = strpart(a:expr, s)
|
|||
|
if tail !~ '^\s*$'
|
|||
|
call extend(items, isparen ? s:ProcessParentheses(tail) : [tail])
|
|||
|
endif
|
|||
|
|
|||
|
return items
|
|||
|
endfunction
|
|||
|
|
|||
|
" Given optional argument, call s:ParseExpr() to parser the nonparentheses expr
|
|||
|
fu! s:ProcessParentheses(expr, ...)
|
|||
|
let s = matchend(a:expr, '^\s*(')
|
|||
|
if s != -1
|
|||
|
let e = javacomplete#util#GetMatchedIndexEx(a:expr, s-1, '(', ')')
|
|||
|
if e >= 0
|
|||
|
let tail = strpart(a:expr, e+1)
|
|||
|
if tail[-1:] == '.'
|
|||
|
return [tail[0:-2]]
|
|||
|
endif
|
|||
|
if tail =~ '^\s*[\=$'
|
|||
|
return s:ProcessParentheses(strpart(a:expr, s, e-s), 1)
|
|||
|
elseif tail =~ '^\s*\w'
|
|||
|
return [strpart(a:expr, 0, e+1) . 'obj.']
|
|||
|
endif
|
|||
|
endif
|
|||
|
|
|||
|
" multi-dot-expr except for new expr
|
|||
|
elseif a:0 > 0 && stridx(a:expr, '.') != match(a:expr, '\.\s*$') && a:expr !~ '^\s*new\s\+'
|
|||
|
return javacomplete#scanner#ParseExpr(a:expr)
|
|||
|
endif
|
|||
|
return [a:expr]
|
|||
|
endfu
|
|||
|
|
|||
|
" search decl {{{1
|
|||
|
" Return: The declaration of identifier under the cursor
|
|||
|
" Note: The type of a variable must be imported or a fqn.
|
|||
|
function! javacomplete#scanner#GetVariableDeclaration()
|
|||
|
let lnum_old = line('.')
|
|||
|
let col_old = col('.')
|
|||
|
|
|||
|
silent call search('[^a-zA-Z0-9$_.,?<>[\] \t\r\n]', 'bW') " call search('[{};(,]', 'b')
|
|||
|
normal! w
|
|||
|
let lnum = line('.')
|
|||
|
let col = col('.')
|
|||
|
if (lnum == lnum_old && col == col_old)
|
|||
|
return ''
|
|||
|
endif
|
|||
|
|
|||
|
silent call cursor(lnum_old, col_old)
|
|||
|
return s:MergeLines(lnum, col, lnum_old, col_old)
|
|||
|
endfunction
|
|||
|
|
|||
|
" vim:set fdm=marker sw=2 nowrap:
|