xref: /vim-8.2.3635/runtime/indent/java.vim (revision 071d4279)
1" Vim indent file
2" Language:	Java
3" Maintainer:	Toby Allsopp <[email protected]>
4" Last Change:	2003 Oct 21
5
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
129