Skip to content

Commit

Permalink
Locate class definition more reliably
Browse files Browse the repository at this point in the history
In theory, anyway.
  • Loading branch information
AndrewRadev committed Oct 27, 2013
1 parent a794070 commit addba7e
Show file tree
Hide file tree
Showing 2 changed files with 44 additions and 19 deletions.
33 changes: 14 additions & 19 deletions indent/ruby.vim
Expand Up @@ -95,11 +95,6 @@ let s:continuation_regex =
" Regex that defines bracket continuations
let s:bracket_continuation_regex = '%\@<!\%([({[]\)\s*\%(#.*\)\=$'

" Regex that matches a class/module definition
let s:class_regex =
\ '\C\%(^\s*\|[=,*/%+\-|;{]\|<<\|>>\|:\s\)\s*\zs' .
\ '\<\%(module\|class\):\@!\>'

" Regex that defines the first part of a splat pattern
let s:splat_regex = '[[,(]\s*\*\s*\%(#.*\)\=$'

Expand Down Expand Up @@ -329,23 +324,23 @@ function s:Match(lnum, regex)
endif
endfunction

" Search for a pattern match with search(), ignoring strings or comments.
"
" Note that you should NOT use the "n" or "c" flags here, since it may loop
" indefinitely. You should use the "W" flag for the same reason.
" Locates the containing class/module's definition line, ignoring nested classes
" along the way.
"
function s:SearchCode(pattern, flags)
function! s:FindContainingClass()
let saved_position = getpos('.')

let [lnum, col] = searchpos(a:pattern, a:flags)

while lnum > 0 && s:IsInStringOrComment(lnum, col)
let [lnum, col] = searchpos(a:pattern, a:flags)
endwhile
while searchpair(s:end_start_regex, s:end_middle_regex, s:end_end_regex, 'bW',
\ s:end_skip_expr) > 0
if expand('<cword>') =~# '\<class\|module\>'
let found_lnum = line('.')
call setpos('.', saved_position)
return found_lnum
endif
endif

call setpos('.', saved_position)

return lnum
return 0
endfunction

" 3. GetRubyIndent Function {{{1
Expand All @@ -372,14 +367,14 @@ function GetRubyIndent(...)
" closest class declaration.
if g:ruby_indent_private_protected_style == 'indent'
if s:Match(clnum, s:private_protected_regex)
let class_line = s:SearchCode(s:class_regex, 'Wb')
let class_line = s:FindContainingClass()
if class_line > 0
return indent(class_line) + &sw
endif
endif
elseif g:ruby_indent_private_protected_style == 'outdent'
if s:Match(clnum, s:private_protected_regex)
let class_line = s:SearchCode(s:class_regex, 'Wb')
let class_line = s:FindContainingClass()
if class_line > 0
return indent(class_line)
endif
Expand Down
30 changes: 30 additions & 0 deletions spec/indent/private_protected_spec.rb
Expand Up @@ -44,6 +44,21 @@ def four
end
EOF

assert_correct_indenting <<-EOF
class One
def two
end
class Two
end
private
def four
end
end
EOF

assert_correct_indenting <<-EOF
class One
def two
Expand Down Expand Up @@ -78,6 +93,21 @@ def four
end
EOF

assert_correct_indenting <<-EOF
class One
def two
end
class Two
end
private
def four
end
end
EOF

assert_correct_indenting <<-EOF
class One
def two
Expand Down

0 comments on commit addba7e

Please sign in to comment.