java.vim 4.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151
  1. " Vim indent file
  2. " Language: Java
  3. " Previous Maintainer: Toby Allsopp <toby.allsopp@peace.com>
  4. " 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
  9. " License: Same as Vim.
  10. " Copyright (c) 2012-2016 Hong Xu
  11. " Before 2012, this file was maintained by Toby Allsopp.
  12. " Only load this indent file when no other was loaded.
  13. if exists("b:did_indent")
  14. finish
  15. endif
  16. let b:did_indent = 1
  17. " Indent Java anonymous classes correctly.
  18. setlocal cindent cinoptions& cinoptions+=j1
  19. " The "extends" and "implements" lines start off with the wrong indent.
  20. setlocal indentkeys& indentkeys+=0=extends indentkeys+=0=implements
  21. " Set the function to do the work.
  22. setlocal indentexpr=GetJavaIndent()
  23. let b:undo_indent = "set cin< cino< indentkeys< indentexpr<"
  24. " Only define the function once.
  25. if exists("*GetJavaIndent")
  26. finish
  27. endif
  28. let s:keepcpo= &cpo
  29. set cpo&vim
  30. function! SkipJavaBlanksAndComments(startline)
  31. let lnum = a:startline
  32. while lnum > 1
  33. let lnum = prevnonblank(lnum)
  34. if getline(lnum) =~ '\*/\s*$'
  35. while getline(lnum) !~ '/\*' && lnum > 1
  36. let lnum = lnum - 1
  37. endwhile
  38. if getline(lnum) =~ '^\s*/\*'
  39. let lnum = lnum - 1
  40. else
  41. break
  42. endif
  43. elseif getline(lnum) =~ '^\s*//'
  44. let lnum = lnum - 1
  45. else
  46. break
  47. endif
  48. endwhile
  49. return lnum
  50. endfunction
  51. function GetJavaIndent()
  52. " Java is just like C; use the built-in C indenting and then correct a few
  53. " specific cases.
  54. let theIndent = cindent(v:lnum)
  55. " If we're in the middle of a comment then just trust cindent
  56. if getline(v:lnum) =~ '^\s*\*'
  57. return theIndent
  58. endif
  59. " find start of previous line, in case it was a continuation line
  60. let lnum = SkipJavaBlanksAndComments(v:lnum - 1)
  61. " If the previous line starts with '@', we should have the same indent as
  62. " the previous one
  63. if getline(lnum) =~ '^\s*@.*$'
  64. return indent(lnum)
  65. endif
  66. let prev = lnum
  67. while prev > 1
  68. let next_prev = SkipJavaBlanksAndComments(prev - 1)
  69. if getline(next_prev) !~ ',\s*$'
  70. break
  71. endif
  72. let prev = next_prev
  73. endwhile
  74. " Try to align "throws" lines for methods and "extends" and "implements" for
  75. " classes.
  76. if getline(v:lnum) =~ '^\s*\(throws\|extends\|implements\)\>'
  77. \ && getline(lnum) !~ '^\s*\(throws\|extends\|implements\)\>'
  78. let theIndent = theIndent + shiftwidth()
  79. endif
  80. " correct for continuation lines of "throws", "implements" and "extends"
  81. let cont_kw = matchstr(getline(prev),
  82. \ '^\s*\zs\(throws\|implements\|extends\)\>\ze.*,\s*$')
  83. if strlen(cont_kw) > 0
  84. let amount = strlen(cont_kw) + 1
  85. if getline(lnum) !~ ',\s*$'
  86. let theIndent = theIndent - (amount + shiftwidth())
  87. if theIndent < 0
  88. let theIndent = 0
  89. endif
  90. elseif prev == lnum
  91. let theIndent = theIndent + amount
  92. if cont_kw ==# 'throws'
  93. let theIndent = theIndent + shiftwidth()
  94. endif
  95. endif
  96. elseif getline(prev) =~ '^\s*\(throws\|implements\|extends\)\>'
  97. \ && (getline(prev) =~ '{\s*$'
  98. \ || getline(v:lnum) =~ '^\s*{\s*$')
  99. let theIndent = theIndent - shiftwidth()
  100. endif
  101. " When the line starts with a }, try aligning it with the matching {,
  102. " skipping over "throws", "extends" and "implements" clauses.
  103. if getline(v:lnum) =~ '^\s*}\s*\(//.*\|/\*.*\)\=$'
  104. call cursor(v:lnum, 1)
  105. silent normal! %
  106. let lnum = line('.')
  107. if lnum < v:lnum
  108. while lnum > 1
  109. let next_lnum = SkipJavaBlanksAndComments(lnum - 1)
  110. if getline(lnum) !~ '^\s*\(throws\|extends\|implements\)\>'
  111. \ && getline(next_lnum) !~ ',\s*$'
  112. break
  113. endif
  114. let lnum = prevnonblank(next_lnum)
  115. endwhile
  116. return indent(lnum)
  117. endif
  118. endif
  119. " Below a line starting with "}" never indent more. Needed for a method
  120. " below a method with an indented "throws" clause.
  121. let lnum = SkipJavaBlanksAndComments(v:lnum - 1)
  122. if getline(lnum) =~ '^\s*}\s*\(//.*\|/\*.*\)\=$' && indent(lnum) < theIndent
  123. let theIndent = indent(lnum)
  124. endif
  125. return theIndent
  126. endfunction
  127. let &cpo = s:keepcpo
  128. unlet s:keepcpo
  129. " vi: sw=2 et