1" Vim indent file 2" Language: Java 3" Previous Maintainer: Toby Allsopp <[email protected]> 4" Current Maintainer: Hong Xu <[email protected]> 5" Last Change: 2012 Jan 20 6" Version: 1.0 7" License: Same as Vim. 8" Copyright (c) 2012 Hong Xu 9" Before 2012, this file is maintained by Toby Allsopp. 10 11" Only load this indent file when no other was loaded. 12if exists("b:did_indent") 13 finish 14endif 15let b:did_indent = 1 16 17" Indent Java anonymous classes correctly. 18setlocal cindent cinoptions& cinoptions+=j1 19 20" The "extends" and "implements" lines start off with the wrong indent. 21setlocal indentkeys& indentkeys+=0=extends indentkeys+=0=implements 22 23" Set the function to do the work. 24setlocal indentexpr=GetJavaIndent() 25 26let b:undo_indent = "set cin< cino< indentkeys< indentexpr<" 27 28" Only define the function once. 29if exists("*GetJavaIndent") 30 finish 31endif 32 33function! SkipJavaBlanksAndComments(startline) 34 let lnum = a:startline 35 while lnum > 1 36 let lnum = prevnonblank(lnum) 37 if getline(lnum) =~ '\*/\s*$' 38 while getline(lnum) !~ '/\*' && lnum > 1 39 let lnum = lnum - 1 40 endwhile 41 if getline(lnum) =~ '^\s*/\*' 42 let lnum = lnum - 1 43 else 44 break 45 endif 46 elseif getline(lnum) =~ '^\s*//' 47 let lnum = lnum - 1 48 else 49 break 50 endif 51 endwhile 52 return lnum 53endfunction 54 55function GetJavaIndent() 56 57 " Java is just like C; use the built-in C indenting and then correct a few 58 " specific cases. 59 let theIndent = cindent(v:lnum) 60 61 " If we're in the middle of a comment then just trust cindent 62 if getline(v:lnum) =~ '^\s*\*' 63 return theIndent 64 endif 65 66 " find start of previous line, in case it was a continuation line 67 let lnum = SkipJavaBlanksAndComments(v:lnum - 1) 68 69 " If the previous line starts with '@', we should have the same indent as 70 " the previous one 71 if getline(lnum) =~ '^\s*@\S\+\s*$' 72 return indent(lnum) 73 endif 74 75 let prev = lnum 76 while prev > 1 77 let next_prev = SkipJavaBlanksAndComments(prev - 1) 78 if getline(next_prev) !~ ',\s*$' 79 break 80 endif 81 let prev = next_prev 82 endwhile 83 84 " Try to align "throws" lines for methods and "extends" and "implements" for 85 " classes. 86 if getline(v:lnum) =~ '^\s*\(extends\|implements\)\>' 87 \ && getline(lnum) !~ '^\s*\(extends\|implements\)\>' 88 let theIndent = theIndent + &sw 89 endif 90 91 " correct for continuation lines of "throws", "implements" and "extends" 92 let cont_kw = matchstr(getline(prev), 93 \ '^\s*\zs\(throws\|implements\|extends\)\>\ze.*,\s*$') 94 if strlen(cont_kw) > 0 95 let amount = strlen(cont_kw) + 1 96 if getline(lnum) !~ ',\s*$' 97 let theIndent = theIndent - (amount + &sw) 98 if theIndent < 0 99 let theIndent = 0 100 endif 101 elseif prev == lnum 102 let theIndent = theIndent + amount 103 if cont_kw ==# 'throws' 104 let theIndent = theIndent + &sw 105 endif 106 endif 107 elseif getline(prev) =~ '^\s*\(throws\|implements\|extends\)\>' 108 \ && (getline(prev) =~ '{\s*$' 109 \ || getline(v:lnum) =~ '^\s*{\s*$') 110 let theIndent = theIndent - &sw 111 endif 112 113 " When the line starts with a }, try aligning it with the matching {, 114 " skipping over "throws", "extends" and "implements" clauses. 115 if getline(v:lnum) =~ '^\s*}\s*\(//.*\|/\*.*\)\=$' 116 call cursor(v:lnum, 1) 117 silent normal % 118 let lnum = line('.') 119 if lnum < v:lnum 120 while lnum > 1 121 let next_lnum = SkipJavaBlanksAndComments(lnum - 1) 122 if getline(lnum) !~ '^\s*\(throws\|extends\|implements\)\>' 123 \ && getline(next_lnum) !~ ',\s*$' 124 break 125 endif 126 let lnum = prevnonblank(next_lnum) 127 endwhile 128 return indent(lnum) 129 endif 130 endif 131 132 " Below a line starting with "}" never indent more. Needed for a method 133 " below a method with an indented "throws" clause. 134 let lnum = SkipJavaBlanksAndComments(v:lnum - 1) 135 if getline(lnum) =~ '^\s*}\s*\(//.*\|/\*.*\)\=$' && indent(lnum) < theIndent 136 let theIndent = indent(lnum) 137 endif 138 139 return theIndent 140endfunction 141 142" vi: sw=2 et 143