Skip to content

Instantly share code, notes, and snippets.

@Fmajor
Created August 8, 2016 06:52
Show Gist options
  • Save Fmajor/c582349d1ab3c5ef69b6939475b450b7 to your computer and use it in GitHub Desktop.
Save Fmajor/c582349d1ab3c5ef69b6939475b450b7 to your computer and use it in GitHub Desktop.
" config for fold
" highlights: this costum function enable using both the 'indent' folding
" and the custum '#<==' '#==>' 'Marker' folding
"#<====================================================================
"nnoremap <space> @=((foldclosed(line('.')) < 0) ? 'zc' :'zo')<CR>
nnoremap <space> za
set foldenable
"set foldmethod=indent foldignore=
set foldmethod=expr
set foldexpr=MyFold(v:lnum)
"inBlock count the stack depth of my maker pair
let b:inBlock=0
let b:lastLineNum=0
let b:lastLevel=0
let b:lastGoodLine=0
let b:lastGoodBlock=0
let b:startFoldingMark='^\s*.\?#<==*\|^\s*.\?#region'
let b:endFoldingMark='^\s*.\?#=*=>\|^\s*.\?#endregion'
function! MyFold(linenum)
let linetext = getline(a:linenum)
let level = indent(a:linenum) / &shiftwidth
"the first line have 0 fold level
if (a:linenum == 1)
if linetext =~ b:startFoldingMark
let b:inBlock = 1
let b:lastLineNum=a:linenum
let b:lastGoodLine=0
let b:lastGoodBlock=0
let b:lastLevel=level
return level
endif
let b:inBlock=0
let b:lastInBlock=0
let b:lastLineNum=a:linenum
let b:lastGoodLine=0
let b:lastGoodBlock=b:inBlock
"echom a:linenum ':' level+b:inBlock '=' level '+' b:inBlock
let b:lastLevel=level + b:inBlock
return level + b:inBlock
endif
" not calculate from the mid of text
if ((b:lastLineNum+1) != a:linenum)
let level = indent(a:linenum) / &shiftwidth
let lastGoodNum = a:linenum-1
while (lastGoodNum>1 && getline(lastGoodNum) =~? '\v^\s*$' )
"while (lastGoodNum>1 && foldlevel(lastGoodNum) == -1 )
"echom ' ' lastGoodNum ': ' foldlevel(lastGoodNum) ' ' lastGoodNum-1 ' : ' foldlevel(lastGoodNum-1)
let lastGoodNum -= 1
endwhile
"echom 'lastGoodNum:' lastGoodNum 'lastGoodLine' b:lastGoodLine 'lastGoodBlock:' b:lastGoodBlock
if (foldlevel(lastGoodNum)==-1)
let b:inBlock=b:lastGoodBlock
"echom 'recovery inBlock with lastGoodBlock: ' b:inBlock
else
let lastlevel = indent(lastGoodNum) / &shiftwidth
let lastlinetext = getline(lastGoodNum)
let lastlinelevel = foldlevel(lastGoodNum)
if lastlinetext =~ b:startFoldingMark
let b:inBlock = lastlinelevel - lastlevel + 1
"echom 'recovery meet startFoldingMark ' b:inBlock
elseif lastlinetext =~ b:endFoldingMark
let b:inBlock = lastlinelevel - lastlevel - 1
"echom 'recovery meet endFoldingMark' b:inBlock
else
let b:inBlock = lastlinelevel - lastlevel
endif
"echom 'recovery inBlock with line ' lastGoodNum 'to be: ' b:inBlock '=' lastlinelevel '-' lastlevel
endif
endif
"blank lines have undefined fold level
if getline(a:linenum) =~? '\v^\s*$'
"echom '(' b:lastLineNum ':' foldlevel(b:lastLineNum) ')' a:linenum ':' -1
let b:lastLineNum=a:linenum
let b:lastLevel=-1
return -1
endif
"if next line is a start of new marker block, inBlock ++
if linetext =~ b:startFoldingMark
"if b:lastLineNum != a:linenum
let b:inBlock = b:inBlock + 1
"endif
"echom '(' b:lastLineNum ':' foldlevel(b:lastLineNum) ')' a:linenum ':' level '|' b:inBlock '(+=1)'
let b:lastLineNum=a:linenum
if (b:lastLevel != -1)
let b:lastGoodLine=a:linenum
let b:lastGoodBlock=b:inBlock
endif
let b:lastLevel=level + b:inBlock - 1
return level + b:inBlock - 1
"if next line is an end of new marker block, inBlock -
elseif linetext =~ b:endFoldingMark
let b:inBlock = b:inBlock - 1
"echom '(' b:lastLineNum ':' foldlevel(b:lastLineNum) ')' a:linenum ':' level+b:inBlock+1 "|" b:inBlock '(-=1)'
let b:lastLineNum=a:linenum
"if (b:lastLevel != -1)
let b:lastGoodLine=a:linenum
let b:lastGoodBlock=b:inBlock
"endif
let b:lastLevel=level + b:inBlock + 1
return level + b:inBlock + 1
endif
"echom '(' b:lastLineNum ':' foldlevel(b:lastLineNum) ')' a:linenum ':' level+b:inBlock '=' level '+' b:inBlock
let b:lastLineNum=a:linenum
if (b:lastLevel != -1)
let b:lastGoodLine=a:linenum
let b:lastGoodBlock=b:inBlock
endif
let b:lastLevel=level + b:inBlock
return level+b:inBlock
endfunction
" function for debug, leave it
nnoremap <F2> :call Do_debug_folding()<CR>
function Do_debug_folding()
exec "echom foldlevel(line('.')) b:lastLineNum"
endfunction
set foldcolumn=0
map ,fc :call Set_foldcolumn()<CR>
function Set_foldcolumn()
if &foldcolumn=="0"
set foldcolumn=3
echo "foldcolumn set to 3"
else
set foldcolumn=0
echo "foldcolumn set to 0"
endif
endfunction
" ftplugin
" .vim/after/ftplugin/markdown/folding.vim
"#====================================================================>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment