folding.vim 3.0 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485
  1. " These are settings to make folding easier to use and look at:
  2. " - Indented folded lines to match origin line indentation.
  3. " - Statbox to right displays line count and fold level.
  4. "
  5. " Note that custom foldtext will only work for vim 7.3+.
  6. if has('folding')
  7. set foldtext=CustomFoldText()
  8. function! CustomFoldText(...)
  9. " At least vim 7.3
  10. " - Requirement for `strdisplaywidth` (If `strdisplaywidth` fails for
  11. " multi-byte chars, consider checking the `strlen` help).
  12. if v:version < 703
  13. return foldtext()
  14. endif
  15. " Common variables for all foldmethods.
  16. let lineCount = v:foldend - v:foldstart + 1
  17. let displayWidth = winwidth(0) - &foldcolumn
  18. if (&number || &relativenumber)
  19. let displayWidth -= &numberwidth
  20. endif
  21. let foldChar = '-'
  22. " Set fold fillchar.
  23. let &l:fillchars = substitute(&l:fillchars,',\?fold:.','','gi')
  24. execute 'setlocal fillchars+=fold:' . foldChar
  25. " Fold text for Diffs - centre-aligned statbox with a line count.
  26. if &foldmethod == 'diff'
  27. let statBox = printf('[ %s matching lines ]', lineCount)
  28. let filler = repeat(foldChar, (displayWidth - strchars(statBox)) / 2)
  29. return filler.statBox
  30. endif
  31. " Fold text for all other situations.
  32. " - Fold description is a max length of 1/3 of the current window width.
  33. " - Fold & comment markers are removed from the fold description.
  34. " Prepare fold indent, and if long enough, indicate folding with '+'.
  35. let foldIndicator = '+ '
  36. let indLen = strdisplaywidth(foldIndicator)
  37. if indent(v:foldstart) >= indLen
  38. let indent = repeat(' ', indent(v:foldstart) - indLen) . foldIndicator
  39. else
  40. let indent = repeat(' ', indent(v:foldstart))
  41. endif
  42. " Prepare the statbox.
  43. " - Fix statbox width at 18 chars.
  44. " - Count width by display cells instead of bytes (vim 7.4+).
  45. if v:version >= 704
  46. let countType = 'S'
  47. else
  48. let countType = 's'
  49. endif
  50. let statBox = '[ ' . printf('%14'.countType, lineCount.' lns, lv '.v:foldlevel) . ' ]'
  51. " Prepare fold description.
  52. " - Use function argument as fold description text if provided.
  53. let foldDesc = a:0 > 0 ? a:1 : getline(v:foldstart)
  54. " Remove any fold markers.
  55. let foldmarkers = split(&foldmarker, ',')
  56. let foldDesc = substitute(foldDesc, '\V' . foldmarkers[0] . '\%(\d\+\)\?\s\*', '', '')
  57. " Remove any surrounding whitespace.
  58. let foldDesc = substitute(foldDesc, '^\s*\(.\{-}\)\s*$', '\1', '')
  59. " Space the description away from the midfiller a bit.
  60. let foldDesc = foldDesc . ' '
  61. " Prepare filler lines.
  62. " - midFiller is the fill between the description and statbox, so its
  63. " length is the leftover space after all other elements.
  64. let endFiller = repeat(foldChar, 1)
  65. let midFillerLength = displayWidth - strdisplaywidth(indent.foldDesc.statBox.endFiller)
  66. let midFiller = repeat(foldChar, midFillerLength)
  67. return indent.foldDesc.midFiller.statBox.endFiller
  68. endfunction
  69. endif