blob: 5e52702fd5eac91a74d3af63a1f47ef83c98c6fc [file] [log] [blame]
Bram Moolenaar9964e462007-05-05 17:54:07 +00001" Vim filetype plugin file
2" Language: cobol
Bram Moolenaar63b74a82019-03-24 15:09:13 +01003" Maintainer: Ankit Jain <ajatkj@yahoo.co.in>
4" (formerly Tim Pope <vimNOSPAM@tpope.info>)
Bram Moolenaar3d1cde82020-08-15 18:55:18 +02005" Last Update: By Ankit Jain (add gtk support) on 15.08.2020
Doug Kearns93197fd2024-01-14 20:59:02 +01006" 2024 Jan 14 by Vim Project (browsefilter)
Bram Moolenaar9964e462007-05-05 17:54:07 +00007
8" Insert mode mappings: <C-T> <C-D> <Tab>
9" Normal mode mappings: < > << >> [[ ]] [] ][
10" Visual mode mappings: < >
11
12if exists("b:did_ftplugin")
13 finish
14endif
15let b:did_ftplugin = 1
16
17let s:cpo_save = &cpo
18set cpo&vim
19
20setlocal commentstring=\ \ \ \ \ \ *%s
21setlocal comments=:*
22setlocal fo+=croqlt
23setlocal expandtab
24setlocal textwidth=72
25
26" matchit support
27if 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
39endif
40
Bram Moolenaar3d1cde82020-08-15 18:55:18 +020041" add gtk support
42if (has("gui_win32") || has("gui_gtk")) && !exists("b:browsefilter")
Doug Kearns93197fd2024-01-14 20:59:02 +010043 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
Bram Moolenaar9964e462007-05-05 17:54:07 +000049endif
50
51let b:undo_ftplugin = "setlocal com< cms< fo< et< tw<" .
52 \ " | unlet! b:browsefilter b:match_words b:match_ignorecase b:match_skip"
53if !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> ]['"
74endif
75
76if !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>
101endif
102
103let &cpo = s:cpo_save
104unlet s:cpo_save
105
106if exists("g:did_cobol_ftplugin_functions")
107 finish
108endif
109let g:did_cobol_ftplugin_functions = 1
110
111function! 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
119endfunction
120
121function! s:increase(...)
122 let lnum = '.'
Bram Moolenaar8d043172014-01-23 14:24:41 +0100123 let sw = shiftwidth()
Bram Moolenaar9964e462007-05-05 17:54:07 +0000124 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
134endfunction
135
136function! s:decrease(...)
137 let lnum = '.'
Bram Moolenaar8d043172014-01-23 14:24:41 +0100138 let sw = shiftwidth()
Bram Moolenaar9964e462007-05-05 17:54:07 +0000139 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
151endfunction
152
153function! CobolIndentBlock(shift)
154 let head = strpart(getline('.'),0,7)
155 let tail = strpart(getline('.'),7)
156 let indent = match(tail,'[^ ]')
Bram Moolenaar8d043172014-01-23 14:24:41 +0100157 let sw = shiftwidth()
Bram Moolenaar9964e462007-05-05 17:54:07 +0000158 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)
176endfunction
177
178function! s:IncreaseFunc(type)
179 '[,']call CobolIndentBlock(1)
180endfunction
181
182function! s:DecreaseFunc(type)
183 '[,']call CobolIndentBlock(-1)
184endfunction
185
186function! 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
203endfunction
204
205function! 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)
218endfunction
219
220function! s:RestoreShiftwidth()
221 if exists("b:cobol_shiftwidth")
222 let &shiftwidth=b:cobol_shiftwidth
223 unlet b:cobol_shiftwidth
224 endif
225 return ""
226endfunction
227
228function! s:Tab()
229 if (strpart(getline('.'),0,col('.')-1) =~ '^\s*$' && &sta)
230 return s:IncreaseIndent()
Bram Moolenaar8d043172014-01-23 14:24:41 +0100231 " &softtabstop < 0: &softtabstop follows &shiftwidth
232 elseif (&sts < 0 || &sts == shiftwidth()) && &sts != 8 && &et
Bram Moolenaar9964e462007-05-05 17:54:07 +0000233 return s:repeat(" ",s:increase(col('.')-1))
234 else
235 return "\<Tab>"
236 endif
237endfunction
238
239function! 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)
248endfunction
249
250function! 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
274endfunction