Bug 531061 - Non-blocking Java completion
Summary: Non-blocking Java completion
Status: RESOLVED FIXED
Alias: None
Product: JDT
Classification: Eclipse Project
Component: UI (show other bugs)
Version: 4.5   Edit
Hardware: All All
: P3 enhancement (vote)
Target Milestone: 4.15 M1   Edit
Assignee: Mickael Istria CLA
QA Contact:
URL:
Whiteboard:
Keywords: noteworthy, performance, plan
: 536940 (view as bug list)
Depends on: 544529 251156 538630 538656 553577 558247 558921 559251
Blocks: 101420 547740 553533 558893 559135 561474
  Show dependency tree
 
Reported: 2018-02-12 11:21 EST by Mickael Istria CLA
Modified: 2020-03-26 04:26 EDT (History)
13 users (show)

See Also:


Attachments
Video demo (11.40 MB, video/mp4)
2019-12-16 16:03 EST, Mickael Istria CLA
no flags Details
Mylyn warning (22.16 KB, image/png)
2020-01-20 04:47 EST, Pierre-Yves Bigourdan CLA
no flags Details

Note You need to log in before you can comment on or make changes to this bug.
Description Mickael Istria CLA 2018-02-12 11:21:06 EST
JDT should support asynchronous completion to not block user when computing completion. Then it would become possible to make content-assist always active whenever user types any character.
Comment 1 Mickael Istria CLA 2018-02-12 11:21:52 EST
Here is a draft I authored when developing async content assit: https://git.eclipse.org/r/#/c/86644/
Comment 2 Stephan Herrmann CLA 2018-02-12 17:31:06 EST
I was about to ask about the intended user experience (worrying that such feature might badly interfere with typing), but then I found that the gerrit is abandoned already.

Without any explanation an abandoned gerrit doesn't seem to help much, hence closing.
Comment 3 Mickael Istria CLA 2018-02-13 03:01:12 EST
The Gerrit is here for reference. I abandonned it because I won't personally work on this. It was moreover not so welcome a while ago because the async content-assist was kind of new and didn't feel safe. Now that many *DT do use it, it may be a better time for JDT to consider it.
The idea is still valid and JDT should at least have support for it in an optional manner one day. So I'm reopening to track discussion and progress on this topic.

The UX associated with async content-assist is more in order to never let user get a frozen editor so they can always keep typing and see editor react. While JDT has improved regarding performance, it's still frequent to see minor freezes/latencies in JDT editor with content assist because of its synchronous nature.
Users typing simultaneously as content-assist computes seems to work correctly, since none of known adopters have complained about it so far.

Then the next step would be a continuous enablement of content-assist. Like IntelliJ IDEA is doing and like the majority of IJ users do report as it being one of its killer-features compared to Eclipse IDE/JDT. That would be a separate story as it involves some other tweaks (such as probably avoiding the auto-insert when completion was triggered automatically).
Comment 4 Stephan Herrmann CLA 2018-02-13 08:38:58 EST
(In reply to Mickael Istria from comment #3)
> That would be
> a separate story as it involves some other tweaks (such as probably avoiding
> the auto-insert when completion was triggered automatically).

That's what I was worried about. If we don't have a story how to avoid the conflict between async content assist and auto-insert then the entire feature is a big fail in UX.

So, when auto-insert is disabled, async content assist enabled, what's the unambiguous gesture for selecting a proposal? By unambiguous I mean it must be a gesture that doesn't occur during normal editing. Also, is there a protocol for invalidating proposals that no longer match the current input in the editor?

If this discussion is already happening elsewhere: please provide a link and I'll be quiet. Otherwise, let's have the discussion here.

Disclaimer: I'm a big fan of explicitly requesting content assist, rather than unsolicited proposals popping up from nowhere.
Comment 5 Mickael Istria CLA 2018-02-13 09:20:00 EST
(In reply to Stephan Herrmann from comment #4)
> That's what I was worried about. If we don't have a story how to avoid the
> conflict between async content assist and auto-insert then the entire
> feature is a big fail in UX.

Right.

> So, when auto-insert is disabled, async content assist enabled, what's the
> unambiguous gesture for selecting a proposal? By unambiguous I mean it must
> be a gesture that doesn't occur during normal editing.

Hitting Enter or clicking the proposal is the unambiguous gesture I have in mind.

> Also, is there a
> protocol for invalidating proposals that no longer match the current input
> in the editor?

The async content-assist is updated similarly to the synchronous one: either it will filter the current proposals according to the newly added character or will recompute a full list of proposal (just like if you hit Ctrl+Space). The difference is that the filtering or computing happens in a dedicated thread which doesn't block UI. Performance-wise, it's quite similar to synchronous one; and the risk of having displayed proposals out of sync with editor are as big as having a UI Freeze when invoking completion these days.
The completion framework assumes that selected proposal applies to the current text. But I'm not sure whether it checks that selected proposal is provided by a completion session matching current state; but if it doesn't, then it's a bug to fix in JFace. It's indeed not something JDT should work around.

> If this discussion is already happening elsewhere: please provide a link and
> I'll be quiet. Otherwise, let's have the discussion here.

Here is fine ;)

> Disclaimer: I'm a big fan of explicitly requesting content assist, rather
> than unsolicited proposals popping up from nowhere.

No problem, I don't think the goal is to ditch current behavior.
It's more:
1. to avoid UI freezes which can still block users
2. to enable (opt-in to get started) a new workflow of edition with continuous assistance for those who want it.
Comment 6 Stephan Herrmann CLA 2018-02-13 15:47:36 EST
(In reply to Mickael Istria from comment #5)
> > So, when auto-insert is disabled, async content assist enabled, what's the
> > unambiguous gesture for selecting a proposal? By unambiguous I mean it must
> > be a gesture that doesn't occur during normal editing.
> 
> Hitting Enter or clicking the proposal is the unambiguous gesture I have in
> mind.

Sounds like every linebreak will get an unwanted proposal inserted.
 
> ... and the risk of having displayed proposals out of sync with
> editor are as big as having a UI Freeze when invoking completion these days.

When I type at 300 kpm then each list of proposals would be relevant for no longer than 200ms. Do you consider 200ms already a UI freeze?

> The completion framework assumes that selected proposal applies to the
> current text. But I'm not sure whether it checks that selected proposal is
> provided by a completion session matching current state; but if it doesn't,
> then it's a bug to fix in JFace. It's indeed not something JDT should work
> around.

good.
Comment 7 Mickael Istria CLA 2018-02-13 16:00:32 EST
(In reply to Stephan Herrmann from comment #6)
> Sounds like every linebreak will get an unwanted proposal inserted.

Ok, there are indeed some cases when to avoid automatically popup of completion. So we'd have to restraint when completion is started. For example, not start completion automatically when we're just after a complete instruction or block for instance, and probably in other places to figure out.

> When I type at 300 kpm then each list of proposals would be relevant for no
> longer than 200ms. Do you consider 200ms already a UI freeze?

I think in a text editor, 200ms can be considered as a freeze. IIRC the threeshold for user feeling annoyed by latency while typing text is something like 50ms. I'll try to find my source later and will share.
And a cool thing with completion is that you don't have to type at 300kpm to write more code. With a good completion always available, one actually types way less but do often code faster because the power of the tool is more accessible.

If you have the opportunity, give a try to IntelliJ Java editor. It's really a good reference in term of having a good completion proposal for Java, both in term of quality of the proposals, how they insert in the code and in term of "high-availability" since user almost never has to ask for completion to show or hide: it's almost always there when you want (or when you don't care), and not there when you don't want it
Comment 8 Mickael Istria CLA 2018-02-14 08:45:56 EST
For the record, I just perceived a UI Freeze from JDT editor, which UI Freeze monitoring reported as during 1.6s plus 1s (there are 2 reports). And, as a result, I also got my current "Console" view replaced by the "Error Log" ones showing the freeze events.
Comment 9 Sarika Sinha CLA 2018-02-27 06:52:02 EST
Moving it out of M6.
Comment 10 Mickael Istria CLA 2018-09-05 05:04:43 EDT
Another occurrence of synchronous content-assist being irritating from time to time: today, for no obvious reasons, some of the content assist providers are failing or too slow. So I constantly get the popup to configure the content-assist and content-assist is not usable until I try to troubleshot the issue.
With async content assist, it's possible to still show partial results, which may in many cases be sufficient for the users.
Comment 11 Mickael Istria CLA 2018-09-05 05:20:26 EDT
bug 538630 is a requirement before JDT can move to async content-assist.
Comment 12 Eclipse Genie CLA 2018-09-10 06:32:13 EDT
New Gerrit change created: https://git.eclipse.org/r/129022
Comment 13 Mickael Istria CLA 2018-11-21 18:45:34 EST
*** Bug 536940 has been marked as a duplicate of this bug. ***
Comment 14 Lars Vogel CLA 2019-05-23 04:12:22 EDT
Paul or Julian, AFAIK Mickael is busy with other work. Maybe you can help here? Making code completion async would be a huge leap for the usage of the IDE.
Comment 15 Julian Honnen CLA 2019-05-23 08:45:27 EDT
(In reply to Lars Vogel from comment #14)
> Paul or Julian, AFAIK Mickael is busy with other work. Maybe you can help
> here? Making code completion async would be a huge leap for the usage of the
> IDE.

The feature is currently stuck on Bug 538656.
Comment 16 Mickael Istria CLA 2019-06-28 05:26:51 EDT
I'm reducing the scope of this particular issue to make Java completion non-blocking when possible. The fact that it's async and running in non-UI Thread is an implementation details to remediate the issue, but I prefer keeping the declaration of "Asynchronous" out of the scope as some could interpret it as a good solution to handle asynchronous providers elegantly, which is not covered here.
Comment 17 Mickael Istria CLA 2019-11-18 04:28:55 EST
Tentative for RC1.
We'll ask PMC approval for this one.
Comment 18 Mickael Istria CLA 2019-11-28 06:43:55 EST
On Gerrit, Noopur identified a (rare yet existing) error. Trying to fix it (without full guarantee of the fix being valid) has led me to some non-trivial refactoring of the AsyncCompletionProposalPopup in JFace.
So given the importance of that change, I think it's better to postpone to early 4.15.
Comment 19 Mickael Istria CLA 2019-12-16 16:03:07 EST
Created attachment 281252 [details]
Video demo

Here is a video demo I've built to showcase the feature, initially for colleagues, but I think it can be of more general interest and be more valuable if shared here as well.
Comment 20 Lars Vogel CLA 2019-12-16 16:10:27 EST
(In reply to Mickael Istria from comment #19)
> Created attachment 281252 [details]
> Video demo
> 
> Here is a video demo I've built to showcase the feature, initially for
> colleagues, but I think it can be of more general interest and be more
> valuable if shared here as well.

Cool, thanks for working on this.
Comment 22 Eclipse Genie CLA 2020-01-07 05:58:54 EST
New Gerrit change created: https://git.eclipse.org/r/155384
Comment 24 Noopur Gupta CLA 2020-01-07 11:18:43 EST
(In reply to Eclipse Genie from comment #23)
> Gerrit change https://git.eclipse.org/r/155384 was merged to [master].
> Commit:
> http://git.eclipse.org/c/platform/eclipse.platform.common.git/commit/?id=1ab76c426e6d97fa9070e50aac1a7b89f2571699
Released the F1 help documentation. Thanks, Mickael.
Comment 25 Noopur Gupta CLA 2020-01-07 11:21:58 EST
Mickael, please add the N&N entry for this.
Comment 26 Lars Vogel CLA 2020-01-07 11:42:02 EST
Thanks Mickael, if this works fine, this will be most important development done for Eclipse IMHO in the last years!!!!
Comment 27 Mickael Istria CLA 2020-01-07 12:46:12 EST
Interested parties should immediately enable the option in the preferences, as documented in https://www.eclipse.org/eclipse/news/4.15/jdt.php#non-blocking-completion and start using it constantly and report any bug or annoyance.
Then, when there are enough testers the list of bugs/annoyance is empty, we can consider flipping the default value.
Comment 28 Julian Honnen CLA 2020-01-08 07:41:40 EST
I'm getting the following NPE with async content assist:

Caused by: java.lang.NullPointerException
	at org.eclipse.jface.text.contentassist.CompletionProposalPopup.completeCommonPrefix(CompletionProposalPopup.java:1676)
	at org.eclipse.jface.text.contentassist.AsyncCompletionProposalPopup.lambda$5(AsyncCompletionProposalPopup.java:289)
	at org.eclipse.jface.text.contentassist.AsyncCompletionProposalPopup.computeAndPopulateProposals(AsyncCompletionProposalPopup.java:213)
	at org.eclipse.jface.text.contentassist.AsyncCompletionProposalPopup.incrementalComplete(AsyncCompletionProposalPopup.java:287)
	at org.eclipse.jface.text.contentassist.ContentAssistant.showPossibleCompletions(ContentAssistant.java:1824)


Cycling around then shows the correct proposals. Exception occurs even in simple examples: 

public class TEST {
  public void test(RuntimeException exception) {
    ex|
  }
}


Probably as an aftereffect I sporadically get
java.lang.IndexOutOfBoundsException: Index 0 out of bounds for length 0
	at java.base/jdk.internal.util.Preconditions.outOfBounds(Preconditions.java:64)
	at java.base/jdk.internal.util.Preconditions.outOfBoundsCheckIndex(Preconditions.java:70)
	at java.base/jdk.internal.util.Preconditions.checkIndex(Preconditions.java:248)
	at java.base/java.util.Objects.checkIndex(Objects.java:373)
	at java.base/java.util.ArrayList.get(ArrayList.java:425)
	at org.eclipse.jface.text.contentassist.CompletionProposalPopup.selectProposal(CompletionProposalPopup.java:1432)
	at org.eclipse.jface.text.contentassist.CompletionProposalPopup.access$5(CompletionProposalPopup.java:1421)


Version: 2020-03 (4.15)
Build id: I20200107-0600
Comment 29 Mickael Istria CLA 2020-01-08 07:55:18 EST
(In reply to Julian Honnen from comment #28)
> I'm getting the following NPE with async content assist:
> 
> Caused by: java.lang.NullPointerException
> 	at
> org.eclipse.jface.text.contentassist.CompletionProposalPopup.
> completeCommonPrefix(CompletionProposalPopup.java:1676)
> 	at
> org.eclipse.jface.text.contentassist.AsyncCompletionProposalPopup.
> lambda$5(AsyncCompletionProposalPopup.java:289)
> 	at
> org.eclipse.jface.text.contentassist.AsyncCompletionProposalPopup.
> computeAndPopulateProposals(AsyncCompletionProposalPopup.java:213)
> 	at
> org.eclipse.jface.text.contentassist.AsyncCompletionProposalPopup.
> incrementalComplete(AsyncCompletionProposalPopup.java:287)
> 	at
> org.eclipse.jface.text.contentassist.ContentAssistant.
> showPossibleCompletions(ContentAssistant.java:1824)

When the "insert common prefix automatically is on", I can reproduce this issue.
Can you please create a new ticket and mark it as a dependency of this one?

> Probably as an aftereffect I sporadically get
> java.lang.IndexOutOfBoundsException: Index 0 out of bounds for length 0
> 	at
> java.base/jdk.internal.util.Preconditions.outOfBounds(Preconditions.java:64)
> 	at
> java.base/jdk.internal.util.Preconditions.
> outOfBoundsCheckIndex(Preconditions.java:70)
> 	at
> java.base/jdk.internal.util.Preconditions.checkIndex(Preconditions.java:248)
> 	at java.base/java.util.Objects.checkIndex(Objects.java:373)
> 	at java.base/java.util.ArrayList.get(ArrayList.java:425)
> 	at
> org.eclipse.jface.text.contentassist.CompletionProposalPopup.
> selectProposal(CompletionProposalPopup.java:1432)
> 	at
> org.eclipse.jface.text.contentassist.CompletionProposalPopup.
> access$5(CompletionProposalPopup.java:1421)

I'm not sure it's related, I think this is more like a synchronization issue (list becomes empty when a method asks for its 1st element). I didn't reproduce it so far.
Comment 30 Pierre-Yves Bigourdan CLA 2020-01-20 04:47:16 EST
Created attachment 281547 [details]
Mylyn warning

I can't seem to enable this feature, there are warnings about Mylyn contributions (see attachment). I'm using the "Eclipse IDE for Java Developers" package, updated to 2020-03 M1.
Comment 31 Mickael Istria CLA 2020-01-20 04:48:47 EST
(In reply to Pierre-Yves B. from comment #30)
> Created attachment 281547 [details]
> Mylyn warning
> 
> I can't seem to enable this feature, there are warnings about Mylyn
> contributions (see attachment). I'm using the "Eclipse IDE for Java
> Developers" package, updated to 2020-03 M1.

This needs to be reported and fixed in Mylyn.
Comment 32 Mickael Istria CLA 2020-01-21 03:30:57 EST
(In reply to Mickael Istria from comment #31)
> This needs to be reported and fixed in Mylyn.

I opened bug 559357