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