neovim

Neovim text editor
git clone https://git.dasho.dev/neovim.git
Log | Files | Refs | README

cobol.vim (9709B)


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