Skip to content

Instantly share code, notes, and snippets.

@bashcoder
Created October 24, 2013 14:33
Show Gist options
  • Save bashcoder/7138386 to your computer and use it in GitHub Desktop.
Save bashcoder/7138386 to your computer and use it in GitHub Desktop.
vim ruby folding for methods
" FoldSearch-based folding.
" Copyright (C) 2005 Mauricio Fernandez <mfp@acm.org>
" Current version: http://eigenclass.org/hiki.rb?Usable+Ruby+folding+for+Vim
"
" Add this to your .vimrc and fold with :R. The default fold expression will
" work with Ruby scripts; you can specify where folds start with
" let b:foldsearchexpr = 'myexpression'
" e.g.
" let b:foldsearchexpr='\(^\s*\(\(private\|public\|protected\|class\)\s\)\)'
" or so for Java.
" One way to have this buffer-local variable set is
" au Filetype java let b:foldsearchexpr='\(^\s*\(\(private\|public\|protected\|class\)\s\)\)'
"
" It is possible to have comments above a method/class/etc be included in the
" fold, by setting b:foldsearchprefix. All the lines above the detected fold
" matching b:foldsearchprefix will be included in said fold.
" For instance, for Ruby code:
" let b:foldsearchprefix = '\v^\s*(#.*)?$'
" which can be automated with
" au Filetype ruby let b:foldsearchprefix='\v^\s*(#.*)?$'
"
" Changelog:
" 2005-12-12 1.1 use b:foldsearchprefix to prepend comments to a fold.
"{{{ set s:sid
map <SID>xx <SID>xx
let s:sid = maparg("<SID>xx")
unmap <SID>xx
let s:sid = substitute(s:sid, 'xx', '', '')
"{{{ FoldText
function! s:Num2S(num, len)
let filler = " "
let text = '' . a:num
return strpart(filler, 1, a:len - strlen(text)) . text
endfunction
execute 'set foldtext=' . s:sid . 'MyNewFoldText()'
function! <SID>MyNewFoldText()
let linenum = v:foldstart
while linenum <= v:foldend
let line = getline(linenum)
if !exists("b:foldsearchprefix") || match(line, b:foldsearchprefix) == -1
break
else
let linenum = linenum + 1
endif
endwhile
if exists("b:foldsearchprefix") && match(line, b:foldsearchprefix) != -1
" all lines matched the prefix regexp
let line = getline(v:foldstart)
endif
let sub = substitute(line, '/\*\|\*/\|{{{\d\=', '', 'g')
let diff = v:foldend - v:foldstart + 1
return '+ [' . s:Num2S(diff,4) . ']' . sub
endfunction
"{{{~foldsearch adapted from t77: Fold on search result (Fs <pattern>)
"Fs pattern Fold search
"Vimtip put to good use by Ralph Amissah zxy@irc.freenode.net
"Modified by Mauricio Fernandez <mfp@acm.org>
function! Foldsearch(search)
setlocal fdm=manual
let origlineno = line(".")
normal zE
normal G$
let folded = 0 "flag to set when a fold is found
let flags = "w" "allow wrapping in the search
let line1 = 0 "set marker for beginning of fold
if a:search == ""
if exists("b:foldsearchexpr")
let searchre = b:foldsearchexpr
else
"Default value, suitable for Ruby scripts
"\(^\s*\(\(def\|class\|module\)\s\)\)\|^\s*[#%"0-9]\{0,4\}\s*{\({{\|!!\)
let searchre = '\v(^\s*(def|class|module|attr_reader|attr_accessor|alias_method)\s' .
\ '|^\s*\w+attr_(reader|accessor)\s|^\s*[#%"0-9]{0,4}\s*\{(\{\{|!!))' .
\ '|^\s*[A-Z]\w+\s*\='
let b:foldsearchexpr = searchre
endif
else
let searchre = a:search
endif
while search(searchre, flags) > 0
let line2 = line(".")
while line2 - 1 >= line1 && line2 - 1 > 0 "sanity check
let prevline = getline(line2 - 1)
if exists("b:foldsearchprefix") && (match(prevline, b:foldsearchprefix) != -1)
let line2 = line2 - 1
else
break
endif
endwhile
if (line2 -1 >= line1)
execute ":" . line1 . "," . (line2-1) . "fold"
let folded = 1 "at least one fold has been found
endif
let line1 = line2 "update marker
let flags = "W" "turn off wrapping
endwhile
normal $G
let line2 = line(".")
if (line2 >= line1 && folded == 1)
execute ":". line1 . "," . line2 . "fold"
endif
execute "normal " . origlineno . "G"
endfunction
"{{{~folds Fold Patterns
" Command is executed as ':Fs pattern'"
command! -nargs=? -complete=command Fs call Foldsearch(<q-args>)
command! -nargs=? -complete=command Fold call Foldsearch(<q-args>)
command! R Fs \(^\s*\(\(def\|class\|module\)\s\)\)\|^\s*[#%"0-9]\{0,4\}\s*{\({{\|!!\)
"command! R Fs
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment