├── CHANGELOG.md ├── plugin └── ruby_fold.vim ├── doc └── ruby_fold.vim ├── LICENSE.md ├── README.md └── autoload └── ruby.vim /CHANGELOG.md: -------------------------------------------------------------------------------- 1 | # Changelog 2 | 3 | ### master 4 | - do not fold on `alias` and single-line method definitions 5 | 6 | ### v1.0.0, 2014-11-24 7 | - improve readme, add docs 8 | - plugin working 9 | -------------------------------------------------------------------------------- /plugin/ruby_fold.vim: -------------------------------------------------------------------------------- 1 | if exists('g:loaded_ruby_fold') || &cp 2 | finish 3 | endif 4 | let g:loaded_ruby_fold = 1 5 | 6 | if has("autocmd") 7 | augroup ruby_fold 8 | autocmd! 9 | autocmd FileType ruby 10 | \ if !exists('g:ruby_fold_lines_limit') || line('$') < g:ruby_fold_lines_limit | 11 | \ if expand('%:t') =~# '_spec.rb$' | 12 | \ let b:rspec_fold_end = 0 | 13 | \ setlocal foldexpr=ruby#rspec_fold(v:lnum) foldmethod=expr | 14 | \ else | 15 | \ setlocal foldexpr=ruby#fold(v:lnum) foldmethod=expr | 16 | \ endif | 17 | \ endif 18 | augroup END 19 | endif 20 | -------------------------------------------------------------------------------- /doc/ruby_fold.vim: -------------------------------------------------------------------------------- 1 | *ruby_fold.txt* simple folding for ruby and rspec files 2 | 3 | Author: Bruno Sutic 4 | 5 | ABOUT *ruby-fold* 6 | 7 | Simple folding for ruby and rspec files. 8 | 9 | Official vim-ruby plugin has fold support with |ruby_fold|. Unfortunately, the 10 | folds produced by that plugin are too "granular". Every if statement, block, 11 | method, class, module and multi-line comment are folded. 12 | In the end, you might find yourself working too much through the folds to 13 | get to the actual code. 14 | 15 | FEATURES *ruby-fold-features* 16 | 17 | |ruby-fold| folds only ruby methods. In rspec files, "it" blocks are folded. 18 | 19 | CONTRIBUTING *ruby-fold-contributing* 20 | 21 | Contributing and bug reports are welcome. Github repo: 22 | 23 | https://github.com/bruno-/vim-ruby-fold 24 | 25 | LICENSE *ruby-fold-license* 26 | 27 | Copyright (c) Bruno Sutic. Distributed under the MIT license. 28 | 29 | vim:tw=78:ts=8:ft=help:norl: 30 | -------------------------------------------------------------------------------- /LICENSE.md: -------------------------------------------------------------------------------- 1 | Copyright (C) Bruno Sutic 2 | 3 | Permission is hereby granted, free of charge, to any person obtaining 4 | a copy of this software and associated documentation files (the "Software"), 5 | to deal in the Software without restriction, including without limitation 6 | the rights to use, copy, modify, merge, publish, distribute, sublicense, 7 | and/or sell copies of the Software, and to permit persons to whom the 8 | Software is furnished to do so, subject to the following conditions: 9 | 10 | The above copyright notice and this permission notice shall be included 11 | in all copies or substantial portions of the Software. 12 | 13 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 14 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES 15 | OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 16 | IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, 17 | DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, 18 | TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE 19 | OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 20 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # ruby-fold.vim 2 | 3 | Simple folding for `ruby` and `rspec` files. 4 | 5 | Official [vim-ruby](https://github.com/vim-ruby/vim-ruby) plugin has too 6 | granular fold support. Every if statement, block, method, class, module and 7 | multi-line comment are folded.
8 | The downside of this is that you might find yourself working too much through 9 | the folds to get to the actual code. 10 | 11 | This plugin folds \*only* ruby methods. In `rspec` files, `it` blocks are 12 | folded. 13 | 14 | Benefits: 15 | - it's easy to get to the "actual code" because folds are always just one level 16 | deep 17 | - high-level file overview stays clean and readable because the code 18 | implementation within the methods is folded 19 | 20 | ### Installation 21 | 22 | Just use your favorite plugin manager. 23 | 24 | ### Options 25 | 26 | Folds computation is slow for big files. This might result in noticeable lag 27 | when opening ruby files. 28 | 29 | The solution to this is to limit fold creation only for small ruby files. 30 | The following option 31 | 32 | let g:ruby_fold_lines_limit = 200 33 | 34 | will only fold ruby files if they have less than 200LOC. 35 | 36 | ### Alternatives 37 | 38 | There is a [pull request](https://github.com/vim-ruby/vim-ruby/pull/272) opened 39 | for official vim-ruby plugin that adds more granular folding support. This PR 40 | could make `vim-ruby-fold` plugin obsolete. 41 | 42 | I tested the above PR for a couple weeks: it's roughly 30% faster at opening big 43 | ruby files (it's still takes quite some time to open ruby files with more than 44 | 1000 LOC). 45 | 46 | The \*big* downside is it makes insert mode horribly slow and laggy. I think 47 | this is due to folds computation after every character insert. 48 | 49 | The `vim-ruby-fold` performs perfectly in this scenario because it computes 50 | folds only when entering the buffer. For this reason I'm sticking with it for 51 | the foreseeable future. 52 | 53 | ### License 54 | 55 | [MIT](LICENSE.md) 56 | -------------------------------------------------------------------------------- /autoload/ruby.vim: -------------------------------------------------------------------------------- 1 | " helpers {{{1 2 | function! s:block_end_line(line) 3 | " adjusting cursor position so that searchpair works properly 4 | let save_pos = getpos('.') 5 | call cursor(a:line, 1) 6 | 7 | let comment_escape = '\v^[^#]*' 8 | let block_openers = '\zs(||||)' 9 | let start_pattern = comment_escape . block_openers 10 | let end_pattern = comment_escape . '\zs' 11 | let skip_pattern = 'getline(".") =~ "\\v\\S\\s<(if|unless)>\\s\\S"' 12 | let flags = 'nW' 13 | let end_pos = searchpair(start_pattern, '', end_pattern, flags, skip_pattern) 14 | 15 | call setpos('.', save_pos) 16 | return end_pos 17 | endfunction 18 | 19 | function! s:get_highlight_groups(current_line, line) 20 | let stack = synstack(a:line, (match(a:current_line, '^\s*\zs'))+1) 21 | return map(stack, 'synIDattr(v:val,"name")') 22 | endfunction 23 | 24 | function! s:alias_line(current_line) 25 | return a:current_line =~# '^\s*alias' 26 | endfunction 27 | 28 | function! s:one_line_method(current_line) 29 | return a:current_line =~# '^\s*def\s.\{-}\= 0 || 42 | \ index(highlight_groups, "rubyDefine", 0, 1) >= 0 || 43 | \ index(highlight_groups, "rubyDocumentation", 0, 1) >= 0 44 | return 1 45 | else 46 | return 0 47 | endif 48 | endfunction 49 | 50 | function! ruby#rspec_fold(line) 51 | " check if fold end is known 52 | if b:rspec_fold_end > 0 && a:line <= b:rspec_fold_end 53 | if a:line ==# b:rspec_fold_end 54 | let b:rspec_fold_end = 0 55 | end 56 | return 1 57 | endif 58 | 59 | " rspec files also fold by ruby rules 60 | if ruby#fold(a:line) 61 | return 1 62 | endif 63 | 64 | let it_line_regex = '^\s*x\?it\s.\{-}do\s*$' 65 | " fold starts on an `it` line 66 | if getline(a:line) =~# it_line_regex 67 | return 1 68 | 69 | " all the subsequent lines in an `it` block are inside a fold 70 | elseif getline(a:line-1) =~# it_line_regex 71 | let b:rspec_fold_end = s:block_end_line(a:line) 72 | return 1 73 | 74 | " handles a scenario when fold is edited 75 | elseif foldlevel(a:line-1) > 0 && s:block_end_line(a:line-1) >= a:line 76 | let b:rspec_fold_end = s:block_end_line(a:line) 77 | return 1 78 | endif 79 | 80 | return 0 81 | endfunction 82 | --------------------------------------------------------------------------------