blob: 49f8010d21e9c17d17518707e51ab2e05e54378d [file] [log] [blame]
Bram Moolenaar071d4272004-06-13 20:20:40 +00001" Vim indent file
2" Language: Java
Bram Moolenaar6be7f872012-01-20 21:08:56 +01003" Previous Maintainer: Toby Allsopp <toby.allsopp@peace.com>
Bram Moolenaar036986f2017-03-16 17:41:02 +01004" Current Maintainer: Hong Xu <hong@topbug.net>
5" Homepage: http://www.vim.org/scripts/script.php?script_id=3899
6" https://github.com/xuhdev/indent-java.vim
7" Last Change: 2016 Mar 7
8" Version: 1.1
Bram Moolenaar6be7f872012-01-20 21:08:56 +01009" License: Same as Vim.
Bram Moolenaar036986f2017-03-16 17:41:02 +010010" Copyright (c) 2012-2016 Hong Xu
11" Before 2012, this file was maintained by Toby Allsopp.
Bram Moolenaar071d4272004-06-13 20:20:40 +000012
13" Only load this indent file when no other was loaded.
14if exists("b:did_indent")
15 finish
16endif
17let b:did_indent = 1
18
19" Indent Java anonymous classes correctly.
Bram Moolenaarb982ca52005-03-28 21:02:15 +000020setlocal cindent cinoptions& cinoptions+=j1
Bram Moolenaar071d4272004-06-13 20:20:40 +000021
22" The "extends" and "implements" lines start off with the wrong indent.
23setlocal indentkeys& indentkeys+=0=extends indentkeys+=0=implements
24
25" Set the function to do the work.
26setlocal indentexpr=GetJavaIndent()
27
Bram Moolenaarb982ca52005-03-28 21:02:15 +000028let b:undo_indent = "set cin< cino< indentkeys< indentexpr<"
29
Bram Moolenaar071d4272004-06-13 20:20:40 +000030" Only define the function once.
31if exists("*GetJavaIndent")
32 finish
33endif
Bram Moolenaar036986f2017-03-16 17:41:02 +010034
Bram Moolenaar8e52a592012-05-18 21:49:28 +020035let s:keepcpo= &cpo
36set cpo&vim
Bram Moolenaar071d4272004-06-13 20:20:40 +000037
38function! SkipJavaBlanksAndComments(startline)
39 let lnum = a:startline
40 while lnum > 1
41 let lnum = prevnonblank(lnum)
42 if getline(lnum) =~ '\*/\s*$'
43 while getline(lnum) !~ '/\*' && lnum > 1
44 let lnum = lnum - 1
45 endwhile
46 if getline(lnum) =~ '^\s*/\*'
47 let lnum = lnum - 1
48 else
49 break
50 endif
51 elseif getline(lnum) =~ '^\s*//'
52 let lnum = lnum - 1
53 else
54 break
55 endif
56 endwhile
57 return lnum
58endfunction
59
60function GetJavaIndent()
61
62 " Java is just like C; use the built-in C indenting and then correct a few
63 " specific cases.
64 let theIndent = cindent(v:lnum)
65
66 " If we're in the middle of a comment then just trust cindent
67 if getline(v:lnum) =~ '^\s*\*'
68 return theIndent
69 endif
70
71 " find start of previous line, in case it was a continuation line
72 let lnum = SkipJavaBlanksAndComments(v:lnum - 1)
Bram Moolenaar6be7f872012-01-20 21:08:56 +010073
74 " If the previous line starts with '@', we should have the same indent as
75 " the previous one
Bram Moolenaar036986f2017-03-16 17:41:02 +010076 if getline(lnum) =~ '^\s*@.*$'
Bram Moolenaar6be7f872012-01-20 21:08:56 +010077 return indent(lnum)
78 endif
79
Bram Moolenaar071d4272004-06-13 20:20:40 +000080 let prev = lnum
81 while prev > 1
82 let next_prev = SkipJavaBlanksAndComments(prev - 1)
83 if getline(next_prev) !~ ',\s*$'
84 break
85 endif
86 let prev = next_prev
87 endwhile
88
89 " Try to align "throws" lines for methods and "extends" and "implements" for
90 " classes.
Bram Moolenaar036986f2017-03-16 17:41:02 +010091 if getline(v:lnum) =~ '^\s*\(throws\|extends\|implements\)\>'
92 \ && getline(lnum) !~ '^\s*\(throws\|extends\|implements\)\>'
93 let theIndent = theIndent + shiftwidth()
Bram Moolenaar071d4272004-06-13 20:20:40 +000094 endif
95
96 " correct for continuation lines of "throws", "implements" and "extends"
97 let cont_kw = matchstr(getline(prev),
98 \ '^\s*\zs\(throws\|implements\|extends\)\>\ze.*,\s*$')
99 if strlen(cont_kw) > 0
100 let amount = strlen(cont_kw) + 1
101 if getline(lnum) !~ ',\s*$'
Bram Moolenaar036986f2017-03-16 17:41:02 +0100102 let theIndent = theIndent - (amount + shiftwidth())
Bram Moolenaar071d4272004-06-13 20:20:40 +0000103 if theIndent < 0
104 let theIndent = 0
105 endif
106 elseif prev == lnum
107 let theIndent = theIndent + amount
108 if cont_kw ==# 'throws'
Bram Moolenaar036986f2017-03-16 17:41:02 +0100109 let theIndent = theIndent + shiftwidth()
Bram Moolenaar071d4272004-06-13 20:20:40 +0000110 endif
111 endif
112 elseif getline(prev) =~ '^\s*\(throws\|implements\|extends\)\>'
113 \ && (getline(prev) =~ '{\s*$'
114 \ || getline(v:lnum) =~ '^\s*{\s*$')
Bram Moolenaar036986f2017-03-16 17:41:02 +0100115 let theIndent = theIndent - shiftwidth()
Bram Moolenaar071d4272004-06-13 20:20:40 +0000116 endif
117
118 " When the line starts with a }, try aligning it with the matching {,
119 " skipping over "throws", "extends" and "implements" clauses.
120 if getline(v:lnum) =~ '^\s*}\s*\(//.*\|/\*.*\)\=$'
121 call cursor(v:lnum, 1)
Bram Moolenaar036986f2017-03-16 17:41:02 +0100122 silent normal! %
Bram Moolenaar071d4272004-06-13 20:20:40 +0000123 let lnum = line('.')
124 if lnum < v:lnum
125 while lnum > 1
126 let next_lnum = SkipJavaBlanksAndComments(lnum - 1)
127 if getline(lnum) !~ '^\s*\(throws\|extends\|implements\)\>'
128 \ && getline(next_lnum) !~ ',\s*$'
129 break
130 endif
131 let lnum = prevnonblank(next_lnum)
132 endwhile
133 return indent(lnum)
134 endif
135 endif
136
137 " Below a line starting with "}" never indent more. Needed for a method
138 " below a method with an indented "throws" clause.
139 let lnum = SkipJavaBlanksAndComments(v:lnum - 1)
140 if getline(lnum) =~ '^\s*}\s*\(//.*\|/\*.*\)\=$' && indent(lnum) < theIndent
141 let theIndent = indent(lnum)
142 endif
143
144 return theIndent
145endfunction
146
Bram Moolenaar8e52a592012-05-18 21:49:28 +0200147let &cpo = s:keepcpo
148unlet s:keepcpo
149
Bram Moolenaar071d4272004-06-13 20:20:40 +0000150" vi: sw=2 et