xref: /vim-8.2.3635/runtime/indent/java.vim (revision 8e52a593)
1071d4279SBram Moolenaar" Vim indent file
2071d4279SBram Moolenaar" Language:	Java
36be7f873SBram Moolenaar" Previous Maintainer: Toby Allsopp <[email protected]>
46be7f873SBram Moolenaar" Current Maintainer: Hong Xu <[email protected]>
5*8e52a593SBram Moolenaar" Last Change:	2012 May 18
66be7f873SBram Moolenaar" Version: 1.0
76be7f873SBram Moolenaar" License: Same as Vim.
86be7f873SBram Moolenaar" Copyright (c) 2012 Hong Xu
96be7f873SBram Moolenaar" Before 2012, this file is maintained by Toby Allsopp.
10071d4279SBram Moolenaar
11071d4279SBram Moolenaar" Only load this indent file when no other was loaded.
12071d4279SBram Moolenaarif exists("b:did_indent")
13071d4279SBram Moolenaar  finish
14071d4279SBram Moolenaarendif
15071d4279SBram Moolenaarlet b:did_indent = 1
16071d4279SBram Moolenaar
17071d4279SBram Moolenaar" Indent Java anonymous classes correctly.
18b982ca5cSBram Moolenaarsetlocal cindent cinoptions& cinoptions+=j1
19071d4279SBram Moolenaar
20071d4279SBram Moolenaar" The "extends" and "implements" lines start off with the wrong indent.
21071d4279SBram Moolenaarsetlocal indentkeys& indentkeys+=0=extends indentkeys+=0=implements
22071d4279SBram Moolenaar
23071d4279SBram Moolenaar" Set the function to do the work.
24071d4279SBram Moolenaarsetlocal indentexpr=GetJavaIndent()
25071d4279SBram Moolenaar
26b982ca5cSBram Moolenaarlet b:undo_indent = "set cin< cino< indentkeys< indentexpr<"
27b982ca5cSBram Moolenaar
28071d4279SBram Moolenaar" Only define the function once.
29071d4279SBram Moolenaarif exists("*GetJavaIndent")
30071d4279SBram Moolenaar  finish
31071d4279SBram Moolenaarendif
32*8e52a593SBram Moolenaarlet s:keepcpo= &cpo
33*8e52a593SBram Moolenaarset cpo&vim
34071d4279SBram Moolenaar
35071d4279SBram Moolenaarfunction! SkipJavaBlanksAndComments(startline)
36071d4279SBram Moolenaar  let lnum = a:startline
37071d4279SBram Moolenaar  while lnum > 1
38071d4279SBram Moolenaar    let lnum = prevnonblank(lnum)
39071d4279SBram Moolenaar    if getline(lnum) =~ '\*/\s*$'
40071d4279SBram Moolenaar      while getline(lnum) !~ '/\*' && lnum > 1
41071d4279SBram Moolenaar        let lnum = lnum - 1
42071d4279SBram Moolenaar      endwhile
43071d4279SBram Moolenaar      if getline(lnum) =~ '^\s*/\*'
44071d4279SBram Moolenaar        let lnum = lnum - 1
45071d4279SBram Moolenaar      else
46071d4279SBram Moolenaar        break
47071d4279SBram Moolenaar      endif
48071d4279SBram Moolenaar    elseif getline(lnum) =~ '^\s*//'
49071d4279SBram Moolenaar      let lnum = lnum - 1
50071d4279SBram Moolenaar    else
51071d4279SBram Moolenaar      break
52071d4279SBram Moolenaar    endif
53071d4279SBram Moolenaar  endwhile
54071d4279SBram Moolenaar  return lnum
55071d4279SBram Moolenaarendfunction
56071d4279SBram Moolenaar
57071d4279SBram Moolenaarfunction GetJavaIndent()
58071d4279SBram Moolenaar
59071d4279SBram Moolenaar  " Java is just like C; use the built-in C indenting and then correct a few
60071d4279SBram Moolenaar  " specific cases.
61071d4279SBram Moolenaar  let theIndent = cindent(v:lnum)
62071d4279SBram Moolenaar
63071d4279SBram Moolenaar  " If we're in the middle of a comment then just trust cindent
64071d4279SBram Moolenaar  if getline(v:lnum) =~ '^\s*\*'
65071d4279SBram Moolenaar    return theIndent
66071d4279SBram Moolenaar  endif
67071d4279SBram Moolenaar
68071d4279SBram Moolenaar  " find start of previous line, in case it was a continuation line
69071d4279SBram Moolenaar  let lnum = SkipJavaBlanksAndComments(v:lnum - 1)
706be7f873SBram Moolenaar
716be7f873SBram Moolenaar  " If the previous line starts with '@', we should have the same indent as
726be7f873SBram Moolenaar  " the previous one
736be7f873SBram Moolenaar  if getline(lnum) =~ '^\s*@\S\+\s*$'
746be7f873SBram Moolenaar    return indent(lnum)
756be7f873SBram Moolenaar  endif
766be7f873SBram Moolenaar
77071d4279SBram Moolenaar  let prev = lnum
78071d4279SBram Moolenaar  while prev > 1
79071d4279SBram Moolenaar    let next_prev = SkipJavaBlanksAndComments(prev - 1)
80071d4279SBram Moolenaar    if getline(next_prev) !~ ',\s*$'
81071d4279SBram Moolenaar      break
82071d4279SBram Moolenaar    endif
83071d4279SBram Moolenaar    let prev = next_prev
84071d4279SBram Moolenaar  endwhile
85071d4279SBram Moolenaar
86071d4279SBram Moolenaar  " Try to align "throws" lines for methods and "extends" and "implements" for
87071d4279SBram Moolenaar  " classes.
88071d4279SBram Moolenaar  if getline(v:lnum) =~ '^\s*\(extends\|implements\)\>'
89071d4279SBram Moolenaar        \ && getline(lnum) !~ '^\s*\(extends\|implements\)\>'
90071d4279SBram Moolenaar    let theIndent = theIndent + &sw
91071d4279SBram Moolenaar  endif
92071d4279SBram Moolenaar
93071d4279SBram Moolenaar  " correct for continuation lines of "throws", "implements" and "extends"
94071d4279SBram Moolenaar  let cont_kw = matchstr(getline(prev),
95071d4279SBram Moolenaar        \ '^\s*\zs\(throws\|implements\|extends\)\>\ze.*,\s*$')
96071d4279SBram Moolenaar  if strlen(cont_kw) > 0
97071d4279SBram Moolenaar    let amount = strlen(cont_kw) + 1
98071d4279SBram Moolenaar    if getline(lnum) !~ ',\s*$'
99071d4279SBram Moolenaar      let theIndent = theIndent - (amount + &sw)
100071d4279SBram Moolenaar      if theIndent < 0
101071d4279SBram Moolenaar        let theIndent = 0
102071d4279SBram Moolenaar      endif
103071d4279SBram Moolenaar    elseif prev == lnum
104071d4279SBram Moolenaar      let theIndent = theIndent + amount
105071d4279SBram Moolenaar      if cont_kw ==# 'throws'
106071d4279SBram Moolenaar        let theIndent = theIndent + &sw
107071d4279SBram Moolenaar      endif
108071d4279SBram Moolenaar    endif
109071d4279SBram Moolenaar  elseif getline(prev) =~ '^\s*\(throws\|implements\|extends\)\>'
110071d4279SBram Moolenaar        \ && (getline(prev) =~ '{\s*$'
111071d4279SBram Moolenaar        \  || getline(v:lnum) =~ '^\s*{\s*$')
112071d4279SBram Moolenaar    let theIndent = theIndent - &sw
113071d4279SBram Moolenaar  endif
114071d4279SBram Moolenaar
115071d4279SBram Moolenaar  " When the line starts with a }, try aligning it with the matching {,
116071d4279SBram Moolenaar  " skipping over "throws", "extends" and "implements" clauses.
117071d4279SBram Moolenaar  if getline(v:lnum) =~ '^\s*}\s*\(//.*\|/\*.*\)\=$'
118071d4279SBram Moolenaar    call cursor(v:lnum, 1)
119071d4279SBram Moolenaar    silent normal %
120071d4279SBram Moolenaar    let lnum = line('.')
121071d4279SBram Moolenaar    if lnum < v:lnum
122071d4279SBram Moolenaar      while lnum > 1
123071d4279SBram Moolenaar        let next_lnum = SkipJavaBlanksAndComments(lnum - 1)
124071d4279SBram Moolenaar        if getline(lnum) !~ '^\s*\(throws\|extends\|implements\)\>'
125071d4279SBram Moolenaar              \ && getline(next_lnum) !~ ',\s*$'
126071d4279SBram Moolenaar          break
127071d4279SBram Moolenaar        endif
128071d4279SBram Moolenaar        let lnum = prevnonblank(next_lnum)
129071d4279SBram Moolenaar      endwhile
130071d4279SBram Moolenaar      return indent(lnum)
131071d4279SBram Moolenaar    endif
132071d4279SBram Moolenaar  endif
133071d4279SBram Moolenaar
134071d4279SBram Moolenaar  " Below a line starting with "}" never indent more.  Needed for a method
135071d4279SBram Moolenaar  " below a method with an indented "throws" clause.
136071d4279SBram Moolenaar  let lnum = SkipJavaBlanksAndComments(v:lnum - 1)
137071d4279SBram Moolenaar  if getline(lnum) =~ '^\s*}\s*\(//.*\|/\*.*\)\=$' && indent(lnum) < theIndent
138071d4279SBram Moolenaar    let theIndent = indent(lnum)
139071d4279SBram Moolenaar  endif
140071d4279SBram Moolenaar
141071d4279SBram Moolenaar  return theIndent
142071d4279SBram Moolenaarendfunction
143071d4279SBram Moolenaar
144*8e52a593SBram Moolenaarlet &cpo = s:keepcpo
145*8e52a593SBram Moolenaarunlet s:keepcpo
146*8e52a593SBram Moolenaar
147071d4279SBram Moolenaar" vi: sw=2 et
148