Subject: Re: bug#75154: 31.0.50; java-ts-mode. Issues with Indentation

From: Artem Bliznetsov <[email-masked]>
Date: Sun, 02 Mar 2025 01:34:05 +0300

> Ok, I attached a patch-set, if you apply this patch-set on top of _latest master_, most of the fixable problems in this report should be fixed/improved. Now, let me reply each item:

Thank you for your patch. I have tested your changes.
During compilation, I encountered the following warning:

In java-ts-mode--first-line-on-multi-line-string:
java-ts-mode.el:105:68: Warning: Unused lexical argument ‘bol’

However, everything seems to be working fine. 

> 1. In the patch I added java-ts-mode-method-chaining-indent-offset,
>    defaults to 8

Thank you! That’s great. Most users accustomed to 8-space indentation
will find the default setting comfortable. Those who prefer
4 spaces are also taken into account.

> 2. Set electric-indent-chars to nil so it doesn’t indent the current
>    line when you press RET.

Actually, setting electric-indent-chars to nil disables all automatic
indentation. Now, I’m reconsidering whether the initial example I
provided was perhaps misguided and beyond what should be expected.

2) Inner Classes
Example 1:
public class Outer {
class Inner {| <-- cursor here moves Inner class unexpectedly

    }
}
Example 2:
public class Outer {
    class Inner { // ???
        | <-- cursor here.           
    }
}

Again, I compared this behavior with IntelliJ IDEA and
wondered why it shouldn't work the same way here. Essentially,
what are we violating if we write

public class Outer {
class Inner {}
}

There are no syntax errors, but class Inner is not indented.
Yes, the indentation appears when pressing RET after {, but if we
then remove the spaces before class Inner and press RET again
after {, electric-indent corrects the indentation.

On one hand, this seems reasonable. On the other hand, shouldn’t this
be handled by an external formatter? This is a minor issue and may
not require any changes.

> 3. The indentation is fixed once you type a valid statement, this is
>    because tree-sitter needs something to generate a parse-tree. We
>    can add some heuristics that gives a more intuitive indentation
>    when the line is empty, eg, "if prev line is while and current line
>    is empty, indent one level", etc. But that’s a more complicated
>    feature and I’ll defer to Theo.

>
> 4.
> - Triple quote support in electric-pair-mode -> let’s open a separate
>   bug report for it and have electric-pair-mode maintainer take a
>   look.

Should I classify this as a bug report? I didn’t notice any feature
request category in the bug tracker. This is a small improvement that
would add some convenience. Triple-quoted text blocks are not
exclusive to Java; many other languages use them as well.

> - In general, TAB in Emacs prog modes indent to a fixed point, rather
>   than just inserting a tab.

I wasn’t aware of how this works. I briefly tested python-ts-mode and
noticed that TAB behaves more freely there.

>I added a indent rule such that aligns a
>   line in a string block to the previous line, for the first line, it indents one level.
>

> 6. For the parameter indentation, I recently added
>    c-ts-common-baseline-indent-rules that can handle it correctly. So
>    if we remove the existing indent rule for the parameters and add
>    c-ts-common-baseline-indent-rules at the end so the indentation
>    falls back to it, the indentation would look like this:
>
> public class TextBlocks {
>     public record StudentRecord(String firstName,
>                                 String lastName,
>                                 Long studentId,
>                                 String email) {
>
>     }
>
>
>     public String filterData(@RequestParam(required = false) String name,
>                              @RequestParam(required = false) String name,
>                              @RequestParam(required = false) Integer age
>     )
> }
>
> Seems fair? Theo, WDYT?

I tested it, and it works. But do you see how it behaves?
I’m not sure how to describe it correctly, but it feels a bit odd.
If issue #3 gets resolved, everything should look much better.

>> - Annotations (@Annotations)
> It seems to work fine? What’s the problem that you see?

That was my mistake. I didn’t check which face was being used—or
whether there was one at all. By default, java-mode uses
c-annotation-face,while java-ts-mode uses font-lock-constant-face.
One inherits from the other. I use the Modus theme, so something may
have changed there.I only noticed it because, without any additional
configuration, java-mode highlighted annotations by default.

Anyway, it’s not that important now.

>> - Diamond Brackets (<>)
> Same as above, what’s the desired behavior?

I just tested it with emacs -q and didn’t see any specific face for <>
in java-mode. I use the popular package rainbow-delimiters.el,
which does highlight <> in java-mode, but it hasn’t been updated in
a while and doesn’t work with java-ts-mode.Currently, java-ts-mode
applies font-lock-operator-face to <>, =, ->, &&, and possibly other
symbols.That doesn’t seem quite right—should all operators really be
highlighted this way? Some users might prefer extensive syntax
highlighting, but it feels excessive to me.

For reference, IntelliJ IDEA also doesn’t highlight <> by default.
It requires a third-party plugin for that. So I’m not sure whether
this should be added or not. If it is, that would be a nice improvement.

>> - Constants, Static Variables, Enum Variables should be highlighted with
>> distinct colors and optionally italic font
>
> For constants, they aren’t highlighted in constant face because rules
> for ‘definition’ and ‘expression’ feature overrides them with
> variable-name face. We can fix this by either moving the ‘constant’
> face after ‘definition’ and ‘expression’ feature, or remove the
> :override flag for ‘definition’ and ‘expression’ feature. Theo, any
> suggestions here?

That would be great to implement! I’m not sure how to show you exactly
how it "should" look. Is it possible to attach images here?
Although, Theo might have IntelliJ IDEA CE installed, so he likely
already knows how it can look visually appealing.

>> - Unused Variables or Classes (Grayed Out)
>> - Unused variables, unused classes, etc., highlighted in gray. Not
>     sure if this can be achieved
>
> Tree-sitter can’t do this. So the only option is to use eglot for it.

Thanks for the clarification! I’ll try to look into this.

----
By the way, I discovered something else today. In
java-ts-mode--keywords, the following keywords are missing:
boolean, byte, char, const, double, float,
goto, int, long, short, super, this, void, permits, var, when, yield, _.
According to the Java Language Specification
https://docs.oracle.com/javase/specs/jls/se23/html/jls-3.html#jls-3.9,
the keyword @interface should be removed since annotations are already
handled separately, and interface is already in the list.

> Finally, some suggestions on communication. As you said on reddit,
> you’re not a native English speaker, so I can’t blame you, but some
> minor changes to wording can make your message sound a lot kinder :)
> For example, short and imperative sentences like "you understand?"
> sounds harsh and condescending; OTOH something like "I hope you can
> understand/get that..." is a lot better. As a rule of thumb, the less
> certain and the longer your expression is, the softer it sounds ;-)
>
> Yuan

Yes, it is true that English is not my native language. However, upon
reviewing my messages,I understand that in certain instances, I was not
sufficiently polite. I will make an effort to improve this.
I regret that this occurred.