1 " viki.vim -- the viki ftplugin
2 " @Author: Thomas Link (micathom AT gmail com?subject=vim)
3 " @License: GPL (see http://www.gnu.org/licenses/gpl.txt)
4 " @Created: 12-Jän-2004.
5 " @Last Change: 2008-02-14.
12 if exists("b:did_ftplugin") "{{{2
15 let b:did_ftplugin = 1
16 " if exists("b:did_viki_ftplugin")
19 " let b:did_viki_ftplugin = 1
21 let b:vikiCommentStart = "%"
22 let b:vikiCommentEnd = ""
23 let b:vikiHeadingMaxLevel = -1
24 if !exists("b:vikiMaxFoldLevel") | let b:vikiMaxFoldLevel = 5 | endif "{{{2
25 if !exists("b:vikiInverseFold") | let b:vikiInverseFold = 0 | endif "{{{2
27 exec "setlocal commentstring=". substitute(b:vikiCommentStart, "%", "%%", "g")
28 \ ."%s". substitute(b:vikiCommentEnd, "%", "%%", "g")
29 exec "setlocal comments=fb:-,fb:+,fb:*,fb:#,fb:?,fb:@,:". b:vikiCommentStart
31 setlocal foldmethod=expr
32 setlocal foldexpr=VikiFoldLevel(v:lnum)
33 setlocal foldtext=VikiFoldText()
35 " setlocal iskeyword+=#,{
39 let &include='\(^\s*#INC.\{-}\(\sfile=\|:\)\)'
40 " let &include='\(^\s*#INC.\{-}\(\sfile=\|:\)\|\[\[\)'
41 " set includeexpr=substitute(v:fname,'\].*$','','')
43 let &define='^\s*\(#Def.\{-}id=\|#\(Fn\|Footnote\).\{-}\(:\|id=\)\|#VAR.\{-}\s\)'
45 " if !exists('b:vikiHideBody') | let b:vikiHideBody = 0 | endif
47 " if !hasmapto(":VikiFind")
48 " nnoremap <buffer> <c-tab> :VikiFindNext<cr>
49 " nnoremap <buffer> <LocalLeader>vn :VikiFindNext<cr>
50 " nnoremap <buffer> <c-s-tab> :VikiFindPrev<cr>
51 " nnoremap <buffer> <LocalLeader>vN :VikiFindPrev<cr>
56 map <buffer> <silent> [[ :call viki#FindPrevHeading()<cr>
57 map <buffer> <silent> ][ :call viki#FindNextHeading()<cr>
58 map <buffer> <silent> ]] ][
59 map <buffer> <silent> [] [[
61 let b:undo_ftplugin = 'setlocal iskeyword< expandtab< foldtext< foldexpr< foldmethod< comments< commentstring< '
63 \ .'| unlet b:vikiHeadingMaxLevel b:vikiCommentStart b:vikiCommentEnd b:vikiInverseFold b:vikiMaxFoldLevel '
65 \ .'| unmap <buffer> [['
66 \ .'| unmap <buffer> ]]'
67 \ .'| unmap <buffer> ]['
68 \ .'| unmap <buffer> []'
72 if exists('*VikiFoldLevel') "{{{2
76 function! VikiFoldText() "{{{3
77 let line = getline(v:foldstart)
78 if synIDattr(synID(v:foldstart, 1, 1), 'name') =~ '^vikiFiles'
79 let line = fnamemodify(viki#FilesGetFilename(line), ':h')
81 let ctxtlev = tlib#var#Get('vikiFoldsContext', 'wbg')
82 let ctxt = get(ctxtlev, v:foldlevel, 0)
86 let [ctxtbeg, ctxtend] = ctxt
91 let line = matchstr(line, '^\s*\zs.*$')
92 for li in range(ctxtbeg, ctxtend)
93 let li = v:foldstart + li
97 let lp = matchstr(getline(li), '^\s*\zs.\{-}\ze\s*$')
99 let lp = substitute(lp, '\s\+', ' ', 'g')
100 let line .= ' | '. lp
104 return v:folddashes . line
107 function! s:VikiFolds() "{{{3
108 let vikiFolds = tlib#var#Get('vikiFolds', 'bg')
110 if vikiFolds == 'ALL'
111 let vikiFolds = 'hlsfb'
112 " let vikiFolds = 'hHlsfb'
113 elseif vikiFolds == 'DEFAULT'
120 function! s:SetMaxLevel() "{{{3
121 let pos = getpos('.')
122 " TLogVAR b:vikiHeadingStart
123 let vikiHeadingRx = '\V\^'. b:vikiHeadingStart .'\+\ze\s'
124 let b:vikiHeadingMaxLevel = 0
125 exec 'keepjumps g/'. vikiHeadingRx .'/let l = matchend(getline("."), vikiHeadingRx) | if l > b:vikiHeadingMaxLevel | let b:vikiHeadingMaxLevel = l | endif'
126 " TLogVAR b:vikiHeadingMaxLevel
127 call setpos('.', pos)
130 if g:vikiFoldMethodVersion == 5
132 function! VikiFoldLevel(lnum) "{{{3
134 let vikiFolds = s:VikiFolds()
136 " TLogVAR b:vikiHeadingStart
137 let lt = getline(a:lnum)
138 let fh = matchend(lt, '\V\^'. b:vikiHeadingStart .'\+\ze\s')
140 " TLogVAR fh, b:vikiHeadingMaxLevel
141 if b:vikiHeadingMaxLevel == -1
142 " TLogDBG 'SetMaxLevel'
145 if fh > b:vikiHeadingMaxLevel
146 let b:vikiHeadingMaxLevel = fh
149 " TLogDBG 'inverse folds'
150 let fh = b:vikiHeadingMaxLevel - fh + 1
155 let body_level = indent(a:lnum) / &sw + 1
156 return b:vikiHeadingMaxLevel + body_level
160 elseif g:vikiFoldMethodVersion == 4
162 function! VikiFoldLevel(lnum) "{{{3
164 let vikiFolds = s:VikiFolds()
166 " TLogVAR b:vikiHeadingStart
167 let lt = getline(a:lnum)
168 let fh = matchend(lt, '\V\^'. b:vikiHeadingStart .'\+\ze\s')
170 " TLogVAR fh, b:vikiHeadingMaxLevel
171 if b:vikiHeadingMaxLevel == -1
172 " TLogDBG 'SetMaxLevel'
175 if fh > b:vikiHeadingMaxLevel
176 let b:vikiHeadingMaxLevel = fh
179 " TLogDBG 'inverse folds'
180 let fh = b:vikiHeadingMaxLevel - fh + 1
185 if b:vikiHeadingMaxLevel <= 0
186 return b:vikiHeadingMaxLevel + 1
193 elseif g:vikiFoldMethodVersion == 3
195 function! VikiFoldLevel(lnum) "{{{3
196 let lt = getline(a:lnum)
200 let fh = matchend(lt, '\V\^'. b:vikiHeadingStart .'\+\ze\s')
203 if b:vikiHeadingMaxLevel == -1
206 if fh > b:vikiHeadingMaxLevel
207 let b:vikiHeadingMaxLevel = fh
208 " TLogVAR b:vikiHeadingMaxLevel
213 let li = indent(a:lnum)
214 let tf = b:vikiHeadingMaxLevel + 1 + (li / &sw)
219 elseif g:vikiFoldMethodVersion == 2
221 function! VikiFoldLevel(lnum) "{{{3
222 let lt = getline(a:lnum)
223 let fh = matchend(lt, '\V\^'. b:vikiHeadingStart .'\+\ze\s')
227 let ll = prevnonblank(a:lnum)
231 let li = indent(a:lnum)
232 let pl = prevnonblank(a:lnum - 1)
234 if li == pi || pl == 0
237 return 'a'. ((li - pi) / &sw)
239 return 's'. ((pi - li) / &sw)
245 function! VikiFoldLevel(lnum) "{{{3
252 let vikiFolds = s:VikiFolds()
257 if b:vikiHeadingMaxLevel == -1
261 let idt = indent(a:lnum)
262 if synIDattr(synID(a:lnum, idt, 1), 'name') =~ '^vikiFiles'
263 call s:SetHeadingMaxLevel(1)
264 " TLogDBG 'vikiFiles: '. idt
265 return b:vikiHeadingMaxLevel + idt / &shiftwidth
268 if stridx(vikiFolds, 'h') >= 0
270 let fl = s:ScanHeading(a:lnum, a:lnum, vikiFolds)
272 " TLogDBG 'heading: '. fl
277 let list = s:MatchList(a:lnum)
279 call s:SetHeadingMaxLevel(1)
281 " return '>'. (b:vikiHeadingMaxLevel + (list / &sw))
282 return (b:vikiHeadingMaxLevel + (list / &sw))
283 elseif getline(a:lnum) !~ '^[[:blank:]]' && s:MatchList(a:lnum - 1) > 0
284 let fl = s:ScanHeading(a:lnum - 1, 1, vikiFolds)
287 let fl = strpart(fl, 1)
289 " TLogDBG 'list indent: '. fl
294 " I have no idea what this is about.
295 " Is this about "inverse" folding?
296 " if vikiFolds =~# 's'
297 " if exists('b:vikiFoldDef')
299 " if vikiFoldLine == a:lnum
300 " return vikiFoldLevel
305 " let vfl = VikiFoldLevel(a:lnum - i)
307 " let b:vikiFoldDef = 'let vikiFoldLine='. a:lnum
308 " \ .'|let vikiFoldLevel="'. vfl .'"'
315 call s:SetHeadingMaxLevel(1)
316 " if b:vikiHeadingMaxLevel == 0
318 " elseif vikiFolds =~# 'b'
320 let bl = exists('b:vikiFoldBodyLevel') ? b:vikiFoldBodyLevel : g:vikiFoldBodyLevel
322 " TLogDBG 'body: '. bl
325 " TLogDBG 'body fallback: '. b:vikiHeadingMaxLevel
326 return b:vikiHeadingMaxLevel + 1
336 exec 'norm! '. w0 .'zt'
343 function! s:ScanHeading(lnum, top, vikiFolds) "{{{3
344 " TLogVAR a:lnum, a:top
345 let [lhead, head] = s:SearchHead(a:lnum, a:top)
348 if head > b:vikiHeadingMaxLevel
349 let b:vikiHeadingMaxLevel = head
351 if b:vikiInverseFold || a:vikiFolds =~# 'H'
352 if b:vikiMaxFoldLevel > head
353 return ">". (b:vikiMaxFoldLevel - head)
364 function! s:SetHeadingMaxLevel(once) "{{{3
365 if a:once && b:vikiHeadingMaxLevel == 0
368 let pos = getpos('.')
371 silent! keepjumps exec 'g/\V\^'. b:vikiHeadingStart .'\+\s/call s:SetHeadingMaxLevelAtCurrentLine(line(".")'
374 call setpos('.', pos)
378 function! s:SetHeadingMaxLevelAtCurrentLine(lnum) "{{{3
379 let m = s:MatchHead(lnum)
380 if m > b:vikiHeadingMaxLevel
381 let b:vikiHeadingMaxLevel = m
385 function! s:SearchHead(lnum, top) "{{{3
386 let pos = getpos('.')
391 let ln = search('\V\^'. b:vikiHeadingStart .'\+\s', 'bWcs', a:top)
393 return [ln, s:MatchHead(ln)]
398 call setpos('.', pos)
402 function! s:MatchHead(lnum) "{{{3
403 " let head = matchend(getline(a:lnum), '\V\^'. escape(b:vikiHeadingStart, '\') .'\ze\s\+')
404 return matchend(getline(a:lnum), '\V\^'. b:vikiHeadingStart .'\+\ze\s')
407 function! s:MatchList(lnum) "{{{3
408 let rx = '^[[:blank:]]\+\ze\(#[A-F]\d\?\|#\d[A-F]\?\|[-+*#?@]\|[0-9#]\+\.\|[a-zA-Z?]\.\|.\{-1,}[[:blank:]]::\)[[:blank:]]'
409 return matchend(getline(a:lnum), rx)