1
0
mirror of https://github.com/SpaceVim/SpaceVim.git synced 2025-02-03 12:20:05 +08:00
SpaceVim/bundle/vim-javacomplete2/autoload/javacomplete.vim

500 lines
20 KiB
VimL
Raw Normal View History

2022-11-02 00:34:34 +08:00
" Vim completion script for java
" Maintainer: artur shaik <ashaihullin@gmail.com>
""
" @section Usage, usage
" You can use `vim-javacomplete2` just like other omni-completion plugin.
" Many samples of input context are gived in the following section.
"
" See |javacomplete-faq| in time if some problem occurs.
" When meeting other problems not described in FAQ, you can contact with
" the author by the following e-mail: ashaihullin@gmail.com
"
""
" @section Input contexts, contexts
" @parentsection usage
" It recognize nearly all kinds of Primary Expressions (see langspec-3.0)
" except for `"Primary.new Indentifier"`. Casting conversion is also supported.
"
" Samples of input contexts are as following: (Note that '|' indicates cursor)
"
" (1). after '.', list members of a class or a package
" >
" - package.| subpackages and classes of a package
" - Type.| static members of the 'Type' class and "class"
" - var.| or field.| members of a variable or a field
" - method().| members of result of method()
" - this.| members of the current class
" - ClassName.this.| members of the qualified class
" - super.| members of the super class
" - array.| members of an array object
" - array[i].| array access, return members of the element of array
" - "String".| String literal, return members of java.lang.String
" - int.| or void.| primitive type or pseudo-type, return "class"
" - int[].| array type, return members of a array type and "class"
" - java.lang.String[].|
" - new int[].| members of the new array instance
" - new java.lang.String[i=1][].|
" - new Type().| members of the new class instance
" - Type.class.| class literal, return members of java.lang.Class
" - void.class.| or int.class.|
" - ((Type)var).| cast var as Type, return members of Type.
" - (var.method()).| same with "var.|"
" - (new Class()).| same with "new Class().|"
" <
" (2). after '(', list matching methods with parameters information.
" >
" - method(|) methods matched
" - var.method(|) methods matched
" - new ClassName(|) constructors matched
" - this(|) constructors of current class matched
" - super(|) constructors of super class matched
" Any place between '(' and ')' will be supported soon.
" Help information of javadoc is not supported yet.
" <
" (3). after an incomplete word, list all the matched beginning with it.
" >
" - var.ab| subset of members of var beginning with `ab`
" - ab| list of all maybes
" <
" (4). import statement
" >
" - " import java.util.|"
" - " import java.ut|"
" - " import ja|"
" - " import java.lang.Character.|" e.g. "Subset"
" - " import static java.lang.Math.|" e.g. "PI, abs"
" <
" (5). package declaration
" >
" - " package com.|"
" <
"
" The above are in simple expression.
"
" (6). after compound expression:
" >
" - PrimaryExpr.var.|
" - PrimaryExpr.method().|
" - PrimaryExpr.method(|)
" - PrimaryExpr.var.ab|
" e.g.
" - "java.lang . System.in .|"
" - "java.lang.System.getenv().|"
" - "int.class.toString().|"
" - "list.toArray().|"
" - "new ZipFile(path).|"
" - "new ZipFile(path).entries().|"
" <
" (7). Nested expression:
" >
" - "System.out.println( str.| )"
" - "System.out.println(str.charAt(| )"
" - "for (int i = 0; i < str.|; i++)"
" - "for ( Object o : a.getCollect| )"
" <
"
""
" @section Kind letter, kindletter
" @parentsection usage
" A single letter indicates the kind of compeltion item. These kinds are:
" >
" + ctor
" v local variable or parameter
" f nonstatic field
" F static field
" m nonstatic method
" M static method
" P package
" C class type
" I interface type
" <
""
" @section Class creation, classnew
" @parentsection usage
" Prompt scheme, for class creation:
" >
" template:[subdirectory]:/package.ClassName extends SuperClass implements Interface(String str, public Integer i):contructor(*):toString(1)
" <
" A: (optional) template - which will be used to create class boilerplate. Some existed templates: junit, interface, exception, servlet, etcl
"
" B: (optional) subdirectory in which class will be put. For example: test, androidTest;
"
" C: class name and package. With `/` will use backsearch for parent package to put in it. Without `/` put in relative package to current;
"
" D: (optional) extends and implements classes will be automatically imported;
"
" E: (optional) private str variable, and public i variable will be added to class;
"
" F: (optional) contructor using all fields and toString override method with only 'str' field will be created. Also hashCode and equals can be used.
"
" There is autocompletion in command prompt that will try to help you. Your current opened file shouldn't have dirty changes or 'hidden' should be set.
""
" @section FAQ, faq
" 4.1 Why can not complete in gradle project?
"
" Check if 'gradle' is in your runtime path or './gradlew' (or
" '.\gradlew.bat' for Windows) is in your project's directory.
"
" 4.2 I have installed gradle, but why I can not complete R.class?
"
" In android project, many of the class contains a ton of
" innerclass, javacomplete2 could works better by reflection, so you need to
" compile you project, after use './gradlew build', R.java will be
" automatically generated and compiled.
""
" @section Todo, todo
" - Add javadoc
" - Cross session cache;
" - Most used (classes, methods, vars) at first place (smart suggestions);
" - FXML support;
" - JSP check support;
" - Refactoring support?;
" - Class creation helpers;
" - etc...
if exists('g:JavaComplete_Autoload')
finish
endif
let g:JavaComplete_Autoload = 1
" It doesn't make sense to do any work if vim doesn't support any Python since
" we relly on it to properly work.
if has('python3')
command! -nargs=1 JavacompletePy py3 <args>
command! -nargs=1 JavacompletePyfile py3file <args>
else
echoerr 'Javacomplete needs Python3 support to run!'
finish
endif
function! s:Log(log) abort
let log = type(a:log) ==# type('') ? a:log : string(a:log)
call javacomplete#logger#Log('[javacomplete] '. a:log)
endfunction
let g:J_ARRAY_TYPE_MEMBERS = [
\ {'kind': 'm', 'word': 'clone(', 'abbr': 'clone()', 'menu': 'Object clone()', },
\ {'kind': 'm', 'word': 'equals(', 'abbr': 'equals()', 'menu': 'boolean equals(Object)', },
\ {'kind': 'm', 'word': 'getClass(', 'abbr': 'getClass()', 'menu': 'Class Object.getClass()', },
\ {'kind': 'm', 'word': 'hashCode(', 'abbr': 'hashCode()', 'menu': 'int hashCode()', },
\ {'kind': 'f', 'word': 'length', 'menu': 'int'},
\ {'kind': 'm', 'word': 'notify(', 'abbr': 'notify()', 'menu': 'void Object.notify()', },
\ {'kind': 'm', 'word': 'notifyAll(', 'abbr': 'notifyAll()', 'menu': 'void Object.notifyAll()', },
\ {'kind': 'm', 'word': 'toString(', 'abbr': 'toString()', 'menu': 'String toString()', },
\ {'kind': 'm', 'word': 'wait(', 'abbr': 'wait()', 'menu': 'void Object.wait() throws InterruptedException', },
\ {'kind': 'm', 'dup': 1, 'word': 'wait(', 'abbr': 'wait()', 'menu': 'void Object.wait(long timeout) throws InterruptedException', },
\ {'kind': 'm', 'dup': 1, 'word': 'wait(', 'abbr': 'wait()', 'menu': 'void Object.wait(long timeout, int nanos) throws InterruptedException', }]
let g:J_ARRAY_TYPE_INFO = {'tag': 'CLASSDEF', 'name': '[', 'ctors': [],
\ 'fields': [{'n': 'length', 'm': '1', 't': 'int'}],
\ 'methods':[
\ {'n': 'clone', 'm': '1', 'r': 'Object', 'p': [], 'd': 'Object clone()'},
\ {'n': 'equals', 'm': '1', 'r': 'boolean', 'p': ['Object'], 'd': 'boolean Object.equals(Object obj)'},
\ {'n': 'getClass', 'm': '100010001', 'r': 'Class', 'p': [], 'd': 'Class Object.getClass()'},
\ {'n': 'hashCode', 'm': '100000001', 'r': 'int', 'p': [], 'd': 'int Object.hashCode()'},
\ {'n': 'notify', 'm': '100010001', 'r': 'void', 'p': [], 'd': 'void Object.notify()'},
\ {'n': 'notifyAll','m': '100010001', 'r': 'void', 'p': [], 'd': 'void Object.notifyAll()'},
\ {'n': 'toString', 'm': '1', 'r': 'String', 'p': [], 'd': 'String Object.toString()'},
\ {'n': 'wait', 'm': '10001', 'r': 'void', 'p': [], 'd': 'void Object.wait() throws InterruptedException'},
\ {'n': 'wait', 'm': '100010001', 'r': 'void', 'p': ['long'], 'd': 'void Object.wait(long timeout) throws InterruptedException'},
\ {'n': 'wait', 'm': '10001', 'r': 'void', 'p': ['long','int'], 'd': 'void Object.wait(long timeout, int nanos) throws InterruptedException'},
\ ]}
let g:J_PRIMITIVE_TYPE_INFO = {'tag': 'CLASSDEF', 'name': '!', 'fields': [{'n': 'class','m': '1','t': 'Class'}]}
let g:J_JSP_BUILTIN_OBJECTS = {'session': 'javax.servlet.http.HttpSession',
\ 'request': 'javax.servlet.http.HttpServletRequest',
\ 'response': 'javax.servlet.http.HttpServletResponse',
\ 'pageContext': 'javax.servlet.jsp.PageContext',
\ 'application': 'javax.servlet.ServletContext',
\ 'config': 'javax.servlet.ServletConfig',
\ 'out': 'javax.servlet.jsp.JspWriter',
\ 'page': 'javax.servlet.jsp.HttpJspPage', }
let g:J_PRIMITIVE_TYPES = ['boolean', 'byte', 'char', 'int', 'short', 'long', 'float', 'double']
let g:J_KEYWORDS_MODS = ['public', 'private', 'protected', 'static', 'final', 'synchronized', 'volatile', 'transient', 'native', 'strictfp', 'abstract']
let g:J_KEYWORDS_TYPE = ['class', 'interface', 'enum']
let g:J_KEYWORDS = g:J_PRIMITIVE_TYPES + g:J_KEYWORDS_MODS + g:J_KEYWORDS_TYPE + ['super', 'this', 'void', 'var'] + ['assert', 'break', 'case', 'catch', 'const', 'continue', 'default', 'do', 'else', 'extends', 'finally', 'for', 'goto', 'if', 'implements', 'import', 'instanceof', 'interface', 'new', 'package', 'return', 'switch', 'throw', 'throws', 'try', 'while', 'true', 'false', 'null']
let g:JC_MODIFIER_PUBLIC = 1
let g:JC_MODIFIER_PROTECTED = 3
let g:JC_MODIFIER_FINAL = 5
let g:JC_MODIFIER_NATIVE = 9
let g:JC_MODIFIER_ABSTRACT = 11
let g:RE_BRACKETS = '\%(\s*\[\s*\]\)'
let g:RE_IDENTIFIER = '[a-zA-Z_$][a-zA-Z0-9_$]*'
let g:RE_ANNOTATION = '@[a-zA-Z_][a-zA-Z0-9_$]*'
let g:RE_QUALID = g:RE_IDENTIFIER. '\%(\s*\.\s*' .g:RE_IDENTIFIER. '\)*'
let g:RE_REFERENCE_TYPE = g:RE_QUALID . g:RE_BRACKETS . '*'
let g:RE_TYPE = g:RE_REFERENCE_TYPE
let g:RE_TYPE_ARGUMENT = '\%(?\s\+\%(extends\|super\)\s\+\)\=' . g:RE_TYPE
let g:RE_TYPE_ARGUMENT_EXTENDS = '\%(?\s\+\%(extends\|super\)\s\+\)' . g:RE_TYPE
let g:RE_TYPE_ARGUMENTS = '<' . g:RE_TYPE_ARGUMENT . '\%(\s*,\s*' . g:RE_TYPE_ARGUMENT . '\)*>'
let g:RE_TYPE_WITH_ARGUMENTS_I = g:RE_IDENTIFIER . '\s*' . g:RE_TYPE_ARGUMENTS
let g:RE_TYPE_WITH_ARGUMENTS = g:RE_TYPE_WITH_ARGUMENTS_I . '\%(\s*' . g:RE_TYPE_WITH_ARGUMENTS_I . '\)*'
let g:RE_TYPE_MODS = '\%(public\|protected\|private\|abstract\|static\|final\|strictfp\)'
let g:RE_TYPE_DECL_HEAD = '\(class\|interface\|enum\)[ \t\n\r ]\+'
let g:RE_TYPE_DECL = '\<\C\(\%(' .g:RE_TYPE_MODS. '\s\+\)*\)' .g:RE_TYPE_DECL_HEAD. '\(' .g:RE_IDENTIFIER. '\)[{< \t\n\r ]'
let g:RE_ARRAY_TYPE = '^\s*\(' .g:RE_QUALID . '\)\(' . g:RE_BRACKETS . '\+\)\s*$'
let g:RE_SELECT_OR_ACCESS = '^\s*\(' . g:RE_IDENTIFIER . '\)\s*\(\[.*\]\)\=\s*$'
let g:RE_ARRAY_ACCESS = '^\s*\(' . g:RE_IDENTIFIER . '\)\s*\(\[.*\]\)\+\s*$'
let g:RE_CASTING = '^\s*(\(' .g:RE_QUALID. '\))\s*\(' . g:RE_IDENTIFIER . '\)\>'
let g:RE_KEYWORDS = '\<\%(' . join(g:J_KEYWORDS, '\|') . '\)\>'
let g:JAVA_HOME = $JAVA_HOME
let g:JavaComplete_Cache = {} " FQN -> member list, e.g. {'java.lang.StringBuffer': classinfo, 'java.util': packageinfo, '/dir/TopLevelClass.java': compilationUnit}
let g:JavaComplete_Files = {} " srouce file path -> properties, e.g. {filekey: {'unit': compilationUnit, 'changedtick': tick, }}
let g:JavaComplete_ProjectKey = ''
fu! SScope() abort
return s:
endfu
function! javacomplete#Disable() abort
let g:JavaComplete_Disabled = 1
endfunction
function! javacomplete#Enable() abort
let g:JavaComplete_Disabled = 0
endfunction
function! javacomplete#ClearCache() abort
let g:JavaComplete_Cache = {}
let g:JavaComplete_Files = {}
call javacomplete#util#RemoveFile(javacomplete#util#GetBase('cache'). g:FILE_SEP. 'class_packages_'. g:JavaComplete_ProjectKey. '.dat')
call javacomplete#server#Communicate('-collect-packages', '', 's:ClearCache')
endfunction
function! javacomplete#Complete(findstart, base) abort
return javacomplete#complete#complete#Complete(a:findstart, a:base, 1)
endfunction
" key of g:JavaComplete_Files for current buffer. It may be the full path of current file or the bufnr of unnamed buffer, and is updated when BufEnter, BufLeave.
function! javacomplete#GetCurrentFileKey() abort
return s:GetCurrentFileKey()
endfunction
function! s:GetCurrentFileKey() abort
return has('autocmd') ? s:curfilekey : empty(expand('%')) ? bufnr('%') : expand('%:p')
endfunction
function! s:SetCurrentFileKey() abort
let s:curfilekey = empty(expand('%')) ? bufnr('%') : expand('%:p')
endfunction
call s:SetCurrentFileKey()
function! s:HandleTextChangedI() abort
if get(g:, 'JC_ClassnameCompletedFlag', 0) && g:JavaComplete_InsertImports
let saveCursor = getcurpos()
let line = getline('.')
if empty(javacomplete#util#Trim(line))
call cursor(line('.') - 1, 500)
let line = getline('.')
let offset = 1
else
if line[col('.') - 2] !~# '\v(\s|\.|\(|\<)'
return
endif
let offset = 0
endif
let g:JC_ClassnameCompletedFlag = 0
call javacomplete#imports#Add(1)
let saveCursor[1] = line('.') + offset
call setpos('.', saveCursor)
endif
if get(g:, 'JC_DeclarationCompletedFlag', 0)
let line = getline('.')
if line[col('.') - 2] != ' '
return
endif
let g:JC_DeclarationCompletedFlag = 0
if line !~# '.*@Override.*'
let line = getline(line('.') - 1)
endif
if line =~# '.*@Override\s\+\(\S\+\|\)\(\s\+\|\)$'
return
endif
if !empty(javacomplete#util#Trim(getline('.')))
call feedkeys("\b\r", 'n')
endif
if g:JavaComplete_ClosingBrace
call feedkeys("}\eO", 'n')
endif
endif
endfunction
function! s:HandleInsertLeave() abort
if get(g:, 'JC_DeclarationCompletedFlag', 0)
let g:JC_DeclarationCompletedFlag = 0
endif
if get(g:, 'JC_ClassnameCompletedFlag', 0)
let g:JC_ClassnameCompletedFlag = 0
endif
endfunction
function! javacomplete#UseFQN() abort
return g:JavaComplete_UseFQN
endfunction
function! s:RemoveCurrentFromCache() abort
let package = javacomplete#complete#complete#GetPackageName()
let classname = split(expand('%:t'), '\.')[0]
let fqn = package. '.'. classname
if has_key(g:JavaComplete_Cache, fqn)
call remove(g:JavaComplete_Cache, fqn)
endif
call javacomplete#server#Communicate('-clear-from-cache', fqn, 's:RemoveCurrentFromCache')
call javacomplete#server#Communicate('-async -recompile-class', fqn, 's:RemoveCurrentFromCache')
let arguments = '-source '. resolve(expand('%:p'))
let arguments .= ' -class '. classname
let arguments .= ' -package '. package
call javacomplete#server#Communicate('-async -add-source-to-cache', arguments, 's:RemoveCurrentFromCache')
endfunction
function! s:DefaultMappings() abort
if g:JavaComplete_EnableDefaultMappings
return
endif
nmap <silent> <buffer> <leader>jI <Plug>(JavaComplete-Imports-AddMissing)
nmap <silent> <buffer> <leader>jR <Plug>(JavaComplete-Imports-RemoveUnused)
nmap <silent> <buffer> <leader>ji <Plug>(JavaComplete-Imports-AddSmart)
nmap <silent> <buffer> <leader>jii <Plug>(JavaComplete-Imports-Add)
nmap <silent> <buffer> <leader>jis <Plug>(JavaComplete-Imports-SortImports)
imap <silent> <buffer> <C-j>I <Plug>(JavaComplete-Imports-AddMissing)
imap <silent> <buffer> <C-j>R <Plug>(JavaComplete-Imports-RemoveUnused)
imap <silent> <buffer> <C-j>i <Plug>(JavaComplete-Imports-AddSmart)
imap <silent> <buffer> <C-j>ii <Plug>(JavaComplete-Imports-Add)
nmap <silent> <buffer> <leader>jM <Plug>(JavaComplete-Generate-AbstractMethods)
imap <silent> <buffer> <C-j>jM <Plug>(JavaComplete-Generate-AbstractMethods)
nmap <silent> <buffer> <leader>jA <Plug>(JavaComplete-Generate-Accessors)
nmap <silent> <buffer> <leader>js <Plug>(JavaComplete-Generate-AccessorSetter)
nmap <silent> <buffer> <leader>jg <Plug>(JavaComplete-Generate-AccessorGetter)
nmap <silent> <buffer> <leader>ja <Plug>(JavaComplete-Generate-AccessorSetterGetter)
nmap <silent> <buffer> <leader>jts <Plug>(JavaComplete-Generate-ToString)
nmap <silent> <buffer> <leader>jeq <Plug>(JavaComplete-Generate-EqualsAndHashCode)
nmap <silent> <buffer> <leader>jc <Plug>(JavaComplete-Generate-Constructor)
nmap <silent> <buffer> <leader>jcc <Plug>(JavaComplete-Generate-DefaultConstructor)
imap <silent> <buffer> <C-j>s <Plug>(JavaComplete-Generate-AccessorSetter)
imap <silent> <buffer> <C-j>g <Plug>(JavaComplete-Generate-AccessorGetter)
imap <silent> <buffer> <C-j>a <Plug>(JavaComplete-Generate-AccessorSetterGetter)
vmap <silent> <buffer> <leader>js <Plug>(JavaComplete-Generate-AccessorSetter)
vmap <silent> <buffer> <leader>jg <Plug>(JavaComplete-Generate-AccessorGetter)
vmap <silent> <buffer> <leader>ja <Plug>(JavaComplete-Generate-AccessorSetterGetter)
nmap <silent> <buffer> <leader>jn <Plug>(JavaComplete-Generate-NewClass)
nmap <silent> <buffer> <leader>jN <Plug>(JavaComplete-Generate-ClassInFile)
endfunction
augroup javacomplete
autocmd!
autocmd BufEnter *.java,*.jsp call s:SetCurrentFileKey()
autocmd BufEnter *.java call s:DefaultMappings()
autocmd BufWritePost *.java call s:RemoveCurrentFromCache()
autocmd VimLeave * call javacomplete#server#Terminate()
if v:version > 704 || v:version == 704 && has('patch143')
autocmd TextChangedI *.java,*.jsp call s:HandleTextChangedI()
else
echohl WarningMsg
echomsg 'JavaComplete2 : TextChangedI feature needs vim version >= 7.4.143'
echohl None
endif
autocmd InsertLeave *.java,*.jsp call s:HandleInsertLeave()
augroup END
let g:JavaComplete_Home = fnamemodify(expand('<sfile>'), ':p:h:h:gs?\\?'. g:FILE_SEP. '?')
let g:JavaComplete_JavaParserJar = fnamemodify(g:JavaComplete_Home. join(['', 'libs', 'javaparser-core-3.5.20.jar'], g:FILE_SEP), ':p')
call s:Log('JavaComplete_Home: '. g:JavaComplete_Home)
""
" path of your sources. Don't try to
" add all sources you have, this will slow down parsing process.
" Add you project sources and necessery library sources. If you
" have compiled classes add them to previous config instead. By
" default plugin will search `src` directory and add it
" automatically.
let g:JavaComplete_SourcesPath = get(g:, 'JavaComplete_SourcesPath', ''). g:PATH_SEP
\. join(filter(javacomplete#util#GlobPathList(getcwd(), 'src', 0, 3), "match(v:val, '.*build.*') < 0"), g:PATH_SEP)
""
" disable the maven repository.
" >
" let g:JavaComplete_MavenRepositoryDisabled = 1
" <
" by default this option is disabled (0).
let g:JavaComplete_MavenRepositoryDisabled = 0
if filereadable(getcwd(). g:FILE_SEP. 'build.gradle')
let g:JavaComplete_SourcesPath = g:JavaComplete_SourcesPath
\. g:PATH_SEP
\. join(javacomplete#util#GlobPathList(getcwd()
\, join(['**', 'build', 'generated', 'source', '**', 'debug'], g:FILE_SEP), 0, 0)
\, g:PATH_SEP)
endif
for source in get(g:, 'JavaComplete_SourceExclude', [])
let source = fnamemodify(source, ':p')
let idx = stridx(g:JavaComplete_SourcesPath, source)
while idx > 0
let colon = stridx(g:JavaComplete_SourcesPath, ':', idx + 1)
let g:JavaComplete_SourcesPath = g:JavaComplete_SourcesPath[:idx - 1] . g:JavaComplete_SourcesPath[colon + 1:]
let idx = stridx(g:JavaComplete_SourcesPath, source)
endwhile
endfor
call s:Log('Default sources: '. g:JavaComplete_SourcesPath)
if exists('g:JavaComplete_LibsPath')
let g:JavaComplete_LibsPath .= g:PATH_SEP
else
""
" path of you jar files. This path will
" always appended with '~/.m2/repository' directory. Here you can
" add your glassfish libs directory or your project libs. It will
" be automatically appended with you jre home path
let g:JavaComplete_LibsPath = ''
endif
call javacomplete#classpath#classpath#BuildClassPath()
function! javacomplete#Start() abort
call javacomplete#server#Start()
endfunction
" vim:set fdm=marker sw=2 nowrap: