Package: emacs;
Reported by: Artem <snake05865 <at> gmail.com>
Date: Sat, 28 Dec 2024 04:38:02 UTC
Severity: minor
Found in version 31.0.50
View this message in rfc822 format
From: Artem <snake05865 <at> gmail.com> To: 75154 <at> debbugs.gnu.org Subject: bug#75154: 31.0.50; java-ts-mode. Issues with Indentation Date: Fri, 27 Dec 2024 18:34:45 +0300
Hello I've identified several issues with indentation in java-ts-mode where it doesn't work as expected. Let me first clarify what I consider "expected" behavior - there are things that are "GOOD", "BAD but allowed", and "Opinion-based. Here are the specific problems: 1) Chaining Methods in the Stream API and Lambda Expressions Example 1: class Foo { void Foo() { List<Customer> customers = customer | <-- Actual (BAD) | <-- Expected (GOOD) (8 spaces) } } When continuing the statement List<Customer> customers = customer .stream and then adding closing parentheses List<Customer> customers = customer .stream() <-- The method filter will move to 4 spaces automatically .filter <-- without parentheses .filter() <-- closing bracet and method moving to 4 spaces This behavior is problematic. In java-mode, this does not occur.IntelliJ IDEA uses 8 spaces for method chains,which makes the code more readable. While some examples use 2 spaces (e.g., for web snippets),in production environments, 8 spaces are more common. This should ideally be customizable for end users. Moreover, the current indentation is hardcoded and doesn’t allow flexibility. For instance, in python-ts-mode, pressing TAB allows you to adjust constructions more freely. This level of flexibility would be beneficial in this context This inflexibility prevents writing common patterns like: @Override protected void configure(HttpSecurity http) throws Exception { http .authorizeRequests() .antMatchers("/admin/**").hasAuthority("ADMIN") .antMatchers("/user").hasAnyAuthority("USER", "ADMIN") .antMatchers("/", "/index").permitAll() Example 2: The following looks correct - public class FloodFill { public static void main(String[] args) { List<Foo> stream = students.stream() .filter(item -> { return item.getValue() > 100 && item.isActive(); }) .map() .collect(); } } But java-ts-mode produces: public class FloodFill { public static void main(String[] args) { List<Foo> stream = students.stream() .filter(item -> { return item.getValue() > 100 && item.isActive(); }) .map() .collect(); } } 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. } } Why does this happen? I did not request this behavior. While Example 1 demonstrates bad code style, it is technically valid. Such "magical" formatting should be handled by a Java formatter, not by Emacs or Tree-sitter rules. IntelliJ IDEA does not apply such formatting; it leaves this task to the formatter. Example 3: public class Outer { class Inner{ void foo(){ }|<--start position. RET |<-- expected position |<-- actual } } If Inner class has incorrect indentation, subsequent code will also be incorrectly indented. 3) for, if, else if, while, do-while without braces public class While { { while () | <-- Expected | <-- Actual } } Although this is bad coding style, it’s allowed and compiles correctly. 4) Java 15 text blocks Text blocks are not properly handled public class TextBlocks { System.out.println(ctx.fetch(""" SELECT table_schema, count(*) FROM information_schema.tables """)); } - Triple quotes handling (should electric-pair-mode be enhanced?) - Text block alignment is opinion-based and should be adjustable with TAB - New SQL expressions should be sticky It seems such multiline strings also do not work well, for example: "'The time has come,' the Walrus said,\n" + 5) Broken Syntax Highlighting public class Outer { HELLO EMACS <-- Write something here class Inner{ <-- This class will not be highlighted void foo(){ } } } Tree-sitter should ignore such uncommon cases to maintain syntax highlighting 6) Multiple Parameters in Methods Example 1 public record StudentRecord( String firstName, String lastName, Long studentId, String email) Example 2 public String filterData(@RequestParam(required = false) String name, @RequestParam(required = false) String name, @RequestParam(required = false) Integer age ) java-ts-mode fails to handle these cases correctly. Desired Fontification (Out of the Box): - Annotations (@Annotations) - Diamond Brackets (<>) - Constants, Static Variables, Enum Variables should be highlighted with distinct colors and optionally italic font - Unused Variables or Classes (Grayed Out) - Unused variables, unused classes, etc., highlighted in gray. Not sure if this can be achieved with Tree-sitter. Anyway, with Flymake + Eglot, it currently works in a somewhat clunky manner. Example public class TextBlocks { enum AnEnum { CONST1, CONST2 } <-- No effect for unused AnEnum. public static final String HELLO ="HELLO"; public static void main(String[] args) { int i = 0; <-- Flymake identifies as unused but looks unpolished. System.out.println(HELLO); } } Overall: I may have missed some aspects, but as it stands, Emacs is not comfortable for Java development with these issues. Some information that might be helpful: - https://github.com/dakrone/eos/blob/dd8aa3a25b496397dd0162d229de571989668619/eos-java.org?plain=1#L30 .Not sure why this Elasticsearch developer created so many custom rules for indentation. - https://github.com/Michael-Allan/Java_Mode_Tamed A major Java mode with sensible fontification. - JetBrains Intellij IDEA Community Edition - File>Settings>Editor>Color Scheme>Java Java for understanding which colors are needed and what is missing. - Editor>Color Scheme>Java>Code Style>Java for indentation settings.
GNU bug tracking system
Copyright (C) 1999 Darren O. Benham,
1997,2003 nCipher Corporation Ltd,
1994-97 Ian Jackson.