xref: /vim-8.2.3635/runtime/indent/java.vim (revision 6be7f873)
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