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