Created
March 15, 2018 19:48
-
-
Save mmktomato/4528881993a8d8bea612f8004f2806fe to your computer and use it in GitHub Desktop.
experimental
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
function! BetterFold(lnum) | |
let headerLevel = GetCurrentHeaderLevel(a:lnum) | |
let level = GetLevel(a:lnum, headerLevel) | |
let type = GetFoldType(a:lnum) | |
let nextHeaderLevel = GetCurrentHeaderLevel(a:lnum + 1) | |
let nextType = GetFoldType(a:lnum + 1) | |
let nextLevel = GetLevel(a:lnum + 1, nextHeaderLevel) | |
let prevHeaderLevel = GetCurrentHeaderLevel(a:lnum - 1) | |
let prevLevel = GetLevel(a:lnum -1, prevHeaderLevel) | |
let direction = nextLevel < level ? "<" : "" | |
if direction == "<" | |
if type == "list" | |
let retval = "<".(level - 1) | |
else | |
let retval = "<".headerLevel | |
endif | |
elseif level == prevLevel | |
let retval = "=" | |
else | |
let retval = level | |
endif | |
echom a:lnum." (".retval."):".getline(a:lnum) | |
return retval | |
endfunction | |
function! GetCurrentHeaderLevel(lnum) | |
let i = a:lnum | |
while 0 < i | |
let headerLevel = GetHeaderLevel(i) | |
if 0 < headerLevel | |
return headerLevel | |
endif | |
let i -= 1 | |
endwhile | |
return 0 | |
endfunction | |
function! GetLevel(lnum, currentHeaderLevel) | |
let level = 0 | |
let listLevel = GetListLevel(a:lnum) | |
if listLevel < 1 | |
let headerLevel = GetHeaderLevel(a:lnum) | |
if headerLevel < 1 | |
let level = a:currentHeaderLevel | |
else | |
let level = headerLevel | |
endif | |
else | |
let level = listLevel + a:currentHeaderLevel | |
endif | |
return level | |
endfunction | |
function! GetFoldType(lnum) | |
if 0 < GetListLevel(a:lnum) | |
return "list" | |
elseif 0 < GetHeaderLevel(a:lnum) | |
return "header" | |
endif | |
return "" | |
endfunction | |
function! GetListLevel(lnum) | |
let pattern = '^\s*\ze[-+*]' " [-+*] are not counted by '\ze'. See ':help \ze'. | |
let depth = GetDepth(a:lnum, pattern) " depth is the number of whitespaces. | |
if depth < 0 | |
return 0 | |
endif | |
return (depth / shiftwidth()) + 1 | |
endfunction | |
function! GetHeaderLevel(lnum) | |
let pattern = '^#\+' | |
let depth = GetDepth(a:lnum, pattern) " depth is the number of '#'s. | |
if depth < 0 | |
return 0 | |
endif | |
return depth | |
endfunction | |
function! GetDepth(lnum, pattern) | |
let line = getline(a:lnum) | |
let matches = matchstrpos(line, a:pattern) | |
if matches[1] < 0 | |
return -1 | |
endif | |
return matches[2] - matches[1] | |
endfunction | |
setlocal foldmethod=expr | |
setlocal foldexpr=BetterFold(v:lnum) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment