Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Emacs scala-mode newline-and-indent weirdness

Tags:

emacs

scala

I have the following code in Emacs under scala-mode (from the Scala 2.8 package):

object t1 {
  def main (args: List[String]) = {
    println("Hello")
  }
}

I also have my return key set to newline-and-indent. When I repeatedly hit return after the last brace, it goes to the leftmost column for one blank line. When I press return again, it indents two spaces. Then it stays at this indentation thereafter. Obviously it shouldn't do this.

However, when I repeatedly run newline-and-indent by the M-x and typing newline-and-indent, I don't get the two-space indentation. The same goes for reindent-then-newline-and-indent.

Why is there this difference?

like image 783
qrest Avatar asked Sep 01 '10 01:09

qrest


1 Answers

Your problem is stemming from the fact that you rebound enter to newline-and-indent, which doesn't seem to be idiomatic when using scala-mode. newline-and-indent ends up calling indent-according-to-mode, which checks for some undesirable settings, works around them if necessary, and if everything is OK, ends up calling indent-line-function, which is a buffer local variable.

Since this is mode-specific, modes define their own indent-line-function. Most have pretty consistent behavior, but Scala's function is scala-indent-line, seen here:

(defun scala-indent-line ()
  "Indent current line as smartly as possible.
When called repeatedly, indent each time one stop further on the right."
  (interactive)
  (if (or (eq last-command this-command)
          (eq last-command 'scala-undent-line))
      (scala-indent-line-to (+ (current-indentation) scala-mode-indent:step))
    (let 
    ((indentation (scala-indentation)))
      (scala-indent-line-to indentation))))

The funny thing about this is that it detects repeated calls and indents further over each time. When using M-x, last-command is not scala-indent-line, it's execute-extended-command. So, when using M-x, it continues to indent at the correct indentation level. When bound to a key, however, it notices it was executed immediately previously and indents an extra level.

The effect isn't cumulative...I think this is because of the odd command set at the end of the function, which initially indents the line, but then checks for the correct indentation with (scala-indentation) and indents accordingly.

I'm not 100% on this, but at first glance that's what seems to be going on.

like image 76
R. P. Dillon Avatar answered Sep 22 '22 15:09

R. P. Dillon