.vim: Support folding based on custom section markers
authorTony Duckles <tony@nynim.org>
Sun, 31 Dec 2017 04:45:45 +0000
committerTony Duckles <tony@nynim.org>
Sun, 31 Dec 2017 21:13:54 +0000
.bashrc
.vim/bundle/autofolds/plugin/autofolds.vim [new file with mode: 0644]
.vimrc

diff --git a/.bashrc b/.bashrc
index 907dfc17d1613bc1ae6e602d4e6cbad8998456d3..6aff4c5e0aebdcdf712791ecf7a5745e75f2bcbb 100644 (file)
--- a/.bashrc
+++ b/.bashrc
@@ -3,6 +3,10 @@
 # A basically sane bash environment.
 # Tony Duckles <http://nynim.org/about/> (based on http://github.com/rtomayko/dotfiles)
 
+# ----------------------------------------------------------------------
+#  BASICS
+# ----------------------------------------------------------------------
+
 # short-circuit for non-interactive sessions
 [ -z "$PS1" ] && return
 
@@ -462,3 +466,4 @@ test -n "$INTERACTIVE" -a -n "$LOGIN" && {
 }
 
 # vim: ts=4 sts=4 shiftwidth=4 expandtab
+# vim: foldmethod=expr foldexpr=autofolds#foldexpr(v\:lnum,'sh') foldtext=autofolds#foldtext() foldlevel=2
diff --git a/.vim/bundle/autofolds/plugin/autofolds.vim b/.vim/bundle/autofolds/plugin/autofolds.vim
new file mode 100644 (file)
index 0000000..dafb546
--- /dev/null
@@ -0,0 +1,43 @@
+" autofolds
+" =========
+" Automatic folding based on custom section markers
+" Inspired by: https://vi.stackexchange.com/a/6608
+
+function! autofolds#foldexpr(lnum, ...)
+  let s:filetype = a:0 > 0 ? a:1 : 'vim'  " optional 'filetype' param
+  let s:comment_char = ''
+  if s:filetype == 'vim'
+    let s:comment_char = '"'
+  elseif s:filetype == 'sh'
+    let s:comment_char = '#'
+  endif
+  if s:comment_char == ''
+    return '='
+  endif
+  let s:thisline = getline(a:lnum)
+  let s:two_following_lines = 0
+  if line(a:lnum) + 2 <= line('$')
+    let s:line_1_after = getline(a:lnum+1)
+    let s:line_2_after = getline(a:lnum+2)
+    let s:two_following_lines = 1
+  endif
+  if !s:two_following_lines
+      return '='
+    endif
+  else
+    if (match(s:thisline, '^'.s:comment_char.' ----------') >= 0) &&
+       \ (match(s:line_1_after, '^'.s:comment_char.' ') >= 0) &&
+       \ (match(s:line_2_after, '^'.s:comment_char.' ----------') >= 0)
+      return '>1'
+    else
+      return '='
+    endif
+  endif
+endfunction
+
+function! autofolds#foldtext()
+  let s:lines = string(v:foldend-v:foldstart)  " # of lines in fold range
+  let s:text = getline(v:foldstart+1)[2:]      " extract text after leading comment marker
+  let s:text = substitute(s:text,'^\s*\(.\{-}\)\s*$', '\1', '')  " strip leading/trailing whitespace
+  return '+'.repeat('-', 1 + v:foldlevel).repeat(' ', 3-len(s:lines)).s:lines.' lines: '.s:text.' '  " mimic standard foldtext() format
+endfunction
diff --git a/.vimrc b/.vimrc
index 0227c000e2fd51dcbd9428e1fa2a915f22c2aa0d..1b6d7c97b04a3e67705d416bd1e41fdef46c310e 100644 (file)
--- a/.vimrc
+++ b/.vimrc
@@ -33,6 +33,7 @@ Plug 'tpope/vim-unimpaired'
 Plug 'vim-airline/vim-airline'
 Plug 'vim-airline/vim-airline-themes'
 
+Plug '~/.vim/bundle/autofolds'
 Plug '~/.vim/bundle/matchit'
 Plug '~/.vim/bundle/mumps'
 
@@ -424,3 +425,5 @@ augroup END
 if filereadable(glob("~/.vimrc.local"))
   source ~/.vimrc.local
 endif
+
+" vim: foldmethod=expr foldexpr=autofolds#foldexpr(v\:lnum) foldtext=autofolds#foldtext() foldlevel=2