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