views:

237

answers:

3

I'm having a problem with Emacs's indentation of Java enums. While it indents the first member OK, it wants to give all of the rest of the static enum members an additional level of indentation. It looks like this:

class MyClass {
    public enum MyEnum {
        ONE(1), //good
            TWO(2), // not good!
            THREE(3),
            FOUR(4);
        private final int value;
    }
}

When I run C-c C-s on the line that opens the enum, it gives me ((inclass 1) (topmost-intro 1)), which doesn't seem quite right -- it seems like it should be giving brace-list-open. When I run it on the first enum member, it gives me ((defun-block-intro 21)), which is definitely not right. Every subsequent member gives (statement-cont 50).

I'm in java-mode and I'm using the java style of indentation. Does anyone know what the problem might be?

+4  A: 

The problem is that Emacs doesn't support Java language features added in 1.5 or later. You will also have problems with generics, for instance.

EDIT: Amazingly, searching Google for "java enum site:debbugs.gnu.org" gives no results. I suggest filing a bug.

doublep
Bug sent through Emacs. We'll see what happens, I guess.
Masterofpsi
yes, it's also amazing that emacs support for Java just stopped in, what, 2003?
Cheeso
I've been working on the java support, actually - I just finished (i think) everything, so it should be checked into CC-mode pretty soon. This is one of the issues it fixed.
Nathaniel Flath
@Nathaniel Flath: Any news on that?
doublep
A: 

You can try using JDEE - I heard that they were planning to include some Java 6 support. Or if you're more adventurous you could try out malabar-mode, which claims to be a better java mode than JDEE. Funny enough the last commit in malabar(from a day ago) has the following message - "Fix enum constant indentation" :-)

Bozhidar Batsov
The latest relase of JDEE not only indents enums improperly, but actually indents the enum's closing brace AT THE SAME LEVEL as the badly-indented members.
Masterofpsi
This does not surprise me. My hopes for malabar, however, are much bigger.
Bozhidar Batsov
+1  A: 

The same problem existed in csharp-mode until last week. The way I fixed it was to add a new matcher in the c-basic-matchers-after setting for the csharp language. The new matcher looks like this:

;; Case 2: declaration of enum with or without an explicit base type
,@(when t
    `((,(byte-compile
         `(lambda (limit)
            (let ((parse-sexp-lookup-properties
                   (cc-eval-when-compile
                     (boundp 'parse-sexp-lookup-properties))))
              (while (re-search-forward
                      ,(concat csharp-enum-decl-re
                               "[ \t\n\r\f\v]*"
                               "{")
                      limit t)
                (unless
                    (progn
                      (goto-char (match-beginning 0))
                      (c-skip-comments-and-strings limit))
                  (progn
                    (save-match-data
                      (goto-char (match-end 0))
                      (c-put-char-property (1- (point))
                                           'c-type
                                           'c-decl-id-start)
                      (c-forward-syntactic-ws))
                    (save-match-data
                      (c-font-lock-declarators limit t nil))
                    (goto-char (match-end 0))
                    )
                  )))
            nil))
       )))

where csharp-enum-decl-re is defined as

(defconst csharp-enum-decl-re
  (concat
   "\\<enum[ \t\n\r\f\v]+"
   "\\([[:alpha:]_][[:alnum:]_]*\\)"
   "[ \t\n\r\f\v]*"
   "\\(:[ \t\n\r\f\v]*"
   "\\("
   (c-make-keywords-re nil
     (list "sbyte" "byte" "short" "ushort" "int" "uint" "long" "ulong"))
   "\\)"
   "\\)?")
  "Regex that captures an enum declaration in C#"
  )

What this does is set a text property on the brace-open after an enum declaration line. That text property tells cc-mode to indent the contents of the brace list differently. As a "brace list". Setting that property gets brace-list-open on the following line.

Maybe something similar will work for you.

You could customize the matchers for java yourself, with something like this, and If you open a bug, you could submit this as a suggested fix.

In C#, enums can derive from any integer type. so,

public enum MyEnumType : uint
{
     ONE = 1,
     TWO,
     THREE,
}

I think that in Java there is no such possibility. If so, the Java regex would be much simpler than the regex I used for C#.


Whoops! It just occurred to me, that with Java's simpler syntax, there is also the possibility that you can turn on brace-lists, just by setting the enum keyword in the right language constant. If that's so, then the solution for you could be as simple as:

(c-lang-defconst c-inexpr-brace-list-kwds
  java '("enum"))

This didn't work for C# because of its more complex syntax.


EDIT - no that didn't work. It's more complicated than that.

Cheeso