derekwyatt/vim-scala

Indentation error after anonymous function block

tek opened this issue · 6 comments

tek commented
object Foo {
  def foo {
    val bar = { item =>
    }
  wrong
  }
}

Looks like this on 7.4.491.

Oddly enough, this works for similar cases; the val has to the first thing in the block, and there has to be a parameter

def foo {
  val x = 1
  val bar = { item =>
...

indents the "wrong" line correctly, as does

def foo {
  val bar = {
...

I think even the first case above is behaving incorrectly; it's setting the indentation for the "wrong" line to be the same as the val x = 1 line, which just happens to result in correct behavior in that case. I think the problem lies in the regex of scala#MatchesIncompleteDefValr, which is failing to identify it as an incomplete line. My first attempts to fix it broke too many things though; this hint might help someone else debug the issue, though.

We've seen this before. For some reason (it seems) that set virtualedit=all fixes the problem. (I don't see this when running in my config).

Can you set that and see if it fixes things?

tek commented

nope, I had the setting on the (empty) default.

edit: virtualedit=all has no effect either.

Hmm... interesting. I actually can reproduce this.

object Foo {
  def foo {
    val bar = { item =>
    }
  wrong
  }
}
object Foo {
  def foo {
    val bar = { item
    }
  wrong
  }
}
object Foo {
  def foo {
    val bar = {
    }
    right
  }
}

So it's something to do with the fact that { isn't on the end of the line (give or take spaces).

tek commented

which fits the regex @andrewla pointed out.

The fix I tried is

diff --git a/indent/scala.vim b/indent/scala.vim
index 5d812e4..156c162 100644
--- a/indent/scala.vim
+++ b/indent/scala.vim
@@ -27,6 +27,7 @@ let s:typeSpecMatcher = '\%(\s*\[\_[^\]]*\]\)'
 let s:defArgMatcher = '\%((\_.\{-})\)'
 let s:returnTypeMatcher = '\%(:\s*\w\+' . s:typeSpecMatcher . '\?\)'
 let g:fullDefMatcher = '^\s*' . s:defMatcher . '\s\+' . s:funcNameMatcher . '\s*' . s:typeSpecMatcher . '\?\s*' . s:defArgMatcher . '\?\s*' . s:returnTypeMatcher . '\?\s*[={]'
+let s:incompleteEndingMatcher = '\([=({]\|{.*=>\)\s*$'

 function! scala#ConditionalConfirm(msg)
   if 0
@@ -185,7 +186,7 @@ function! scala#NumberOfBraceGroups(line)
 endfunction

 function! scala#MatchesIncompleteDefValr(line)
-  if a:line =~ '^\s*\%(' . s:defMatcher . '\|\<va[lr]\>\).*[=({]\s*$'
+  if a:line =~ '^\s*\%(' . s:defMatcher . '\|\<va[lr]\>\).*' . s:incompleteEndingMatcher
     return 1
   else
     return 0

I don't remember what it broke, though.