Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Save mmktomato/4528881993a8d8bea612f8004f2806fe to your computer and use it in GitHub Desktop.
Save mmktomato/4528881993a8d8bea612f8004f2806fe to your computer and use it in GitHub Desktop.
experimental
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