eiffel.vim 3.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116
  1. " Vim indent file
  2. " Language: Eiffel
  3. " Maintainer: Jocelyn Fiat <jfiat@eiffel.com>
  4. " Previous-Maintainer: David Clarke <gadicath@dishevelled.net>
  5. " Contributions from: Takuya Fujiwara
  6. " Contributions from: Thilo Six
  7. " $Date: 2017/03/08 06:00:00 $
  8. " $Revision: 1.4 $
  9. " URL: https://github.com/eiffelhub/vim-eiffel
  10. " Only load this indent file when no other was loaded.
  11. if exists("b:did_indent")
  12. finish
  13. endif
  14. let b:did_indent = 1
  15. setlocal indentexpr=GetEiffelIndent()
  16. setlocal nolisp
  17. setlocal nosmartindent
  18. setlocal nocindent
  19. setlocal autoindent
  20. setlocal comments=:--
  21. setlocal indentkeys+==end,=else,=ensure,=require,=check,=loop,=until
  22. setlocal indentkeys+==creation,=feature,=inherit,=class,=is,=redefine,=rename,=variant
  23. setlocal indentkeys+==invariant,=do,=local,=export
  24. let b:undo_indent = "setl smartindent< indentkeys< indentexpr< autoindent< comments< "
  25. " Define some stuff
  26. " keywords grouped by indenting
  27. let s:trust_user_indent = '\(+\)\(\s*\(--\).*\)\=$'
  28. let s:relative_indent = '^\s*\(deferred\|class\|feature\|creation\|inherit\|loop\|from\|across\|until\|if\|else\|elseif\|ensure\|require\|check\|do\|local\|invariant\|variant\|rename\|redefine\|do\|export\)\>'
  29. let s:outdent = '^\s*\(else\|invariant\|variant\|do\|require\|until\|loop\|local\)\>'
  30. let s:no_indent = '^\s*\(class\|feature\|creation\|inherit\)\>'
  31. let s:single_dent = '^[^-]\+[[:alnum:]]\+ is\(\s*\(--\).*\)\=$'
  32. let s:inheritance_dent = '\s*\(redefine\|rename\|export\)\>'
  33. " Only define the function once.
  34. if exists("*GetEiffelIndent")
  35. finish
  36. endif
  37. let s:keepcpo= &cpo
  38. set cpo&vim
  39. function GetEiffelIndent()
  40. " Eiffel Class indenting
  41. "
  42. " Find a non-blank line above the current line.
  43. let lnum = prevnonblank(v:lnum - 1)
  44. " At the start of the file use zero indent.
  45. if lnum == 0
  46. return 0
  47. endif
  48. " trust the user's indenting
  49. if getline(lnum) =~ s:trust_user_indent
  50. return -1
  51. endif
  52. " Add a 'shiftwidth' after lines that start with an indent word
  53. let ind = indent(lnum)
  54. if getline(lnum) =~ s:relative_indent
  55. let ind = ind + shiftwidth()
  56. endif
  57. " Indent to single indent
  58. if getline(v:lnum) =~ s:single_dent && getline(v:lnum) !~ s:relative_indent
  59. \ && getline(v:lnum) !~ '\s*\<\(and\|or\|implies\)\>'
  60. let ind = shiftwidth()
  61. endif
  62. " Indent to double indent
  63. if getline(v:lnum) =~ s:inheritance_dent
  64. let ind = 2 * shiftwidth()
  65. endif
  66. " Indent line after the first line of the function definition
  67. if getline(lnum) =~ s:single_dent
  68. let ind = ind + shiftwidth()
  69. endif
  70. " The following should always be at the start of a line, no indenting
  71. if getline(v:lnum) =~ s:no_indent
  72. let ind = 0
  73. endif
  74. " Subtract a 'shiftwidth', if this isn't the first thing after the 'is'
  75. " or first thing after the 'do'
  76. if getline(v:lnum) =~ s:outdent && getline(v:lnum - 1) !~ s:single_dent
  77. \ && getline(v:lnum - 1) !~ '^\s*do\>'
  78. let ind = ind - shiftwidth()
  79. endif
  80. " Subtract a shiftwidth for end statements
  81. if getline(v:lnum) =~ '^\s*end\>'
  82. let ind = ind - shiftwidth()
  83. endif
  84. " set indent of zero end statements that are at an indent of 3, this should
  85. " only ever be the class's end.
  86. if getline(v:lnum) =~ '^\s*end\>' && ind == shiftwidth()
  87. let ind = 0
  88. endif
  89. return ind
  90. endfunction
  91. let &cpo = s:keepcpo
  92. unlet s:keepcpo
  93. " vim:sw=2