dot_files/vim-plugins/bundle/eclim/autoload/eclim/java/impl.vim
2017-10-08 12:00:02 +01:00

353 lines
11 KiB
VimL

" Author: Eric Van Dewoestine
"
" Description: {{{
" see http://eclim.org/vim/java/impl.html
"
" License:
"
" Copyright (C) 2005 - 2014 Eric Van Dewoestine
"
" This program is free software: you can redistribute it and/or modify
" it under the terms of the GNU General Public License as published by
" the Free Software Foundation, either version 3 of the License, or
" (at your option) any later version.
"
" This program is distributed in the hope that it will be useful,
" but WITHOUT ANY WARRANTY; without even the implied warranty of
" MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
" GNU General Public License for more details.
"
" You should have received a copy of the GNU General Public License
" along with this program. If not, see <http://www.gnu.org/licenses/>.
"
" }}}
" Script Varables {{{
let s:command_constructor =
\ '-command java_constructor -p "<project>" -f "<file>" -o <offset> -e <encoding>'
let s:command_properties =
\ '-command java_bean_properties -p "<project>" -f "<file>" ' .
\ '-o <offset> -e <encoding> -t <type> -r <properties> <indexed>'
let s:command_impl =
\ '-command java_impl -p "<project>" -f "<file>" -o <offset> -e <encoding>'
let s:command_impl_insert =
\ '-command java_impl -p "<project>" -f "<file>" -t "<type>" ' .
\ '-s "<superType>" <methods>'
let s:command_delegate =
\ '-command java_delegate -p "<project>" -f "<file>" -o <offset> -e <encoding>'
let s:command_delegate_insert =
\ '-command java_delegate -p "<project>" -f "<file>" -v "<type>" ' .
\ '-s "<superType>" <methods>'
let s:no_properties =
\ 'Unable to find property at current cursor position: ' .
\ 'Not on a field declaration or possible java syntax error.'
let s:cross_type_selection = "Visual selection is currently limited to methods of one super type at a time."
" }}}
function! eclim#java#impl#Constructor(first, last, bang) " {{{
if !eclim#project#util#IsCurrentFileInProject()
return
endif
call eclim#lang#SilentUpdate()
let properties = a:last == 1 ? [] :
\ eclim#java#util#GetSelectedFields(a:first, a:last)
let project = eclim#project#util#GetCurrentProjectName()
let file = eclim#project#util#GetProjectRelativeFilePath()
let command = s:command_constructor
let command = substitute(command, '<project>', project, '')
let command = substitute(command, '<file>', file, '')
let command = substitute(command, '<offset>', eclim#util#GetOffset(), '')
let command = substitute(command, '<encoding>', eclim#util#GetEncoding(), '')
if a:bang == ''
let command .= ' -s'
endif
if len(properties) > 0
let json = substitute(string(properties), "'", '"', 'g')
if has('win32') || has('win64')
let command .= ' -r "' . json . '"'
else
let command .= " -r '" . json . "'"
endif
endif
let result = eclim#Execute(command)
if type(result) == g:STRING_TYPE && result != ''
call eclim#util#EchoError(result)
return
endif
if result != "0"
call eclim#util#Reload({'retab': 1})
write
endif
endfunction " }}}
function! eclim#java#impl#GetterSetter(first, last, bang, type) " {{{
if !eclim#project#util#IsCurrentFileInProject()
return
endif
call eclim#lang#SilentUpdate()
let properties = eclim#java#util#GetSelectedFields(a:first, a:last)
if len(properties) == 0
call eclim#util#EchoError(s:no_properties)
return
endif
let project = eclim#project#util#GetCurrentProjectName()
let file = eclim#project#util#GetProjectRelativeFilePath()
let indexed = a:bang != '' ? '-i' : ''
let command = s:command_properties
let command = substitute(command, '<project>', project, '')
let command = substitute(command, '<file>', file, '')
let command = substitute(command, '<offset>', eclim#util#GetOffset(), '')
let command = substitute(command, '<encoding>', eclim#util#GetEncoding(), '')
let command = substitute(command, '<type>', a:type, '')
let command = substitute(command, '<properties>', join(properties, ','), '')
let command = substitute(command, '<indexed>', indexed, '')
let result = eclim#Execute(command)
if result != "0"
call eclim#util#Reload({'retab': 1})
write
endif
endfunction " }}}
function! eclim#java#impl#Impl() " {{{
if !eclim#project#util#IsCurrentFileInProject()
return
endif
call eclim#lang#SilentUpdate()
let project = eclim#project#util#GetCurrentProjectName()
let file = eclim#project#util#GetProjectRelativeFilePath()
let offset = eclim#util#GetCurrentElementOffset()
let command = s:command_impl
let command = substitute(command, '<project>', project, '')
let command = substitute(command, '<file>', file, '')
let command = substitute(command, '<offset>', offset, '')
let command = substitute(command, '<encoding>', eclim#util#GetEncoding(), '')
call eclim#java#impl#ImplWindow(command)
endfunction " }}}
function! eclim#java#impl#ImplWindow(command) " {{{
if (eclim#java#impl#Window(a:command, "impl"))
nnoremap <silent> <buffer> <cr> :call <SID>AddImpl(0)<cr>
vnoremap <silent> <buffer> <cr> :<C-U>call <SID>AddImpl(1)<cr>
endif
endfunction " }}}
function! eclim#java#impl#ImplWindowFolding() " {{{
setlocal foldmethod=syntax
setlocal foldlevel=99
endfunction " }}}
function! eclim#java#impl#Delegate() " {{{
if !eclim#project#util#IsCurrentFileInProject()
return
endif
call eclim#lang#SilentUpdate()
let project = eclim#project#util#GetCurrentProjectName()
let file = eclim#project#util#GetProjectRelativeFilePath()
let offset = eclim#util#GetCurrentElementOffset()
let encoding = eclim#util#GetEncoding()
let command = s:command_delegate
let command = substitute(command, '<project>', project, '')
let command = substitute(command, '<file>', file, '')
let command = substitute(command, '<offset>', offset, '')
let command = substitute(command, '<encoding>', encoding, '')
call eclim#java#impl#DelegateWindow(command)
endfunction " }}}
function! eclim#java#impl#DelegateWindow(command) " {{{
if (eclim#java#impl#Window(a:command, "delegate"))
nnoremap <silent> <buffer> <cr> :call <SID>AddDelegate(0)<cr>
vnoremap <silent> <buffer> <cr> :<C-U>call <SID>AddDelegate(1)<cr>
endif
endfunction " }}}
function! eclim#java#impl#Add(command, function, visual) " {{{
let winnr = bufwinnr(bufnr('^' . b:filename))
" src window is not longer open.
if winnr == -1
call eclim#util#EchoError(b:filename . ' no longer found in an open window.')
return
endif
if a:visual
let start = line("'<")
let end = line("'>")
endif
let superType = ""
let methods = []
" non-visual mode or only one line selected
if !a:visual || start == end
" not a valid selection
if line('.') == 1 || getline('.') =~ '^\(\s*//\|package\|$\|}\)'
return
endif
let line = getline('.')
if line =~ '^\s*throws'
let line = getline(line('.') - 1)
endif
" on a method line
if line =~ '^\s\+'
call add(methods, s:MethodSig(line))
let ln = search('^\w', 'bWn')
if ln > 0
let superType = substitute(getline(ln), '.*\s\(.*\) {', '\1', '')
endif
" on a type line
else
let superType = substitute(line, '.*\s\(.*\) {', '\1', '')
endif
" visual mode
else
let pos = getpos('.')
let index = start
while index <= end
let line = getline(index)
if line =~ '^\s*\($\|throws\|package\)'
" do nothing
" on a method line
elseif line =~ '^\s\+'
call add(methods, s:MethodSig(line))
call cursor(index, 1)
let ln = search('^\w', 'bWn')
if ln > 0
let super = substitute(getline(ln), '.*\s\(.*\) {', '\1', '')
if superType != "" && super != superType
call eclim#util#EchoError(s:cross_type_selection)
call setpos('.', pos)
return
endif
let superType = super
endif
" on a type line
else
let super = substitute(line, '.*\s\(.*\) {', '\1', '')
if superType != "" && super != superType
call eclim#util#EchoError(s:cross_type_selection)
call setpos('.', pos)
return
endif
let superType = super
endif
call setpos('.', pos)
let index += 1
endwhile
if superType == ""
return
endif
endif
" search up for the nearest package
let ln = search('^package', 'bWn')
if ln > 0
let package = substitute(getline(ln), '.*\s\(.*\);', '\1', '')
let superType = package . '.' . substitute(superType, '<.\{-}>', '', 'g')
endif
let type = getline(1)
let impl_winnr = winnr()
exec winnr . "winc w"
call eclim#lang#SilentUpdate()
let project = eclim#project#util#GetCurrentProjectName()
let file = eclim#project#util#GetProjectRelativeFilePath()
let command = a:command
let command = substitute(command, '<project>', project, '')
let command = substitute(command, '<file>', file, '')
let command = substitute(command, '<type>', type, '')
let command = substitute(command, '<superType>', superType, '')
if len(methods)
let json = substitute(string(methods), "'", '"', 'g')
let command = substitute(command, '<methods>', '-m ''' . json . '''', '')
else
let command = substitute(command, '<methods>', '', '')
endif
call a:function(command)
noautocmd exec winnr . "winc w"
call eclim#util#Reload({'retab': 1})
write
noautocmd exec impl_winnr . "winc w"
endfunction " }}}
function! eclim#java#impl#Window(command, name) " {{{
let matches = matchlist(a:command, '-o \([0-9]*\)')
let offset = len(matches) > 1 ? matches[1] : 0
let name = eclim#project#util#GetProjectRelativeFilePath() . '_' . a:name
let project = eclim#project#util#GetCurrentProjectName()
let result = eclim#Execute(a:command, {'project': project})
if type(result) == g:STRING_TYPE
call eclim#util#EchoError(result)
return
endif
if type(result) != g:DICT_TYPE
return
endif
let content = [result.type]
for super in result.superTypes
call add(content, '')
call add(content, 'package ' . super.packageName . ';')
call add(content, super.signature . ' {')
for method in super.methods
let signature = split(method, '\n')
let content += map(signature, '"\t" . v:val')
endfor
call add(content, '}')
endfor
call eclim#util#TempWindow(name, content, {'preserveCursor': 1})
setlocal ft=java
call eclim#java#impl#ImplWindowFolding()
let b:eclim_offset = offset
return 1
endfunction " }}}
function! s:AddImpl(visual) " {{{
let command = s:command_impl_insert
if g:EclimJavaImplInsertAtCursor
let command .= ' -o ' . b:eclim_offset
endif
call eclim#java#impl#Add
\ (command, function("eclim#java#impl#ImplWindow"), a:visual)
endfunction " }}}
function! s:AddDelegate(visual) " {{{
call eclim#java#impl#Add
\ (s:command_delegate_insert, function("eclim#java#impl#DelegateWindow"), a:visual)
endfunction " }}}
function! s:MethodSig(line) " {{{
let sig = substitute(a:line, '.*\s\(\w\+(.*\)', '\1', '')
let sig = substitute(sig, ',\s', ',', 'g')
let sig = substitute(sig, '<.\{-}>', '', 'g')
return sig
endfunction " }}}
" vim:ft=vim:fdm=marker