.vim/bundle/vim-asciidoc-folding/after/ftplugin/asciidoc/folding.vim
changeset 26 1bb2363eba47
parent 25 d22ae2e9efc2
child 27 c1d260ead8fa
equal deleted inserted replaced
25:d22ae2e9efc2 26:1bb2363eba47
     1 " Fold expression for asciidoc files
       
     2 "
       
     3 " NOTE: only supports Atx-style, not Setext style sections. See
       
     4 " http://asciidoctor.org/docs/asciidoc-recommended-practices/ for more info.
       
     5 "
       
     6 " Script's originally based on https://github.com/nelstrom/vim-markdown-folding
       
     7 "
       
     8 " vim:set fdm=marker:
       
     9 
       
    10 " Fold expressions {{{1
       
    11 function! StackedMarkdownFolds()
       
    12   if HeadingDepth(v:lnum) > 0
       
    13     return ">1"
       
    14   else
       
    15     return "="
       
    16   endif
       
    17 endfunction
       
    18 
       
    19 function! NestedMarkdownFolds()
       
    20   let depth = HeadingDepth(v:lnum)
       
    21   if depth > 0
       
    22     return ">".depth
       
    23   else
       
    24     return "="
       
    25   endif
       
    26 endfunction
       
    27 
       
    28 " Helpers {{{1
       
    29 function! s:SID()
       
    30   return matchstr(expand('<sfile>'), '<SNR>\d\+_')
       
    31 endfunction
       
    32 
       
    33 function! HeadingDepth(lnum)
       
    34   " 5 ='s is deepest section level, according to `asciidoc --help syntax`.
       
    35   " Only 1 = is the document header, which isn't really worth folding, so we
       
    36   " ignore it and subtract one off the count to get the fold level.
       
    37   let level=0
       
    38   let thisline = getline(a:lnum)
       
    39   let hashCount = len(matchstr(thisline, '^=\{2,5}'))
       
    40   " Ignore lines with too many ='s (usually block deliminators)
       
    41   if hashCount > 1 && hashCount < 5
       
    42     let level = hashCount - 1
       
    43   endif
       
    44 
       
    45   if level > 0 && LineIsFenced(a:lnum)
       
    46     " Ignore ='s if they appear within fenced code blocks
       
    47     let level = 0
       
    48   endif
       
    49 
       
    50   return level
       
    51 endfunction
       
    52 
       
    53 function! LineIsFenced(lnum)
       
    54   if exists("b:current_syntax") && b:current_syntax ==# 'asciidoc'
       
    55     " It's cheap to check if the current line has 'markdownCode' syntax group
       
    56     return s:HasSyntaxGroup(a:lnum, 'markdownCode')
       
    57   endif
       
    58 endfunction
       
    59 
       
    60 function! s:HasSyntaxGroup(lnum, targetGroup)
       
    61   let syntaxGroup = map(synstack(a:lnum, 1), 'synIDattr(v:val, "name")')
       
    62   for value in syntaxGroup
       
    63     " Likely dependant on the asciidoc syntax file, so will need to be
       
    64     " updated accordingly
       
    65     if value =~ '\vasciidocListingBlock'
       
    66       return 1
       
    67     endif
       
    68   endfor
       
    69 endfunction
       
    70 
       
    71 
       
    72 function! s:FoldText()
       
    73   let level = HeadingDepth(v:foldstart)
       
    74   let indent = repeat('=', level)
       
    75   let title = substitute(getline(v:foldstart), '^=\+\s*', '', '')
       
    76   let foldsize = (v:foldend - v:foldstart)
       
    77   let linecount = '['.foldsize.' line'.(foldsize>1?'s':'').']'
       
    78   return indent.' '.title.' '.linecount
       
    79 endfunction
       
    80 
       
    81 " API {{{1
       
    82 function! ToggleMarkdownFoldexpr()
       
    83   if &l:foldexpr ==# 'StackedMarkdownFolds()'
       
    84     setlocal foldexpr=NestedMarkdownFolds()
       
    85   else
       
    86     setlocal foldexpr=StackedMarkdownFolds()
       
    87   endif
       
    88 endfunction
       
    89 command! -buffer FoldToggle call ToggleMarkdownFoldexpr()
       
    90 
       
    91 " Setup {{{1
       
    92 if !exists('g:markdown_fold_style')
       
    93   let g:markdown_fold_style = 'stacked'
       
    94 endif
       
    95 
       
    96 if !exists('g:markdown_fold_override_foldtext')
       
    97   let g:markdown_fold_override_foldtext = 1
       
    98 endif
       
    99 
       
   100 setlocal foldmethod=expr
       
   101 
       
   102 if g:markdown_fold_override_foldtext
       
   103   let &l:foldtext = s:SID() . 'FoldText()'
       
   104 endif
       
   105 
       
   106 let &l:foldexpr =
       
   107   \ g:markdown_fold_style ==# 'nested'
       
   108   \ ? 'NestedMarkdownFolds()'
       
   109   \ : 'StackedMarkdownFolds()'
       
   110 
       
   111 " Teardown {{{1
       
   112 " To avoid errors when undo_ftplugin not defined yet
       
   113 if !exists('b:undo_ftplugin')
       
   114     let b:undo_ftplugin = ''
       
   115 endif
       
   116 
       
   117 let b:undo_ftplugin .= '
       
   118   \ | setlocal foldmethod< foldtext< foldexpr<
       
   119   \ | delcommand FoldToggle
       
   120   \ '
       
   121