summaryrefslogtreecommitdiffstats
path: root/indent/ruby.vim
diff options
context:
space:
mode:
Diffstat (limited to 'indent/ruby.vim')
-rw-r--r--indent/ruby.vim36
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