1" Vim filetype plugin file 2" Language: cobol 3" Author: Tim Pope <vimNOSPAM@tpope.info> 4" $Id: cobol.vim,v 1.1 2007/05/05 17:24:38 vimboss Exp $ 5 6" Insert mode mappings: <C-T> <C-D> <Tab> 7" Normal mode mappings: < > << >> [[ ]] [] ][ 8" Visual mode mappings: < > 9 10if exists("b:did_ftplugin") 11 finish 12endif 13let b:did_ftplugin = 1 14 15let s:cpo_save = &cpo 16set cpo&vim 17 18setlocal commentstring=\ \ \ \ \ \ *%s 19setlocal comments=:* 20setlocal fo+=croqlt 21setlocal expandtab 22setlocal textwidth=72 23 24" matchit support 25if exists("loaded_matchit") 26 let s:ordot = '\|\ze\.\%( \@=\|$\)' 27 let b:match_ignorecase=1 28 "let b:match_skip = 'getline(".") =~ "^.\\{6\\}[*/C]"' 29 let b:match_words= 30 \ '\$if\>:$else\>:\$endif\>,' . 31 \ '[$-]\@<!\<if\>:\<\%(then\|else\)\>:\<end-if\>'.s:ordot.',' . 32 \ '-\@<!\<perform\s\+\%(\d\+\s\+times\|until\|varying\|with\s\+test\)\>:\<end-perform\>'.s:ordot . ',' . 33 \ '-\@<!\<\%(search\|evaluate\)\>:\<\%(when\)\>:\<end-\%(search\|evaluate\)\>' .s:ordot . ',' . 34 \ '-\@<!\<\%(add\|compute\|divide\|multiply\|subtract\)\>\%(.*\(\%$\|\%(\n\%(\%(\s*\|.\{6\}\)[*/].*\n\)*\)\=\s*\%(not\s\+\)\=on\s\+size\s\+error\>\)\)\@=:\%(\<not\s\+\)\@<!\<\%(not\s\+\)\=on\s\+size\s\+error\>:\<end-\%(add\|compute\|divide\|multiply\|subtract\)\>' .s:ordot . ',' . 35 \ '-\@<!\<\%(string\|unstring\|accept\|display\|call\)\>\%(.*\(\%$\|\%(\n\%(\%(\s*\|.\{6\}\)[*/].*\n\)*\)\=\s*\%(not\s\+\)\=on\s\+\%(overflow\|exception\)\>\)\)\@=:\%(\<not\s\+\)\@<!\<\%(not\s\+\)\=on\s\+\%(overflow\|exception\)\>:\<end-\%(string\|unstring\|accept\|display\|call\)\>' .s:ordot . ',' . 36 \ '-\@<!\<\%(delete\|rewrite\|start\|write\|read\)\>\%(.*\(\%$\|\%(\n\%(\%(\s*\|.\{6\}\)[*/].*\n\)*\)\=\s*\%(invalid\s\+key\|at\s\+end\|no\s\+data\|at\s\+end-of-page\)\>\)\)\@=:\%(\<not\s\+\)\@<!\<\%(not\s\+\)\=\%(invalid\s\+key\|at\s\+end\|no\s\+data\|at\s\+end-of-page\)\>:\<end-\%(delete\|rewrite\|start\|write\|read\)\>' .s:ordot 37endif 38 39if has("gui_win32") && !exists("b:browsefilter") 40 let b:browsefilter = "COBOL Source Files (*.cbl, *.cob)\t*.cbl;*.cob;*.lib\n". 41 \ "All Files (*.*)\t*.*\n" 42endif 43 44let b:undo_ftplugin = "setlocal com< cms< fo< et< tw<" . 45 \ " | unlet! b:browsefilter b:match_words b:match_ignorecase b:match_skip" 46if !exists("g:no_plugin_maps") && !exists("g:no_cobol_maps") 47 let b:undo_ftplugin = b:undo_ftplugin . 48 \ " | sil! exe 'nunmap <buffer> <'" . 49 \ " | sil! exe 'nunmap <buffer> >'" . 50 \ " | sil! exe 'nunmap <buffer> <<'" . 51 \ " | sil! exe 'nunmap <buffer> >>'" . 52 \ " | sil! exe 'vunmap <buffer> <'" . 53 \ " | sil! exe 'vunmap <buffer> >'" . 54 \ " | sil! exe 'iunmap <buffer> <C-D>'" . 55 \ " | sil! exe 'iunmap <buffer> <C-T>'" . 56 \ " | sil! exe 'iunmap <buffer> <Tab>'" . 57 \ " | sil! exe 'nunmap <buffer> <Plug>Traditional'" . 58 \ " | sil! exe 'nunmap <buffer> <Plug>Comment'" . 59 \ " | sil! exe 'nunmap <buffer> <Plug>DeComment'" . 60 \ " | sil! exe 'vunmap <buffer> <Plug>VisualTraditional'" . 61 \ " | sil! exe 'vunmap <buffer> <Plug>VisualComment'" . 62 \ " | sil! exe 'iunmap <buffer> <Plug>VisualDeComment'" . 63 \ " | sil! exe 'unmap <buffer> [['" . 64 \ " | sil! exe 'unmap <buffer> ]]'" . 65 \ " | sil! exe 'unmap <buffer> []'" . 66 \ " | sil! exe 'unmap <buffer> ]['" 67endif 68 69if !exists("g:no_plugin_maps") && !exists("g:no_cobol_maps") 70 if version >= 700 71 nnoremap <silent> <buffer> > :set opfunc=<SID>IncreaseFunc<CR>g@ 72 nnoremap <silent> <buffer> < :set opfunc=<SID>DecreaseFunc<CR>g@ 73 endif 74 nnoremap <silent> <buffer> >> :call CobolIndentBlock(1)<CR> 75 nnoremap <silent> <buffer> << :call CobolIndentBlock(-1)<CR> 76 vnoremap <silent> <buffer> > :call CobolIndentBlock(v:count1)<CR> 77 vnoremap <silent> <buffer> < :call CobolIndentBlock(-v:count1)<CR> 78 inoremap <silent> <buffer> <C-T> <C-R>=<SID>IncreaseIndent()<CR><C-R>=<SID>RestoreShiftwidth()<CR> 79 inoremap <silent> <buffer> <C-D> <C-R>=<SID>DecreaseIndent()<CR><C-R>=<SID>RestoreShiftwidth()<CR> 80 if !maparg("<Tab>","i") 81 inoremap <silent> <buffer> <Tab> <C-R>=<SID>Tab()<CR><C-R>=<SID>RestoreShiftwidth()<CR> 82 endif 83 noremap <silent> <buffer> [[ m':call search('\c^\%(\s*\<Bar>.\{6\}\s\+\)\zs[A-Za-z0-9-]\+\s\+\%(division\<Bar>section\)\s*\.','bW')<CR> 84 noremap <silent> <buffer> ]] m':call search('\c^\%(\s*\<Bar>.\{6\}\s\+\)\zs[A-Za-z0-9-]\+\s\+\%(division\<Bar>section\)\.','W')<CR> 85 noremap <silent> <buffer> [] m':call <SID>toend('b')<CR> 86 noremap <silent> <buffer> ][ m':call <SID>toend('')<CR> 87 " For EnhancedCommentify 88 noremap <silent> <buffer> <Plug>Traditional :call <SID>Comment('t')<CR> 89 noremap <silent> <buffer> <Plug>Comment :call <SID>Comment('c')<CR> 90 noremap <silent> <buffer> <Plug>DeComment :call <SID>Comment('u')<CR> 91 noremap <silent> <buffer> <Plug>VisualTraditional :'<,'>call <SID>Comment('t')<CR> 92 noremap <silent> <buffer> <Plug>VisualComment :'<,'>call <SID>Comment('c')<CR> 93 noremap <silent> <buffer> <Plug>VisualDeComment :'<,'>call <SID>Comment('u')<CR> 94endif 95 96let &cpo = s:cpo_save 97unlet s:cpo_save 98 99if exists("g:did_cobol_ftplugin_functions") 100 finish 101endif 102let g:did_cobol_ftplugin_functions = 1 103 104function! s:repeat(str,count) 105 let i = 0 106 let ret = "" 107 while i < a:count 108 let ret = ret . a:str 109 let i = i + 1 110 endwhile 111 return ret 112endfunction 113 114function! s:increase(...) 115 let lnum = '.' 116 let sw = &shiftwidth 117 let i = a:0 ? a:1 : indent(lnum) 118 if i >= 11 119 return sw - (i - 11) % sw 120 elseif i >= 7 121 return 11-i 122 elseif i == 6 123 return 1 124 else 125 return 6-i 126 endif 127endfunction 128 129function! s:decrease(...) 130 let lnum = '.' 131 let sw = &shiftwidth 132 let i = indent(a:0 ? a:1 : lnum) 133 if i >= 11 + sw 134 return 1 + (i + 12) % sw 135 elseif i > 11 136 return i-11 137 elseif i > 7 138 return i-7 139 elseif i == 7 140 return 1 141 else 142 return i 143 endif 144endfunction 145 146function! CobolIndentBlock(shift) 147 let head = strpart(getline('.'),0,7) 148 let tail = strpart(getline('.'),7) 149 let indent = match(tail,'[^ ]') 150 let sw = &shiftwidth 151 let shift = a:shift 152 if shift > 0 153 if indent < 4 154 let tail = s:repeat(" ",4-indent).tail 155 let shift = shift - 1 156 endif 157 let tail = s:repeat(" ",shift*sw).tail 158 let shift = 0 159 elseif shift < 0 160 if (indent-4) > -shift * sw 161 let tail = strpart(tail,-shift * sw) 162 elseif (indent-4) > (-shift-1) * sw 163 let tail = strpart(tail,indent - 4) 164 else 165 let tail = strpart(tail,indent) 166 endif 167 endif 168 call setline('.',head.tail) 169endfunction 170 171function! s:IncreaseFunc(type) 172 '[,']call CobolIndentBlock(1) 173endfunction 174 175function! s:DecreaseFunc(type) 176 '[,']call CobolIndentBlock(-1) 177endfunction 178 179function! s:IncreaseIndent() 180 let c = "\<C-T>" 181 if exists("*InsertCtrlTWrapper") 182 let key = InsertCtrlTWrapper() 183 if key != c 184 return key 185 endif 186 endif 187 let interval = s:increase() 188 let b:cobol_shiftwidth = &shiftwidth 189 let &shiftwidth = 1 190 let lastchar = strpart(getline('.'),col('.')-2,1) 191 if lastchar == '0' || lastchar == '^' 192 return "\<BS>".lastchar.c 193 else 194 return s:repeat(c,interval) 195 endif 196endfunction 197 198function! s:DecreaseIndent() 199 let c = "\<C-D>" 200 if exists("*InsertCtrlDWrapper") 201 " I hack Ctrl-D to delete when not at the end of the line. 202 let key = InsertCtrlDWrapper() 203 if key != c 204 return key 205 endif 206 endif 207 let interval = s:decrease() 208 let b:cobol_shiftwidth = &shiftwidth 209 let &shiftwidth = 1 210 return s:repeat(c,interval) 211endfunction 212 213function! s:RestoreShiftwidth() 214 if exists("b:cobol_shiftwidth") 215 let &shiftwidth=b:cobol_shiftwidth 216 unlet b:cobol_shiftwidth 217 endif 218 return "" 219endfunction 220 221function! s:Tab() 222 if (strpart(getline('.'),0,col('.')-1) =~ '^\s*$' && &sta) 223 return s:IncreaseIndent() 224 elseif &sts == &sw && &sts != 8 && &et 225 return s:repeat(" ",s:increase(col('.')-1)) 226 else 227 return "\<Tab>" 228 endif 229endfunction 230 231function! s:Comment(arg) 232 " For EnhancedCommentify 233 let line = getline('.') 234 if (line =~ '^.\{6\}[*/C]' || a:arg == 'c') && a:arg != 'u' 235 let line = substitute(line,'^.\{6\}\zs.',' ','') 236 else 237 let line = substitute(line,'^.\{6\}\zs.','*','') 238 endif 239 call setline('.',line) 240endfunction 241 242function! s:toend(direction) 243 let ignore = '^\(\s*\|.\{6\}\)\%([*/]\|\s*$\)' 244 let keep = line('.') 245 keepjumps + 246 while line('.') < line('$') && getline('.') =~ ignore 247 keepjumps + 248 endwhile 249 let res = search('\c^\%(\s*\|.\{6\}\s\+\)\zs[A-Za-z0-9-]\+\s\+\%(division\|section\)\s*\.',a:direction.'W') 250 if a:direction != 'b' && !res 251 let res = line('$') 252 keepjumps $ 253 elseif res 254 keepjumps - 255 endif 256 if res 257 while line('.') > 1 && getline('.') =~ ignore 258 keepjumps - 259 endwhile 260 if line('.') == 1 && getline('.') =~ ignore 261 exe "keepjumps ".keep 262 endif 263 else 264 exe "keepjumps ".keep 265 endif 266endfunction 267