1
0
mirror of https://github.com/SpaceVim/SpaceVim.git synced 2025-01-24 05:20:04 +08:00
SpaceVim/bundle/vim-javacomplete2/autoload/javacomplete.vim
2022-11-02 00:34:34 +08:00

500 lines
20 KiB
VimL
Vendored
Raw Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

" 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: