Skip to main content
aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDawid Pakuła2018-05-19 14:32:33 -0400
committerDawid Pakuła2018-05-22 06:46:34 -0400
commit30061a13a03c470c959f108a39b9d4f9d4ad01c0 (patch)
treee6f0c8f5fc1d43a2816e5ab577dc0e223472a0b9 /org.eclipse.jface.text/src
parent8914d96dd8db9bf3ad4a748c5ffc2f536596fc55 (diff)
downloadeclipse.platform.text-30061a13a03c470c959f108a39b9d4f9d4ad01c0.tar.gz
eclipse.platform.text-30061a13a03c470c959f108a39b9d4f9d4ad01c0.tar.xz
eclipse.platform.text-30061a13a03c470c959f108a39b9d4f9d4ad01c0.zip
Bug 534395 - [content assist] Prefix autocompletion not work in async mode
Change-Id: I967d74001e8a07295946b43e41e99167aa1760c2 Signed-off-by: Dawid Pakuła <zulus@w3des.net>
Diffstat (limited to 'org.eclipse.jface.text/src')
-rw-r--r--org.eclipse.jface.text/src/org/eclipse/jface/text/contentassist/AsyncCompletionProposalPopup.java170
-rw-r--r--org.eclipse.jface.text/src/org/eclipse/jface/text/contentassist/CompletionProposalPopup.java10
2 files changed, 117 insertions, 63 deletions
diff --git a/org.eclipse.jface.text/src/org/eclipse/jface/text/contentassist/AsyncCompletionProposalPopup.java b/org.eclipse.jface.text/src/org/eclipse/jface/text/contentassist/AsyncCompletionProposalPopup.java
index b1a02d8a1..26f260d4a 100644
--- a/org.eclipse.jface.text/src/org/eclipse/jface/text/contentassist/AsyncCompletionProposalPopup.java
+++ b/org.eclipse.jface.text/src/org/eclipse/jface/text/contentassist/AsyncCompletionProposalPopup.java
@@ -21,6 +21,7 @@ import java.util.concurrent.ExecutionException;
import java.util.concurrent.Future;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;
+import java.util.function.Consumer;
import org.eclipse.osgi.util.NLS;
@@ -148,79 +149,132 @@ class AsyncCompletionProposalPopup extends CompletionProposalPopup {
fFilterOffset= fInvocationOffset;
fLastCompletionOffset= fFilterOffset;
// start invocation of processors as Futures, and make them populate the proposals upon completion
- List<ICompletionProposal> computedProposals = Collections.synchronizedList(new ArrayList<>());
fFutures= buildCompletionFuturesOrJobs(fInvocationOffset);
- List<CompletableFuture<Void>> populateFutures = new ArrayList<>(fFutures.size());
- for (CompletableFuture<List<ICompletionProposal>> future : fFutures) {
- populateFutures.add(future.thenAccept(proposals ->
- computedProposals.addAll(proposals)
- ));
- }
+ runFutures(fInvocationOffset, null, true, autoActivated, true);
+ } else {
+ fLastCompletionOffset= fFilterOffset;
+ handleRepeatedInvocation();
+ }
- long requestBeginningTimestamp = System.currentTimeMillis();
- long stillRemainingThreeshold = MAX_WAIT_IN_MS;
- for (CompletableFuture<?> future : populateFutures) {
- try {
- future.get(stillRemainingThreeshold, TimeUnit.MILLISECONDS);
- } catch (TimeoutException | ExecutionException | InterruptedException ex) {
- // future failed or took more time than we want to wait
- }
- stillRemainingThreeshold = MAX_WAIT_IN_MS - (System.currentTimeMillis() - requestBeginningTimestamp);
- if (stillRemainingThreeshold < 0) {
- // we already spent too much time (more than MAX_WAIT_IN_MS), stop waiting.
- break;
- }
+ return getErrorMessage();
+ }
+
+ @Override
+ void handleRepeatedInvocation() {
+ cancelFutures();
+ fFutures= buildCompletionFuturesOrJobs(fInvocationOffset);
+ runFutures(fInvocationOffset, null, false, false, false);
+ }
+
+ private List<ICompletionProposal> runFutures(int offset, Consumer<List<ICompletionProposal>> callback, boolean createSelector, boolean autoActivated, boolean autoInsert) {
+ List<ICompletionProposal> computedProposals= Collections.synchronizedList(new ArrayList<>());
+ List<CompletableFuture<Void>> populateFutures= new ArrayList<>(fFutures.size());
+ for (CompletableFuture<List<ICompletionProposal>> future : fFutures) {
+ populateFutures.add(future.thenAccept(proposals -> computedProposals.addAll(proposals)));
+ }
+
+ long requestBeginningTimestamp= System.currentTimeMillis();
+ long stillRemainingThreeshold= MAX_WAIT_IN_MS;
+ for (CompletableFuture<?> future : populateFutures) {
+ try {
+ future.get(stillRemainingThreeshold, TimeUnit.MILLISECONDS);
+ } catch (TimeoutException | ExecutionException | InterruptedException ex) {
+ // future failed or took more time than we want to wait
}
- fComputedProposals = computedProposals;
- if (stillRemainingThreeshold > 0) { // everything ready in time, go synchronous
- int count= computedProposals.size();
- if (count == 0 && hideWhenNoProposals(autoActivated))
- return null;
-
- if (count == 1 && !autoActivated && canAutoInsert(computedProposals.get(0))) {
- insertProposal(computedProposals.get(0), (char) 0, 0, fInvocationOffset);
- hide();
- } else {
+ stillRemainingThreeshold= MAX_WAIT_IN_MS - (System.currentTimeMillis() - requestBeginningTimestamp);
+ if (stillRemainingThreeshold < 0) {
+ // we already spent too much time (more than MAX_WAIT_IN_MS), stop waiting.
+ break;
+ }
+ }
+ fComputedProposals= computedProposals;
+ if (stillRemainingThreeshold > 0) { // everything ready in time, go synchronous
+ int count= computedProposals.size();
+ if (count == 0 && hideWhenNoProposals(autoActivated))
+ return computedProposals;
+
+ if (autoInsert && count == 1 && !autoActivated && canAutoInsert(computedProposals.get(0))) {
+ insertProposal(computedProposals.get(0), (char) 0, 0, offset);
+ hide();
+ } else {
+ if (createSelector) {
createProposalSelector();
+ }
+ if (callback != null) {
+ callback.accept(computedProposals);
+ } else {
setProposals(computedProposals, false);
displayProposals();
}
- } else { // processors took too much time, go asynchronous
+ }
+ } else { // processors took too much time, go asynchronous
+ if (createSelector) {
createProposalSelector();
- ComputingProposal computingProposal= new ComputingProposal(fInvocationOffset, fFutures.size());
- computedProposals.add(0, computingProposal);
- fComputedProposals = computedProposals;
- setProposals(fComputedProposals, false);
- Set<CompletableFuture<Void>> remaining = Collections.synchronizedSet(new HashSet<>(populateFutures));
- for (CompletableFuture<Void> populateFuture : populateFutures) {
- populateFuture.thenRun(() -> {
- remaining.removeIf(CompletableFuture::isDone);
- computingProposal.setRemaining(remaining.size());
- if (remaining.isEmpty()) {
- computedProposals.remove(computingProposal);
- }
- List<ICompletionProposal> newProposals = new ArrayList<>(computedProposals);
- fComputedProposals = newProposals;
- Display.getDefault().asyncExec(() -> {
- if (!autoActivated && remaining.isEmpty() && newProposals.size() == 1 && canAutoInsert(newProposals.get(0))) {
- if (Helper.okToUse(fProposalShell)) {
- insertProposal(newProposals.get(0), (char) 0, 0, fInvocationOffset);
- hide();
- }
- return;
+ }
+ ComputingProposal computingProposal= new ComputingProposal(offset, fFutures.size());
+ computedProposals.add(0, computingProposal);
+ setProposals(fComputedProposals, false);
+ Set<CompletableFuture<Void>> remaining= Collections.synchronizedSet(new HashSet<>(populateFutures));
+ for (CompletableFuture<Void> populateFuture : populateFutures) {
+ populateFuture.thenRun(() -> {
+ remaining.removeIf(CompletableFuture::isDone);
+ computingProposal.setRemaining(remaining.size());
+ if (remaining.isEmpty()) {
+ computedProposals.remove(computingProposal);
+ }
+ List<ICompletionProposal> newProposals= new ArrayList<>(computedProposals);
+ fComputedProposals= newProposals;
+ Display.getDefault().asyncExec(() -> {
+ if (autoInsert && !autoActivated && remaining.isEmpty() && newProposals.size() == 1 && canAutoInsert(newProposals.get(0))) {
+ if (Helper.okToUse(fProposalShell)) {
+ insertProposal(newProposals.get(0), (char) 0, 0, offset);
+ hide();
}
+ return;
+ }
+ if (remaining.isEmpty() && callback != null) {
+ callback.accept(newProposals);
+ } else {
setProposals(newProposals, false);
displayProposals();
- });
+ }
});
- }
- displayProposals();
+ });
}
- } else {
- fLastCompletionOffset= fFilterOffset;
- handleRepeatedInvocation();
+ displayProposals();
+ }
+ return computedProposals;
+ }
+
+ @Override
+ public String incrementalComplete() {
+ cancelFutures();
+ if (Helper.okToUse(fProposalShell) && fFilteredProposals != null) {
+ return super.incrementalComplete();
}
+ final Control control= fContentAssistSubjectControlAdapter.getControl();
+
+ if (fKeyListener == null)
+ fKeyListener= new ProposalSelectionListener();
+
+ if (!Helper.okToUse(fProposalShell) && !control.isDisposed())
+ fContentAssistSubjectControlAdapter.addKeyListener(fKeyListener);
+ fInvocationOffset= fContentAssistSubjectControlAdapter.getSelectedRange().x;
+ fFilterOffset= fInvocationOffset;
+ fLastCompletionOffset= fFilterOffset;
+
+ fFutures= buildCompletionFuturesOrJobs(fInvocationOffset);
+ fFilteredProposals= runFutures(fInvocationOffset, (List<ICompletionProposal> proposals) -> {
+ ensureDocumentListenerInstalled();
+ if (proposals.size() > 0 && completeCommonPrefix()) {
+ hide();
+ } else {
+ fFilteredProposals= proposals;
+ setProposals(proposals, false);
+ displayProposals();
+ }
+ }, true, false, true);
return getErrorMessage();
}
diff --git a/org.eclipse.jface.text/src/org/eclipse/jface/text/contentassist/CompletionProposalPopup.java b/org.eclipse.jface.text/src/org/eclipse/jface/text/contentassist/CompletionProposalPopup.java
index 3161ed5fe..9951e6f29 100644
--- a/org.eclipse.jface.text/src/org/eclipse/jface/text/contentassist/CompletionProposalPopup.java
+++ b/org.eclipse.jface.text/src/org/eclipse/jface/text/contentassist/CompletionProposalPopup.java
@@ -290,7 +290,7 @@ class CompletionProposalPopup implements IContentAssistListener {
/** Listener filling the document event queue. */
private IDocumentListener fDocumentListener;
/** The filter list of proposals. */
- private List<ICompletionProposal> fFilteredProposals;
+ List<ICompletionProposal> fFilteredProposals;
/** The computed list of proposals. */
List<ICompletionProposal> fComputedProposals;
/** The offset for which the proposals have been computed. */
@@ -1267,7 +1267,7 @@ class CompletionProposalPopup implements IContentAssistListener {
*
* @since 3.2
*/
- private void ensureDocumentListenerInstalled() {
+ void ensureDocumentListenerInstalled() {
if (fDocumentListener == null) {
fDocumentListener= new IDocumentListener() {
@Override
@@ -1619,7 +1619,7 @@ class CompletionProposalPopup implements IContentAssistListener {
if (count == 1 && canAutoInsert(fFilteredProposals.get(0))) {
insertProposal(fFilteredProposals.get(0), (char) 0, 0, fInvocationOffset);
- hide();
+ hide();
} else {
ensureDocumentListenerInstalled();
if (count > 0 && completeCommonPrefix())
@@ -1630,8 +1630,8 @@ class CompletionProposalPopup implements IContentAssistListener {
setProposals(fComputedProposals, false);
displayProposals();
}
+ }
}
- }
});
}
return getErrorMessage();
@@ -1647,7 +1647,7 @@ class CompletionProposalPopup implements IContentAssistListener {
* selector can be closed, <code>false</code> otherwise
* @since 3.0
*/
- private boolean completeCommonPrefix() {
+ boolean completeCommonPrefix() {
// 0: insert single proposals
if (fFilteredProposals.size() == 1) {

Back to the top