xref: /vim-8.2.3635/runtime/indent/java.vim (revision 036986f1)
1071d4279SBram Moolenaar" Vim indent file
2071d4279SBram Moolenaar" Language:	Java
36be7f873SBram Moolenaar" Previous Maintainer: Toby Allsopp <[email protected]>
4*036986f1SBram Moolenaar" Current Maintainer: Hong Xu <[email protected]>
5*036986f1SBram Moolenaar" Homepage: http://www.vim.org/scripts/script.php?script_id=3899
6*036986f1SBram Moolenaar"           https://github.com/xuhdev/indent-java.vim
7*036986f1SBram Moolenaar" Last Change:	2016 Mar 7
8*036986f1SBram Moolenaar" Version: 1.1
96be7f873SBram Moolenaar" License: Same as Vim.
10*036986f1SBram Moolenaar" Copyright (c) 2012-2016 Hong Xu
11*036986f1SBram Moolenaar" Before 2012, this file was maintained by Toby Allsopp.
12071d4279SBram Moolenaar
13071d4279SBram Moolenaar" Only load this indent file when no other was loaded.
14071d4279SBram Moolenaarif exists("b:did_indent")
15071d4279SBram Moolenaar  finish
16071d4279SBram Moolenaarendif
17071d4279SBram Moolenaarlet b:did_indent = 1
18071d4279SBram Moolenaar
19071d4279SBram Moolenaar" Indent Java anonymous classes correctly.
20b982ca5cSBram Moolenaarsetlocal cindent cinoptions& cinoptions+=j1
21071d4279SBram Moolenaar
22071d4279SBram Moolenaar" The "extends" and "implements" lines start off with the wrong indent.
23071d4279SBram Moolenaarsetlocal indentkeys& indentkeys+=0=extends indentkeys+=0=implements
24071d4279SBram Moolenaar
25071d4279SBram Moolenaar" Set the function to do the work.
26071d4279SBram Moolenaarsetlocal indentexpr=GetJavaIndent()
27071d4279SBram Moolenaar
28b982ca5cSBram Moolenaarlet b:undo_indent = "set cin< cino< indentkeys< indentexpr<"
29b982ca5cSBram Moolenaar
30071d4279SBram Moolenaar" Only define the function once.
31071d4279SBram Moolenaarif exists("*GetJavaIndent")
32071d4279SBram Moolenaar  finish
33071d4279SBram Moolenaarendif
34*036986f1SBram Moolenaar
358e52a593SBram Moolenaarlet s:keepcpo= &cpo
368e52a593SBram Moolenaarset cpo&vim
37071d4279SBram Moolenaar
38071d4279SBram Moolenaarfunction! SkipJavaBlanksAndComments(startline)
39071d4279SBram Moolenaar  let lnum = a:startline
40071d4279SBram Moolenaar  while lnum > 1
41071d4279SBram Moolenaar    let lnum = prevnonblank(lnum)
42071d4279SBram Moolenaar    if getline(lnum) =~ '\*/\s*$'
43071d4279SBram Moolenaar      while getline(lnum) !~ '/\*' && lnum > 1
44071d4279SBram Moolenaar        let lnum = lnum - 1
45071d4279SBram Moolenaar      endwhile
46071d4279SBram Moolenaar      if getline(lnum) =~ '^\s*/\*'
47071d4279SBram Moolenaar        let lnum = lnum - 1
48071d4279SBram Moolenaar      else
49071d4279SBram Moolenaar        break
50071d4279SBram Moolenaar      endif
51071d4279SBram Moolenaar    elseif getline(lnum) =~ '^\s*//'
52071d4279SBram Moolenaar      let lnum = lnum - 1
53071d4279SBram Moolenaar    else
54071d4279SBram Moolenaar      break
55071d4279SBram Moolenaar    endif
56071d4279SBram Moolenaar  endwhile
57071d4279SBram Moolenaar  return lnum
58071d4279SBram Moolenaarendfunction
59071d4279SBram Moolenaar
60071d4279SBram Moolenaarfunction GetJavaIndent()
61071d4279SBram Moolenaar
62071d4279SBram Moolenaar  " Java is just like C; use the built-in C indenting and then correct a few
63071d4279SBram Moolenaar  " specific cases.
64071d4279SBram Moolenaar  let theIndent = cindent(v:lnum)
65071d4279SBram Moolenaar
66071d4279SBram Moolenaar  " If we're in the middle of a comment then just trust cindent
67071d4279SBram Moolenaar  if getline(v:lnum) =~ '^\s*\*'
68071d4279SBram Moolenaar    return theIndent
69071d4279SBram Moolenaar  endif
70071d4279SBram Moolenaar
71071d4279SBram Moolenaar  " find start of previous line, in case it was a continuation line
72071d4279SBram Moolenaar  let lnum = SkipJavaBlanksAndComments(v:lnum - 1)
736be7f873SBram Moolenaar
746be7f873SBram Moolenaar  " If the previous line starts with '@', we should have the same indent as
756be7f873SBram Moolenaar  " the previous one
76*036986f1SBram Moolenaar  if getline(lnum) =~ '^\s*@.*$'
776be7f873SBram Moolenaar    return indent(lnum)
786be7f873SBram Moolenaar  endif
796be7f873SBram Moolenaar
80071d4279SBram Moolenaar  let prev = lnum
81071d4279SBram Moolenaar  while prev > 1
82071d4279SBram Moolenaar    let next_prev = SkipJavaBlanksAndComments(prev - 1)
83071d4279SBram Moolenaar    if getline(next_prev) !~ ',\s*$'
84071d4279SBram Moolenaar      break
85071d4279SBram Moolenaar    endif
86071d4279SBram Moolenaar    let prev = next_prev
87071d4279SBram Moolenaar  endwhile
88071d4279SBram Moolenaar
89071d4279SBram Moolenaar  " Try to align "throws" lines for methods and "extends" and "implements" for
90071d4279SBram Moolenaar  " classes.
91*036986f1SBram Moolenaar  if getline(v:lnum) =~ '^\s*\(throws\|extends\|implements\)\>'
92*036986f1SBram Moolenaar        \ && getline(lnum) !~ '^\s*\(throws\|extends\|implements\)\>'
93*036986f1SBram Moolenaar    let theIndent = theIndent + shiftwidth()
94071d4279SBram Moolenaar  endif
95071d4279SBram Moolenaar
96071d4279SBram Moolenaar  " correct for continuation lines of "throws", "implements" and "extends"
97071d4279SBram Moolenaar  let cont_kw = matchstr(getline(prev),
98071d4279SBram Moolenaar        \ '^\s*\zs\(throws\|implements\|extends\)\>\ze.*,\s*$')
99071d4279SBram Moolenaar  if strlen(cont_kw) > 0
100071d4279SBram Moolenaar    let amount = strlen(cont_kw) + 1
101071d4279SBram Moolenaar    if getline(lnum) !~ ',\s*$'
102*036986f1SBram Moolenaar      let theIndent = theIndent - (amount + shiftwidth())
103071d4279SBram Moolenaar      if theIndent < 0
104071d4279SBram Moolenaar        let theIndent = 0
105071d4279SBram Moolenaar      endif
106071d4279SBram Moolenaar    elseif prev == lnum
107071d4279SBram Moolenaar      let theIndent = theIndent + amount
108071d4279SBram Moolenaar      if cont_kw ==# 'throws'
109*036986f1SBram Moolenaar        let theIndent = theIndent + shiftwidth()
110071d4279SBram Moolenaar      endif
111071d4279SBram Moolenaar    endif
112071d4279SBram Moolenaar  elseif getline(prev) =~ '^\s*\(throws\|implements\|extends\)\>'
113071d4279SBram Moolenaar        \ && (getline(prev) =~ '{\s*$'
114071d4279SBram Moolenaar        \  || getline(v:lnum) =~ '^\s*{\s*$')
115*036986f1SBram Moolenaar    let theIndent = theIndent - shiftwidth()
116071d4279SBram Moolenaar  endif
117071d4279SBram Moolenaar
118071d4279SBram Moolenaar  " When the line starts with a }, try aligning it with the matching {,
119071d4279SBram Moolenaar  " skipping over "throws", "extends" and "implements" clauses.
120071d4279SBram Moolenaar  if getline(v:lnum) =~ '^\s*}\s*\(//.*\|/\*.*\)\=$'
121071d4279SBram Moolenaar    call cursor(v:lnum, 1)
122*036986f1SBram Moolenaar    silent normal! %
123071d4279SBram Moolenaar    let lnum = line('.')
124071d4279SBram Moolenaar    if lnum < v:lnum
125071d4279SBram Moolenaar      while lnum > 1
126071d4279SBram Moolenaar        let next_lnum = SkipJavaBlanksAndComments(lnum - 1)
127071d4279SBram Moolenaar        if getline(lnum) !~ '^\s*\(throws\|extends\|implements\)\>'
128071d4279SBram Moolenaar              \ && getline(next_lnum) !~ ',\s*$'
129071d4279SBram Moolenaar          break
130071d4279SBram Moolenaar        endif
131071d4279SBram Moolenaar        let lnum = prevnonblank(next_lnum)
132071d4279SBram Moolenaar      endwhile
133071d4279SBram Moolenaar      return indent(lnum)
134071d4279SBram Moolenaar    endif
135071d4279SBram Moolenaar  endif
136071d4279SBram Moolenaar
137071d4279SBram Moolenaar  " Below a line starting with "}" never indent more.  Needed for a method
138071d4279SBram Moolenaar  " below a method with an indented "throws" clause.
139071d4279SBram Moolenaar  let lnum = SkipJavaBlanksAndComments(v:lnum - 1)
140071d4279SBram Moolenaar  if getline(lnum) =~ '^\s*}\s*\(//.*\|/\*.*\)\=$' && indent(lnum) < theIndent
141071d4279SBram Moolenaar    let theIndent = indent(lnum)
142071d4279SBram Moolenaar  endif
143071d4279SBram Moolenaar
144071d4279SBram Moolenaar  return theIndent
145071d4279SBram Moolenaarendfunction
146071d4279SBram Moolenaar
1478e52a593SBram Moolenaarlet &cpo = s:keepcpo
1488e52a593SBram Moolenaarunlet s:keepcpo
1498e52a593SBram Moolenaar
150071d4279SBram Moolenaar" vi: sw=2 et
151