aboutsummaryrefslogtreecommitdiff
path: root/runtime/ftplugin/java.vim
diff options
context:
space:
mode:
authorJosh Rahm <joshuarahm@gmail.com>2025-02-05 23:09:29 +0000
committerJosh Rahm <joshuarahm@gmail.com>2025-02-05 23:09:29 +0000
commitd5f194ce780c95821a855aca3c19426576d28ae0 (patch)
treed45f461b19f9118ad2bb1f440a7a08973ad18832 /runtime/ftplugin/java.vim
parentc5d770d311841ea5230426cc4c868e8db27300a8 (diff)
parent44740e561fc93afe3ebecfd3618bda2d2abeafb0 (diff)
downloadrneovim-rahm.tar.gz
rneovim-rahm.tar.bz2
rneovim-rahm.zip
Merge remote-tracking branch 'upstream/master' into mix_20240309HEADrahm
Diffstat (limited to 'runtime/ftplugin/java.vim')
-rw-r--r--runtime/ftplugin/java.vim282
1 files changed, 278 insertions, 4 deletions
diff --git a/runtime/ftplugin/java.vim b/runtime/ftplugin/java.vim
index 55b358374f..cfd25bce6c 100644
--- a/runtime/ftplugin/java.vim
+++ b/runtime/ftplugin/java.vim
@@ -3,7 +3,7 @@
" Maintainer: Aliaksei Budavei <0x000c70 AT gmail DOT com>
" Former Maintainer: Dan Sharp
" Repository: https://github.com/zzzyxwvut/java-vim.git
-" Last Change: 2024 Sep 26
+" Last Change: 2024 Dec 25
" 2024 Jan 14 by Vim Project (browsefilter)
" 2024 May 23 by Riley Bruins <ribru17@gmail.com> ('commentstring')
@@ -90,10 +90,269 @@ if (has("gui_win32") || has("gui_gtk")) && !exists("b:browsefilter")
endif
endif
+"""" Support pre- and post-compiler actions for SpotBugs.
+if (!empty(get(g:, 'spotbugs_properties', {})) ||
+ \ !empty(get(b:, 'spotbugs_properties', {}))) &&
+ \ filereadable($VIMRUNTIME . '/compiler/spotbugs.vim')
+
+ function! s:SpotBugsGetProperty(name, default) abort
+ return get(
+ \ {s:spotbugs_properties_scope}spotbugs_properties,
+ \ a:name,
+ \ a:default)
+ endfunction
+
+ function! s:SpotBugsHasProperty(name) abort
+ return has_key(
+ \ {s:spotbugs_properties_scope}spotbugs_properties,
+ \ a:name)
+ endfunction
+
+ function! s:SpotBugsGetProperties() abort
+ return {s:spotbugs_properties_scope}spotbugs_properties
+ endfunction
+
+ " Work around ":bar"s and ":autocmd"s.
+ function! JavaFileTypeExecuteActionOnce(cleanup_cmd, action_cmd) abort
+ try
+ execute a:cleanup_cmd
+ finally
+ execute a:action_cmd
+ endtry
+ endfunction
+
+ if exists("b:spotbugs_properties")
+ let s:spotbugs_properties_scope = 'b:'
+
+ " Merge global entries, if any, in buffer-local entries, favouring
+ " defined buffer-local ones.
+ call extend(
+ \ b:spotbugs_properties,
+ \ get(g:, 'spotbugs_properties', {}),
+ \ 'keep')
+ elseif exists("g:spotbugs_properties")
+ let s:spotbugs_properties_scope = 'g:'
+ endif
+
+ let s:commands = {}
+
+ for s:name in ['DefaultPreCompilerCommand',
+ \ 'DefaultPreCompilerTestCommand',
+ \ 'DefaultPostCompilerCommand']
+ if s:SpotBugsHasProperty(s:name)
+ let s:commands[s:name] = remove(
+ \ s:SpotBugsGetProperties(),
+ \ s:name)
+ endif
+ endfor
+
+ if s:SpotBugsHasProperty('compiler')
+ " XXX: Postpone loading the script until all state, if any, has been
+ " collected.
+ if !empty(s:commands)
+ let g:spotbugs#state = {
+ \ 'compiler': remove(s:SpotBugsGetProperties(), 'compiler'),
+ \ 'commands': copy(s:commands),
+ \ }
+ else
+ let g:spotbugs#state = {
+ \ 'compiler': remove(s:SpotBugsGetProperties(), 'compiler'),
+ \ }
+ endif
+
+ " Merge default entries in global (or buffer-local) entries, favouring
+ " defined global (or buffer-local) ones.
+ call extend(
+ \ {s:spotbugs_properties_scope}spotbugs_properties,
+ \ spotbugs#DefaultProperties(),
+ \ 'keep')
+ elseif !empty(s:commands)
+ " XXX: Postpone loading the script until all state, if any, has been
+ " collected.
+ let g:spotbugs#state = {'commands': copy(s:commands)}
+ endif
+
+ unlet s:commands s:name
+ let s:request = 0
+
+ if s:SpotBugsHasProperty('PostCompilerAction')
+ let s:request += 4
+ endif
+
+ if s:SpotBugsHasProperty('PreCompilerTestAction')
+ let s:dispatcher = printf('call call(%s, [])',
+ \ string(s:SpotBugsGetProperties().PreCompilerTestAction))
+ let s:request += 2
+ endif
+
+ if s:SpotBugsHasProperty('PreCompilerAction')
+ let s:dispatcher = printf('call call(%s, [])',
+ \ string(s:SpotBugsGetProperties().PreCompilerAction))
+ let s:request += 1
+ endif
+
+ " Adapt the tests for "s:FindClassFiles()" from "compiler/spotbugs.vim".
+ if (s:request == 3 || s:request == 7) &&
+ \ (!empty(s:SpotBugsGetProperty('sourceDirPath', [])) &&
+ \ !empty(s:SpotBugsGetProperty('classDirPath', [])) &&
+ \ !empty(s:SpotBugsGetProperty('testSourceDirPath', [])) &&
+ \ !empty(s:SpotBugsGetProperty('testClassDirPath', [])))
+ function! s:DispatchAction(paths_action_pairs) abort
+ let name = expand('%:p')
+
+ for [paths, Action] in a:paths_action_pairs
+ for path in paths
+ if name =~# (path . '.\{-}\.java\=$')
+ call Action()
+ return
+ endif
+ endfor
+ endfor
+ endfunction
+
+ let s:dir_cnt = min([
+ \ len(s:SpotBugsGetProperties().sourceDirPath),
+ \ len(s:SpotBugsGetProperties().classDirPath)])
+ let s:test_dir_cnt = min([
+ \ len(s:SpotBugsGetProperties().testSourceDirPath),
+ \ len(s:SpotBugsGetProperties().testClassDirPath)])
+
+ " Do not break up path pairs with filtering!
+ let s:dispatcher = printf('call s:DispatchAction(%s)',
+ \ string([[s:SpotBugsGetProperties().sourceDirPath[0 : s:dir_cnt - 1],
+ \ s:SpotBugsGetProperties().PreCompilerAction],
+ \ [s:SpotBugsGetProperties().testSourceDirPath[0 : s:test_dir_cnt - 1],
+ \ s:SpotBugsGetProperties().PreCompilerTestAction]]))
+ unlet s:test_dir_cnt s:dir_cnt
+ endif
+
+ if exists("s:dispatcher")
+ function! s:ExecuteActions(pre_action, post_action) abort
+ try
+ execute a:pre_action
+ catch /\<E42:/
+ execute a:post_action
+ endtry
+ endfunction
+ endif
+
+ if s:request
+ if exists("b:spotbugs_syntax_once") || empty(join(getline(1, 8), ''))
+ let s:actions = [{'event': 'User'}]
+ else
+ " XXX: Handle multiple FileType events when vimrc contains more
+ " than one filetype setting for the language, e.g.:
+ " :filetype plugin indent on
+ " :autocmd BufRead,BufNewFile *.java setlocal filetype=java ...
+ " XXX: DO NOT ADD b:spotbugs_syntax_once TO b:undo_ftplugin !
+ let b:spotbugs_syntax_once = 1
+ let s:actions = [{
+ \ 'event': 'Syntax',
+ \ 'once': 1,
+ \ }, {
+ \ 'event': 'User',
+ \ }]
+ endif
+
+ for s:idx in range(len(s:actions))
+ if s:request == 7 || s:request == 6 || s:request == 5
+ let s:actions[s:idx].cmd = printf('call s:ExecuteActions(%s, %s)',
+ \ string(s:dispatcher),
+ \ string(printf('compiler spotbugs | call call(%s, [])',
+ \ string(s:SpotBugsGetProperties().PostCompilerAction))))
+ elseif s:request == 4
+ let s:actions[s:idx].cmd = printf(
+ \ 'compiler spotbugs | call call(%s, [])',
+ \ string(s:SpotBugsGetProperties().PostCompilerAction))
+ elseif s:request == 3 || s:request == 2 || s:request == 1
+ let s:actions[s:idx].cmd = printf('call s:ExecuteActions(%s, %s)',
+ \ string(s:dispatcher),
+ \ string('compiler spotbugs'))
+ else
+ let s:actions[s:idx].cmd = ''
+ endif
+ endfor
+
+ if !exists("#java_spotbugs")
+ augroup java_spotbugs
+ augroup END
+ endif
+
+ " The events are defined in s:actions.
+ silent! autocmd! java_spotbugs User <buffer>
+ silent! autocmd! java_spotbugs Syntax <buffer>
+
+ for s:action in s:actions
+ if has_key(s:action, 'once')
+ execute printf('autocmd java_spotbugs %s <buffer> ' .
+ \ 'call JavaFileTypeExecuteActionOnce(%s, %s)',
+ \ s:action.event,
+ \ string(printf('autocmd! java_spotbugs %s <buffer>',
+ \ s:action.event)),
+ \ string(s:action.cmd))
+ else
+ execute printf('autocmd java_spotbugs %s <buffer> %s',
+ \ s:action.event,
+ \ s:action.cmd)
+ endif
+ endfor
+
+ if s:SpotBugsHasProperty('PostCompilerActionExecutor') &&
+ \ (s:request == 7 || s:request == 6 ||
+ \ s:request == 5 || s:request == 4)
+ let s:augroup = s:SpotBugsGetProperty(
+ \ 'augroupForPostCompilerAction',
+ \ 'java_spotbugs_post')
+ let s:augroup = !empty(s:augroup) ? s:augroup : 'java_spotbugs_post'
+
+ for s:candidate in ['java_spotbugs_post', s:augroup]
+ if !exists("#" . s:candidate)
+ execute printf('augroup %s | augroup END', s:candidate)
+ endif
+ endfor
+
+ silent! autocmd! java_spotbugs_post User <buffer>
+
+ " Define a User ":autocmd" to define a once-only ShellCmdPost
+ " ":autocmd" that will invoke "PostCompilerActionExecutor" and let
+ " it decide whether to proceed with ":compiler spotbugs" etc.; and
+ " seek explicit synchronisation with ":doautocmd ShellCmdPost" by
+ " omitting "nested" for "java_spotbugs_post" and "java_spotbugs".
+ execute printf('autocmd java_spotbugs_post User <buffer> ' .
+ \ 'call JavaFileTypeExecuteActionOnce(%s, %s)',
+ \ string(printf('autocmd! %s ShellCmdPost <buffer>', s:augroup)),
+ \ string(printf('autocmd %s ShellCmdPost <buffer> ' .
+ \ 'call JavaFileTypeExecuteActionOnce(%s, %s)',
+ \ s:augroup,
+ \ string(printf('autocmd! %s ShellCmdPost <buffer>', s:augroup)),
+ \ string(printf('call call(%s, [%s])',
+ \ string(s:SpotBugsGetProperties().PostCompilerActionExecutor),
+ \ string(printf('compiler spotbugs | call call(%s, [])',
+ \ string(s:SpotBugsGetProperties().PostCompilerAction))))))))
+ endif
+
+ unlet! s:candidate s:augroup s:action s:actions s:idx s:dispatcher
+ endif
+
+ delfunction s:SpotBugsGetProperties
+ delfunction s:SpotBugsHasProperty
+ delfunction s:SpotBugsGetProperty
+ unlet! s:request s:spotbugs_properties_scope
+endif
+
+function! JavaFileTypeCleanUp() abort
+ setlocal suffixes< suffixesadd< formatoptions< comments< commentstring< path< includeexpr<
+ unlet! b:browsefilter
+
+ " The concatenated ":autocmd" removals may be misparsed as an ":autocmd".
+ " A _once-only_ ShellCmdPost ":autocmd" is always a call-site definition.
+ silent! autocmd! java_spotbugs User <buffer>
+ silent! autocmd! java_spotbugs Syntax <buffer>
+ silent! autocmd! java_spotbugs_post User <buffer>
+endfunction
+
" Undo the stuff we changed.
-let b:undo_ftplugin = "setlocal suffixes< suffixesadd<" .
- \ " formatoptions< comments< commentstring< path< includeexpr<" .
- \ " | unlet! b:browsefilter"
+let b:undo_ftplugin = 'call JavaFileTypeCleanUp() | delfunction JavaFileTypeCleanUp'
" See ":help vim9-mix".
if !has("vim9script")
@@ -114,6 +373,21 @@ if exists("s:zip_func_upgradable")
setlocal suffixesadd<
endif
+if exists("*s:DispatchAction")
+ def! s:DispatchAction(paths_action_pairs: list<list<any>>)
+ const name: string = expand('%:p')
+
+ for [paths: list<string>, Action: func: any] in paths_action_pairs
+ for path in paths
+ if name =~# (path .. '.\{-}\.java\=$')
+ Action()
+ return
+ endif
+ endfor
+ endfor
+ enddef
+endif
+
" Restore the saved compatibility options.
let &cpo = s:save_cpo
unlet s:save_cpo