Question

I'm trying to get vim to indent continuation lines starting on a new line this way:

def foo
  open_paren_at_EOL(
      100, 200)

  a = {
      :foo => 1,
  }
end

Vim 7.3's default indentation [1] for those lines looks like this:

def foo
  open_paren_at_EOL(
    100, 200)

  a = {
    :foo => 1,
  }
end

I have tried multiple cino= values and I even tried adapting the .vim script from [2] but with no success.

My .vimrc is here:

https://github.com/slnc/dotfiles/blob/master/.vimrc

Thanks!

Was it helpful?

Solution

What you could do to get this kind of indenting is to find out which areas of the GetRubyIndent function are relevant to these continuations and increase the return values. For the example you gave, this seems to do the job:

diff --git a/indent/ruby.vim b/indent/ruby.vim
index 05c1e85..6f51cf2 100644
--- a/indent/ruby.vim
+++ b/indent/ruby.vim
@@ -368,7 +368,7 @@ function GetRubyIndent(...)

  " If the previous line ended with a block opening, add a level of indent.
  if s:Match(lnum, s:block_regex)
-    return indent(s:GetMSL(lnum)) + &sw
+    return indent(s:GetMSL(lnum)) + &sw * 2
  endif

  " If the previous line ended with the "*" of a splat, add a level of indent
@@ -383,7 +383,7 @@ function GetRubyIndent(...)
    if open.pos != -1
      if open.type == '(' && searchpair('(', '', ')', 'bW', s:skip_expr) > 0
        if col('.') + 1 == col('$')
-          return ind + &sw
+          return ind + &sw * 2
        else
          return virtcol('.')
        endif

I'm not entirely sure if this won't break anything else, but it seems like a safe change to me. If you find cases that don't indent the way you want, you could just fix it the hard way: search for return within the limits of the function, then increase the indentation that is returned by one more &shiftwidth (or &sw). Check if it works, and if it doesn't, undo and then move on to the next return, until you actually find it.

You could fork vim-ruby, or you could just copy the indent/ruby.vim file to ~/.vim/indent/ruby.vim and change it as you wish. It should have priority over the bundled indent/ruby.vim.

If you're looking for a completely unobtrusive solution, that would be difficult. Theoretically, you could override the GetRubyIndent function as an indenter by using setlocal indentexpr=CustomGetRubyIndent(v:lnum), and then define a CustomGetRubyIndent function, which implements your behaviour in particular cases only and delegates to GetRubyIndent. I wouldn't recommend going that far, though, it could get rather messy.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top