From d57c72c9432094bd11a745be0e00db4640abd92a Mon Sep 17 00:00:00 2001 From: Tony Duckles Date: Sat, 30 Dec 2017 22:45:45 -0600 Subject: [PATCH] .vim: Support folding based on custom section markers --- .bashrc | 5 +++ .vim/bundle/autofolds/plugin/autofolds.vim | 43 ++++++++++++++++++++++ .vimrc | 3 ++ 3 files changed, 51 insertions(+) create mode 100644 .vim/bundle/autofolds/plugin/autofolds.vim diff --git a/.bashrc b/.bashrc index 907dfc1..6aff4c5 100644 --- a/.bashrc +++ b/.bashrc @@ -3,6 +3,10 @@ # A basically sane bash environment. # Tony Duckles (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 index 0000000..dafb546 --- /dev/null +++ b/.vim/bundle/autofolds/plugin/autofolds.vim @@ -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 0227c00..1b6d7c9 100644 --- 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 -- 2.47.1