Follow-up: it's not promising. Vim's current syntax definition for
Ruby (
http://vim-ruby.rubyforge.org) does enable syntax-based folding,
but it can't be selective about what it folds (i.e. classes and
methods only, per Ara's request).
The following settings should be OK:
set foldmethod=syntax
set foldnestmax=2 " or 3
If anyone knows enough about Vim to make the folding smarter for Ruby
files, please step forward
Gavin
I don't know about making folds smarter than you already have.
This is the folding I use with ruby and like, for what that is worth,
as someone who would not like to be without vim folding. I use the
attached folding setup and open ruby (and other files) in folded mode -
it is a bit like having a table of contents. It is made up from things
extracted from vim tips a couple of years back, modified as required
over time.
Lets see what does it include:
<leader>ff folds file
fs after a search, shows only search results all else folded
(no idea whether this feature has become part of mainstream vim)
to open a file in fold mode (i.e. with the fold instructions installed):
gvim -c :R
In additon to folding on def, class, and module (also public protected
private) it folds on #{{ (until the next fold), i use comment markers
and {{ to place folds in all files in which i want fold headings ...
vim setup files included.
There is no recursive (levels of) folding here.
Vim is so flexible how you choose to work with these things is a
matter of taste.
I don't have the time to clean it up, or to extract things (just) ruby
right now but share as is, unedited, (and including some non-ruby folding,
and probably some other superflous bits, actually i did start deleting a bit).
(there may be problems with line breaks). Oh and final caveat, apart from
having figured out what folds i was comfortable with using some time in the
past, (and using that ever since) i can't claim to know much about vim folds.
Vim fold section follows:
" arch-tag: vimrc folds related (e-mail address removed)
:filetype on
:filetype indent on
set foldexpr=Foldexpr_fun('^\\i')
:hi FoldColumn ctermfg=Black ctermbg=magenta
:hi Folded ctermfg=Black ctermbg=magenta
"{{~foldsearchx FoldSearch (opens result of search all else closed)
"mapped to \f & \z t77 late
:set foldexpr=getline(v:lnum-1)!~@/&&getline(v:lnum)!~@/&&getline(v:lnum+1)!~@/
:map fs :set foldmethod=expr foldcolumn=2 foldlevel=0 <cr>
:map <leader>see :set foldmethod=expr foldcolumn=2 foldlevel=0 <cr>
:map <leader>fa :Fa<cr>
function! FoldInst()
if ( &filetype == "ruby" )
"erase folds, first fold then erase, or just use open folds zR
:map <leader>fe :R<cr> zE
:R
else
:map <leader>fe :F<cr> zE
:F
endif
endfunc
:nmap <silent> <leader>ff :silent call FoldInst()<cr>
:map <leader>fO :R <cr>fe<cr> " erase folds
"{{~foldtoggle Fold Toggle mapped to <space>
" Toggle fold state between closed and opened.
" If there is no fold at current line, just moves forward. If it is present,
" reverse it's state.
fun! ToggleFold()
if foldlevel('.') == 0
normal! l
else
if foldclosed('.') < 0
. foldclose
else
. foldopen
endif
endif
" Clear status line
echo
endfun
" Map this function to Space key.
:noremap <space> :call ToggleFold()<cr>
"{{~foldtype Fold? set foldtext
:set foldtext=v:folddashes.substitute(getline(v:foldstart),'{{\\d\\=','','g',)
:set foldexpr=getline(v:lnum-1)!~@/&&getline(v:lnum)!~@/&&getline(v:lnum+1)!~@/
"{{~foldsearch t77: Fold on search result
"(Fs <pattern> or Fc Frb Flm Fp) Fs pattern Fold search #Str (structure)
" ruby program pattern based on module class and def #Strlm (structure)
" lm file pattern based on <!1!> etc.
function! Foldsearch(search)
set fdm=manual
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
while search(a:search, flags) > 0
let line2 = line(".")
" echo "pattern found at line # " line2
if (line2 -1 > line1)
: "echo line1 . ":" . (line2-1)
: "echo "A fold goes here."
: 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
" Now create the last fold which goes to the end of the file.
: normal $G
: let line2 = line(".")
" echo "end of file found at line # " line2
: if (line2 > line1 && folded == 1)
" echo line1 . ":" . line2
" echo "A fold goes here."
: execute ":". line1 . "," . line2 . "fold"
: endif
: normal 1G
: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>)
"{{~folds :T Fold Patterns exuberant tag list :T
:command! T Fs ^\s*\S\+\s\+(
"{{~folds :R Fold Patterns Ruby :R
:command! R Fs \(^\s*\(\(def\|class\|module\)\s\)\|\
\(\(public\|protected\|private\)\(\s\|$\)\)\)\
\|^[0-9]{\|[#%"]\{1,4\}\s*{\({\|!!\)
:command! Re Fs \(^\s*\(\(def\|class\|module\)\s\)\)\
\|^\s*[ #%"0-9\~]\{0,4\}{\({{\|!!\)
"{{~folds :F Fold Patterns SiSU Markup :F
:command! F Fs [1-8]{\|#\s*{{\|^[#%"0-9]\{0,4\}\s*{[{!]