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