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