diff options
Diffstat (limited to 'indent/ruby.vim')
-rw-r--r-- | indent/ruby.vim | 36 |
1 files changed, 30 insertions, 6 deletions
diff --git a/indent/ruby.vim b/indent/ruby.vim index afa72995..e4a295fd 100644 --- a/indent/ruby.vim +++ b/indent/ruby.vim @@ -93,6 +93,9 @@ let s:ruby_indent_keywords = \ '\|\%([=,*/%+-]\|<<\|>>\|:\s\)\s*\zs' . \ '\<\%(if\|for\|while\|until\|case\|unless\|begin\):\@!\>' +" Def without an end clause: def method_call(...) = <expression> +let s:ruby_endless_def = '\<def\s\+\k\+[!?]\=\%((.*)\|\s\)\s*=' + " Regex used for words that, at the start of a line, remove a level of indent. let s:ruby_deindent_keywords = \ '^\s*\zs\<\%(ensure\|else\|rescue\|elsif\|when\|end\):\@!\>' @@ -112,10 +115,26 @@ let s:end_middle_regex = '\<\%(ensure\|else\|\%(\%(^\|;\)\s*\)\@<=\<rescue:\@!\> " Regex that defines the end-match for the 'end' keyword. let s:end_end_regex = '\%(^\|[^.:@$]\)\@<=\<end:\@!\>' -" Expression used for searchpair() call for finding match for 'end' keyword. -let s:end_skip_expr = s:skip_expr . - \ ' || (expand("<cword>") == "do"' . - \ ' && getline(".") =~ "^\\s*\\<\\(while\\|until\\|for\\):\\@!\\>")' +" Expression used for searchpair() call for finding a match for an 'end' keyword. +function! s:EndSkipExpr() + if eval(s:skip_expr) + return 1 + elseif expand('<cword>') == 'do' + \ && getline(".") =~ '^\s*\<\(while\|until\|for\):\@!\>' + return 1 + elseif getline('.') =~ s:ruby_endless_def + return 1 + elseif getline('.') =~ '\<def\s\+\k\+[!?]\=([^)]*$' + " Then it's a `def method(` with a possible `) =` later + call search('\<def\s\+\k\+\zs(', 'W', line('.')) + normal! % + return getline('.') =~ ')\s*=' + else + return 0 + endif +endfunction + +let s:end_skip_expr = function('s:EndSkipExpr') " Regex that defines continuation lines, not including (, {, or [. let s:non_bracket_continuation_regex = @@ -575,6 +594,11 @@ function! s:AfterUnbalancedBracket(pline_info) abort call cursor(info.plnum, closing.pos + 1) normal! % + if strpart(info.pline, closing.pos) =~ '^)\s*=' + " special case: the closing `) =` of an endless def + return indent(s:GetMSL(line('.'))) + endif + if s:Match(line('.'), s:ruby_indent_keywords) return indent('.') + info.sw else @@ -613,7 +637,7 @@ function! s:AfterIndentKeyword(pline_info) abort let info = a:pline_info let col = s:Match(info.plnum, s:ruby_indent_keywords) - if col > 0 + if col > 0 && s:Match(info.plnum, s:ruby_endless_def) <= 0 call cursor(info.plnum, col) let ind = virtcol('.') - 1 + info.sw " TODO: make this better (we need to count them) (or, if a searchpair @@ -660,7 +684,7 @@ function! s:IndentingKeywordInMSL(msl_info) abort " TODO: this does not take into account contrived things such as " module Foo; class Bar; end let col = s:Match(info.plnum_msl, s:ruby_indent_keywords) - if col > 0 + if col > 0 && s:Match(info.plnum_msl, s:ruby_endless_def) <= 0 let ind = indent(info.plnum_msl) + info.sw if s:Match(info.plnum_msl, s:end_end_regex) let ind = ind - info.sw |