How do I make vim indent java annotations correctly?
-
03-07-2019 - |
Question
When indenting java code with annotations, vim insists on indenting like this:
@Test
public void ...
I want the annotation to be in the same column as the method definition but I can't seem to find a way to tell vim to do that, except maybe using an indent expression but I'm not sure if I can use that together with regular cindent.
edit: The filetype plugin was already turned on I just got a bit confused about indenting plugins. The accepted answer may be a bit hackish but works for me as well.
Solution
Edit: I cannot delete my own answer because it has already been accepted, but @pydave's answer seems to be the better (more robust) solution.
You should probably be using the indentation file for the java FileType (instead of using cindent) by setting
filetype plugin indent on
.
That said, the indentation file coming with the Vim 7.1 from my linux distribution (looking at the current vim svn this is still true for 7.2) doesn't account for annotations yet. I therefore copied /usr/share/vim/vim71/indent/java.vim
(see https://vim.svn.sourceforge.net/svnroot/vim/branches/vim7.1/runtime/indent/java.vim) to ~/.vim/indent/java.vim
and added the following lines right before the end:
let lnum = prevnonblank(v:lnum - 1)
let line = getline(lnum)
if line =~ '^\s*@.*$'
let theIndent = indent(lnum)
endif
I'm not sure if this breaks any of the other indentations, but it works for me.
OTHER TIPS
You shouldn't modify the built-in vim settings. Your changes could disappear after a package upgrade. If you copy it to your .vim, then you won't get any java indent bug fixes.
Instead, put the following into a new file called ~/.vim/after/indent/java.vim
function! GetJavaIndent_improved()
let theIndent = GetJavaIndent()
let lnum = prevnonblank(v:lnum - 1)
let line = getline(lnum)
if line =~ '^\s*@.*$'
let theIndent = indent(lnum)
endif
return theIndent
endfunction
setlocal indentexpr=GetJavaIndent_improved()
That way it loads the stock java indent and only modifies the indent to remove the annotation indents.
I found pydave's suggestion almost what I wanted, but I wanted this:
@Override
public void ...
and this:
@Override public void ...
so I replaced the regex (as per pydave's, place in ~/.vim/after/indent/java.vim
):
setlocal indentexpr=GetJavaIndent_improved()
function! GetJavaIndent_improved()
let theIndent = GetJavaIndent()
let lnum = prevnonblank(v:lnum - 1)
let line = getline(lnum)
if line =~ '^\s*@[^{]*$'
let theIndent = indent(lnum)
endif
return theIndent
endfunction