xref: /vim-8.2.3635/runtime/indent/java.vim (revision 818c9e7e)
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 May 18
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
32let s:keepcpo= &cpo
33set cpo&vim
34
35function! SkipJavaBlanksAndComments(startline)
36  let lnum = a:startline
37  while lnum > 1
38    let lnum = prevnonblank(lnum)
39    if getline(lnum) =~ '\*/\s*$'
40      while getline(lnum) !~ '/\*' && lnum > 1
41        let lnum = lnum - 1
42      endwhile
43      if getline(lnum) =~ '^\s*/\*'
44        let lnum = lnum - 1
45      else
46        break
47      endif
48    elseif getline(lnum) =~ '^\s*//'
49      let lnum = lnum - 1
50    else
51      break
52    endif
53  endwhile
54  return lnum
55endfunction
56
57function GetJavaIndent()
58
59  " Java is just like C; use the built-in C indenting and then correct a few
60  " specific cases.
61  let theIndent = cindent(v:lnum)
62
63  " If we're in the middle of a comment then just trust cindent
64  if getline(v:lnum) =~ '^\s*\*'
65    return theIndent
66  endif
67
68  " find start of previous line, in case it was a continuation line
69  let lnum = SkipJavaBlanksAndComments(v:lnum - 1)
70
71  " If the previous line starts with '@', we should have the same indent as
72  " the previous one
73  if getline(lnum) =~ '^\s*@\S\+\s*$'
74    return indent(lnum)
75  endif
76
77  let prev = lnum
78  while prev > 1
79    let next_prev = SkipJavaBlanksAndComments(prev - 1)
80    if getline(next_prev) !~ ',\s*$'
81      break
82    endif
83    let prev = next_prev
84  endwhile
85
86  " Try to align "throws" lines for methods and "extends" and "implements" for
87  " classes.
88  if getline(v:lnum) =~ '^\s*\(extends\|implements\)\>'
89        \ && getline(lnum) !~ '^\s*\(extends\|implements\)\>'
90    let theIndent = theIndent + &sw
91  endif
92
93  " correct for continuation lines of "throws", "implements" and "extends"
94  let cont_kw = matchstr(getline(prev),
95        \ '^\s*\zs\(throws\|implements\|extends\)\>\ze.*,\s*$')
96  if strlen(cont_kw) > 0
97    let amount = strlen(cont_kw) + 1
98    if getline(lnum) !~ ',\s*$'
99      let theIndent = theIndent - (amount + &sw)
100      if theIndent < 0
101        let theIndent = 0
102      endif
103    elseif prev == lnum
104      let theIndent = theIndent + amount
105      if cont_kw ==# 'throws'
106        let theIndent = theIndent + &sw
107      endif
108    endif
109  elseif getline(prev) =~ '^\s*\(throws\|implements\|extends\)\>'
110        \ && (getline(prev) =~ '{\s*$'
111        \  || getline(v:lnum) =~ '^\s*{\s*$')
112    let theIndent = theIndent - &sw
113  endif
114
115  " When the line starts with a }, try aligning it with the matching {,
116  " skipping over "throws", "extends" and "implements" clauses.
117  if getline(v:lnum) =~ '^\s*}\s*\(//.*\|/\*.*\)\=$'
118    call cursor(v:lnum, 1)
119    silent normal %
120    let lnum = line('.')
121    if lnum < v:lnum
122      while lnum > 1
123        let next_lnum = SkipJavaBlanksAndComments(lnum - 1)
124        if getline(lnum) !~ '^\s*\(throws\|extends\|implements\)\>'
125              \ && getline(next_lnum) !~ ',\s*$'
126          break
127        endif
128        let lnum = prevnonblank(next_lnum)
129      endwhile
130      return indent(lnum)
131    endif
132  endif
133
134  " Below a line starting with "}" never indent more.  Needed for a method
135  " below a method with an indented "throws" clause.
136  let lnum = SkipJavaBlanksAndComments(v:lnum - 1)
137  if getline(lnum) =~ '^\s*}\s*\(//.*\|/\*.*\)\=$' && indent(lnum) < theIndent
138    let theIndent = indent(lnum)
139  endif
140
141  return theIndent
142endfunction
143
144let &cpo = s:keepcpo
145unlet s:keepcpo
146
147" vi: sw=2 et
148