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