occam.vim (4738B)
1 " Vim indent file 2 " Language: occam 3 " Maintainer: Mario Schweigler <ms44@kent.ac.uk> (Invalid email address) 4 " Doug Kearns <dougkearns@gmail.com> 5 " Last Change: 2022 Apr 06 6 7 " Only load this indent file when no other was loaded. 8 if exists("b:did_indent") 9 finish 10 endif 11 let b:did_indent = 1 12 13 "{{{ Settings 14 " Set the occam indent function 15 setlocal indentexpr=GetOccamIndent() 16 " Indent after new line and after initial colon 17 setlocal indentkeys=o,O,0=: 18 "}}} 19 20 let b:undo_indent = "setl inde< indk<" 21 22 " Only define the function once 23 if exists("*GetOccamIndent") 24 finish 25 endif 26 let s:keepcpo= &cpo 27 set cpo&vim 28 29 "{{{ Indent definitions 30 " Define carriage return indent 31 let s:FirstLevelIndent = '^\C\s*\(IF\|ALT\|PRI\s\+ALT\|PAR\|SEQ\|PRI\s\+PAR\|WHILE\|VALOF\|CLAIM\|FORKING\)\>\|\(--.*\)\@<!\(\<PROC\>\|??\|\<CASE\>\s*\(--.*\)\=\_$\)' 32 let s:FirstLevelNonColonEndIndent = '^\C\s*PROTOCOL\>\|\(--.*\)\@<!\<\(\(CHAN\|DATA\)\s\+TYPE\|FUNCTION\)\>' 33 let s:SecondLevelIndent = '^\C\s*\(IF\|ALT\|PRI\s\+ALT\)\>\|\(--.*\)\@<!?\s*\<CASE\>\s*\(--.*\)\=\_$' 34 let s:SecondLevelNonColonEndIndent = '\(--.*\)\@<!\<\(CHAN\|DATA\)\s\+TYPE\>' 35 36 " Define colon indent 37 let s:ColonIndent = '\(--.*\)\@<!\<PROC\>' 38 let s:ColonNonColonEndIndent = '^\C\s*PROTOCOL\>\|\(--.*\)\@<!\<\(\(CHAN\|DATA\)\s\+TYPE\|FUNCTION\)\>' 39 40 let s:ColonEnd = '\(--.*\)\@<!:\s*\(--.*\)\=$' 41 let s:ColonStart = '^\s*:\s*\(--.*\)\=$' 42 43 " Define comment 44 let s:CommentLine = '^\s*--' 45 "}}} 46 47 "{{{ function GetOccamIndent() 48 " Auxiliary function to get the correct indent for a line of occam code 49 function GetOccamIndent() 50 51 " Ensure magic is on 52 let save_magic = &magic 53 setlocal magic 54 55 " Get reference line number 56 let linenum = prevnonblank(v:lnum - 1) 57 while linenum > 0 && getline(linenum) =~ s:CommentLine 58 let linenum = prevnonblank(linenum - 1) 59 endwhile 60 61 " Get current indent 62 let curindent = indent(linenum) 63 64 " Get current line 65 let line = getline(linenum) 66 67 " Get previous line number 68 let prevlinenum = prevnonblank(linenum - 1) 69 while prevlinenum > 0 && getline(prevlinenum) =~ s:CommentLine 70 let prevlinenum = prevnonblank(prevlinenum - 1) 71 endwhile 72 73 " Get previous line 74 let prevline = getline(prevlinenum) 75 76 " Colon indent 77 if getline(v:lnum) =~ s:ColonStart 78 79 let found = 0 80 81 while found < 1 82 83 if line =~ s:ColonStart 84 let found = found - 1 85 elseif line =~ s:ColonIndent || (line =~ s:ColonNonColonEndIndent && line !~ s:ColonEnd) 86 let found = found + 1 87 endif 88 89 if found < 1 90 let linenum = prevnonblank(linenum - 1) 91 if linenum > 0 92 let line = getline(linenum) 93 else 94 let found = 1 95 endif 96 endif 97 98 endwhile 99 100 if linenum > 0 101 let curindent = indent(linenum) 102 else 103 let colonline = getline(v:lnum) 104 let tabstr = '' 105 while strlen(tabstr) < &tabstop 106 let tabstr = ' ' . tabstr 107 endwhile 108 let colonline = substitute(colonline, '\t', tabstr, 'g') 109 let curindent = match(colonline, ':') 110 endif 111 112 " Restore magic 113 if !save_magic|setlocal nomagic|endif 114 115 return curindent 116 endif 117 118 if getline(v:lnum) =~ '^\s*:' 119 let colonline = getline(v:lnum) 120 let tabstr = '' 121 while strlen(tabstr) < &tabstop 122 let tabstr = ' ' . tabstr 123 endwhile 124 let colonline = substitute(colonline, '\t', tabstr, 'g') 125 let curindent = match(colonline, ':') 126 127 " Restore magic 128 if !save_magic|setlocal nomagic|endif 129 130 return curindent 131 endif 132 133 " Carriage return indenat 134 if line =~ s:FirstLevelIndent || (line =~ s:FirstLevelNonColonEndIndent && line !~ s:ColonEnd) 135 \ || (line !~ s:ColonStart && (prevline =~ s:SecondLevelIndent 136 \ || (prevline =~ s:SecondLevelNonColonEndIndent && prevline !~ s:ColonEnd))) 137 let curindent = curindent + shiftwidth() 138 139 " Restore magic 140 if !save_magic|setlocal nomagic|endif 141 142 return curindent 143 endif 144 145 " Commented line 146 if getline(prevnonblank(v:lnum - 1)) =~ s:CommentLine 147 148 " Restore magic 149 if !save_magic|setlocal nomagic|endif 150 151 return indent(prevnonblank(v:lnum - 1)) 152 endif 153 154 " Look for previous second level IF / ALT / PRI ALT 155 let found = 0 156 157 while !found 158 159 if indent(prevlinenum) == curindent - shiftwidth() 160 let found = 1 161 endif 162 163 if !found 164 let prevlinenum = prevnonblank(prevlinenum - 1) 165 while prevlinenum > 0 && getline(prevlinenum) =~ s:CommentLine 166 let prevlinenum = prevnonblank(prevlinenum - 1) 167 endwhile 168 if prevlinenum == 0 169 let found = 1 170 endif 171 endif 172 173 endwhile 174 175 if prevlinenum > 0 176 if getline(prevlinenum) =~ s:SecondLevelIndent 177 let curindent = curindent + shiftwidth() 178 endif 179 endif 180 181 " Restore magic 182 if !save_magic|setlocal nomagic|endif 183 184 return curindent 185 186 endfunction 187 "}}} 188 189 let &cpo = s:keepcpo 190 unlet s:keepcpo