zimbu.vim 3.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130
  1. " Vim indent file
  2. " Language: Zimbu
  3. " Maintainer: The Vim Project <https://github.com/vim/vim>
  4. " Last Change: 2023 Aug 10
  5. " Former Maintainer: Bram Moolenaar <Bram@vim.org>
  6. " Only load this indent file when no other was loaded.
  7. if exists("b:did_indent")
  8. finish
  9. endif
  10. let b:did_indent = 1
  11. setlocal ai nolisp nocin
  12. setlocal indentexpr=GetZimbuIndent(v:lnum)
  13. setlocal indentkeys=0{,0},!^F,o,O,0=ELSE,0=ELSEIF,0=CASE,0=DEFAULT,0=FINALLY
  14. " We impose recommended defaults: no Tabs, 'shiftwidth' = 2
  15. setlocal sw=2 et
  16. let b:undo_indent = "setl ai< cin< et< indentkeys< indentexpr< lisp< sw<"
  17. " Only define the function once.
  18. if exists("*GetZimbuIndent")
  19. finish
  20. endif
  21. let s:cpo_save = &cpo
  22. set cpo&vim
  23. " Come here when loading the script the first time.
  24. let s:maxoff = 50 " maximum number of lines to look backwards for ()
  25. func GetZimbuIndent(lnum)
  26. let prevLnum = prevnonblank(a:lnum - 1)
  27. if prevLnum == 0
  28. " This is the first non-empty line, use zero indent.
  29. return 0
  30. endif
  31. " Taken from Python indenting:
  32. " If the previous line is inside parenthesis, use the indent of the starting
  33. " line.
  34. " Trick: use the non-existing "dummy" variable to break out of the loop when
  35. " going too far back.
  36. call cursor(prevLnum, 1)
  37. let parlnum = searchpair('(\|{\|\[', '', ')\|}\|\]', 'nbW',
  38. \ "line('.') < " . (prevLnum - s:maxoff) . " ? dummy :"
  39. \ . " synIDattr(synID(line('.'), col('.'), 1), 'name')"
  40. \ . " =~ '\\(Comment\\|String\\|Char\\)$'")
  41. if parlnum > 0
  42. let plindent = indent(parlnum)
  43. let plnumstart = parlnum
  44. else
  45. let plindent = indent(prevLnum)
  46. let plnumstart = prevLnum
  47. endif
  48. " When inside parenthesis: If at the first line below the parenthesis add
  49. " two 'shiftwidth', otherwise same as previous line.
  50. " i = (a
  51. " + b
  52. " + c)
  53. call cursor(a:lnum, 1)
  54. let p = searchpair('(\|{\|\[', '', ')\|}\|\]', 'bW',
  55. \ "line('.') < " . (a:lnum - s:maxoff) . " ? dummy :"
  56. \ . " synIDattr(synID(line('.'), col('.'), 1), 'name')"
  57. \ . " =~ '\\(Comment\\|String\\|Char\\)$'")
  58. if p > 0
  59. if p == prevLnum
  60. " When the start is inside parenthesis, only indent one 'shiftwidth'.
  61. let pp = searchpair('(\|{\|\[', '', ')\|}\|\]', 'bW',
  62. \ "line('.') < " . (a:lnum - s:maxoff) . " ? dummy :"
  63. \ . " synIDattr(synID(line('.'), col('.'), 1), 'name')"
  64. \ . " =~ '\\(Comment\\|String\\|Char\\)$'")
  65. if pp > 0
  66. return indent(prevLnum) + shiftwidth()
  67. endif
  68. return indent(prevLnum) + shiftwidth() * 2
  69. endif
  70. if plnumstart == p
  71. return indent(prevLnum)
  72. endif
  73. return plindent
  74. endif
  75. let prevline = getline(prevLnum)
  76. let thisline = getline(a:lnum)
  77. " If this line is not a comment and the previous one is then move the
  78. " previous line further back.
  79. if thisline !~ '^\s*#'
  80. while prevline =~ '^\s*#'
  81. let prevLnum = prevnonblank(prevLnum - 1)
  82. if prevLnum == 0
  83. " Only comment lines before this, no indent
  84. return 0
  85. endif
  86. let prevline = getline(prevLnum)
  87. let plindent = indent(prevLnum)
  88. endwhile
  89. endif
  90. if prevline =~ '^\s*\(IF\|\|ELSEIF\|ELSE\|GENERATE_IF\|\|GENERATE_ELSEIF\|GENERATE_ELSE\|WHILE\|REPEAT\|TRY\|CATCH\|FINALLY\|FOR\|DO\|SWITCH\|CASE\|DEFAULT\|FUNC\|VIRTUAL\|ABSTRACT\|DEFINE\|REPLACE\|FINAL\|PROC\|MAIN\|NEW\|ENUM\|CLASS\|INTERFACE\|BITS\|MODULE\|SHARED\)\>'
  91. let plindent += shiftwidth()
  92. endif
  93. if thisline =~ '^\s*\(}\|ELSEIF\>\|ELSE\>\|CATCH\|FINALLY\|GENERATE_ELSEIF\>\|GENERATE_ELSE\>\|UNTIL\>\)'
  94. let plindent -= shiftwidth()
  95. endif
  96. if thisline =~ '^\s*\(CASE\>\|DEFAULT\>\)' && prevline !~ '^\s*SWITCH\>'
  97. let plindent -= shiftwidth()
  98. endif
  99. " line up continued comment that started after some code
  100. " String something # comment comment
  101. " # comment
  102. if a:lnum == prevLnum + 1 && thisline =~ '^\s*#' && prevline !~ '^\s*#'
  103. let n = match(prevline, '#')
  104. if n > 1
  105. let plindent = n
  106. endif
  107. endif
  108. return plindent
  109. endfunc
  110. let &cpo = s:cpo_save
  111. unlet s:cpo_save