Bug 449787 - [typing] Automatically put semicolon at end of line if complete expression
Summary: [typing] Automatically put semicolon at end of line if complete expression
Status: ASSIGNED
Alias: None
Product: JDT
Classification: Eclipse Project
Component: Text (show other bugs)
Version: 4.5   Edit
Hardware: All All
: P5 enhancement (vote)
Target Milestone: ---   Edit
Assignee: JDT-Text-Inbox CLA
QA Contact:
URL:
Whiteboard:
Keywords:
Depends on:
Blocks:
 
Reported: 2014-11-03 10:04 EST by Alex Blewitt CLA
Modified: 2014-11-12 08:00 EST (History)
2 users (show)

See Also:


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Alex Blewitt CLA 2014-11-03 10:04:58 EST
When hitting enter on a line without a semi-colon, add one automatically if it is a complete expression.

For example:

System.out.println("Hello World")| <- cursor here, press enter

System.out.println("Hello World"); <- semi-colon added
| <- cursor now here

Semi-colons could be added if:

1. Preference was set to allow this
2. It wasn't a { or a statement expecting a block (for, if, while)
3. The expression was complete (i.e. no imbalancing ( or ) added on the line)

Sometimes newlines are used to wrap expressions or to do method chaining, so if the following line started with an infix operator (such as .) the semi-colon could be removed automatically.

Adding the semi-colon could be conservative (i.e. might not work in some cases) but would be much faster than adding a new line, then going up and using a quick-fix to add one (or go back up to the line and typing the semi-colon). If it was good enough it would feel that the IDE is working with a language that didn't need semi-colons.
Comment 1 Dani Megert CLA 2014-11-11 07:51:34 EST
Alex, since 4.4 we auto-insert the semicolon when using content assist (see bug 198508). Are you not using content assist?
Comment 2 Alex Blewitt CLA 2014-11-11 09:09:33 EST
If I use the template 'sysout' I see the semi-colon at the end; but I'm not sure if that's because it's part of the template or not.

I also found a preference under 'Java -> Editor -> Typing' (which was unselected) that allows for braces and semi-colons to be inserted. It says this only works if 'Smart insert mode' is enabled, but I didn't find the corresponding option (and searching in preferences doesn't show it either). I assume that it's enabled because when I type ( it puts in the ).

If I type:

char c = "hello".char|

and then hit tab, it expands to:

char c = "hello".charAt(|)

I don't see the semicolon being added there.

If I do:

System.g|

and then hit tab, it expands to: 

System.gc();

which does have a semi-colon on.

Is the difference between an expression and a statement? Generally I don't see the semi-colon being inserted when I expand to a method that returns a value.

System.get|
->
System.getenv()

without a semi-colon

System.ex|
->
System.exit(|);

So if this is the case, the semi-colon is only being added after 'void' expressions. Sometimes there are methods that return a value where you want the effect but aren't bothered by the result; for example, Map.put() returns the old value (if any) but in most cases you want to have:

map.put("foo","bar")| (followed by a return)
->
map.put("foo","bar");
|
Comment 3 Dani Megert CLA 2014-11-11 11:10:33 EST
(In reply to Alex Blewitt from comment #2)
> So if this is the case, the semi-colon is only being added after 'void'
> expressions.

Correct, see the bug I cited in comment 1.

> Sometimes there are methods that return a value where you want
> the effect but aren't bothered by the result; for example, Map.put() returns
> the old value (if any) but in most cases you want to have:
> 
> map.put("foo","bar")| (followed by a return)
> ->
> map.put("foo","bar");

Yes, and sometimes you don't. Especially with the new stream APIs chaining will become more and more popular. The other thing is that one usually puts the dot on the next line when chaning and that's also how the formatter formats the source.

It would for sure have to be a new option that is off by default.
Comment 4 Alex Blewitt CLA 2014-11-12 08:00:48 EST
(In reply to Dani Megert from comment #3)
> > Sometimes there are methods that return a value where you want
> > the effect but aren't bothered by the result; for example, Map.put() returns
> > the old value (if any) but in most cases you want to have:
> > 
> > map.put("foo","bar")| (followed by a return)
> > ->
> > map.put("foo","bar");
> 
> Yes, and sometimes you don't. Especially with the new stream APIs chaining
> will become more and more popular. The other thing is that one usually puts
> the dot on the next line when chaning and that's also how the formatter
> formats the source.
> 
> It would for sure have to be a new option that is off by default.

I agree that streaming is important. What I'd suggest is that it is implemented as follows:

map.put("foo","bar")|
 (return) ->
map.put("foo","bar");
|
 (dot) ->
map.put("foo","bar")
.|

so when a continuation character (realistically, a non alphanumeric character) is added on the following line that the prior line - if it ends with a ; - is removed. 

Updates to lines happen already; e.g. when you e.g. delete a paren the corresponding other paren would also be deleted again. So in this case, a combination of ';\n.' would be updated to be '\n.'

This would also come in handy when running builder operations with futures because you could have:

CompletableFuture future = CompletableFuture.runAsync(...);
|

and by typing on the next line you could auto-chain:

CompletableFuture future = CompletableFuture.runAsync(...)  <- note removal of ;
.|

so you could do

.andThen(...);
|

.andThen(...)
.andThen(...)|

etc.