Skip to main content
aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--org.eclipse.jface.text.tests/META-INF/MANIFEST.MF2
-rw-r--r--org.eclipse.jface.text.tests/pom.xml2
-rw-r--r--org.eclipse.jface.text.tests/src/org/eclipse/jface/text/tests/contentassist/AsyncContentAssistTest.java58
-rw-r--r--org.eclipse.jface.text.tests/src/org/eclipse/jface/text/tests/contentassist/BarContentAssistProcessor.java20
-rw-r--r--org.eclipse.jface.text/META-INF/MANIFEST.MF2
-rw-r--r--org.eclipse.jface.text/src/org/eclipse/jface/internal/text/link/contentassist/ContentAssistant2.java67
-rw-r--r--org.eclipse.jface.text/src/org/eclipse/jface/text/contentassist/CompletionProposalPopup.java6
-rw-r--r--org.eclipse.jface.text/src/org/eclipse/jface/text/contentassist/ContentAssistSubjectControlAdapter.java39
-rw-r--r--org.eclipse.jface.text/src/org/eclipse/jface/text/contentassist/ContentAssistant.java157
-rw-r--r--org.eclipse.jface.text/src/org/eclipse/jface/text/contentassist/IContentAssistProcessor.java32
-rw-r--r--org.eclipse.jface.text/src/org/eclipse/jface/text/contentassist/IContentAssistProcessorExtension.java141
-rw-r--r--org.eclipse.ui.genericeditor/src/org/eclipse/ui/internal/genericeditor/CompositeContentAssistProcessor.java82
12 files changed, 338 insertions, 270 deletions
diff --git a/org.eclipse.jface.text.tests/META-INF/MANIFEST.MF b/org.eclipse.jface.text.tests/META-INF/MANIFEST.MF
index 546e86c0e57..7181b7ed885 100644
--- a/org.eclipse.jface.text.tests/META-INF/MANIFEST.MF
+++ b/org.eclipse.jface.text.tests/META-INF/MANIFEST.MF
@@ -2,7 +2,7 @@ Manifest-Version: 1.0
Bundle-ManifestVersion: 2
Bundle-Name: %Plugin.name
Bundle-SymbolicName: org.eclipse.jface.text.tests
-Bundle-Version: 3.11.1300.qualifier
+Bundle-Version: 3.12.0.qualifier
Bundle-Vendor: %Plugin.providerName
Bundle-Localization: plugin
Export-Package:
diff --git a/org.eclipse.jface.text.tests/pom.xml b/org.eclipse.jface.text.tests/pom.xml
index 5e278417a10..2b5fff07e24 100644
--- a/org.eclipse.jface.text.tests/pom.xml
+++ b/org.eclipse.jface.text.tests/pom.xml
@@ -19,7 +19,7 @@
</parent>
<groupId>org.eclipse.jface</groupId>
<artifactId>org.eclipse.jface.text.tests</artifactId>
- <version>3.11.1300-SNAPSHOT</version>
+ <version>3.12.0-SNAPSHOT</version>
<packaging>eclipse-test-plugin</packaging>
<properties>
<testSuite>${project.artifactId}</testSuite>
diff --git a/org.eclipse.jface.text.tests/src/org/eclipse/jface/text/tests/contentassist/AsyncContentAssistTest.java b/org.eclipse.jface.text.tests/src/org/eclipse/jface/text/tests/contentassist/AsyncContentAssistTest.java
index 5976c1b4290..fde1c44024d 100644
--- a/org.eclipse.jface.text.tests/src/org/eclipse/jface/text/tests/contentassist/AsyncContentAssistTest.java
+++ b/org.eclipse.jface.text.tests/src/org/eclipse/jface/text/tests/contentassist/AsyncContentAssistTest.java
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2019 Red Hat Inc. and others.
+ * Copyright (c) 2019, 2021 Red Hat Inc. and others.
*
* This program and the accompanying materials
* are made available under the terms of the Eclipse Public License 2.0
@@ -10,6 +10,7 @@
*
* Contributors:
* - Mickael Istria (Red Hat Inc.)
+ * Christoph Läubrich - add additional test
*******************************************************************************/
package org.eclipse.jface.text.tests.contentassist;
@@ -28,7 +29,9 @@ import org.junit.Test;
import org.eclipse.swt.SWT;
import org.eclipse.swt.layout.FillLayout;
import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Control;
import org.eclipse.swt.widgets.Display;
+import org.eclipse.swt.widgets.Event;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.swt.widgets.Table;
import org.eclipse.swt.widgets.TableItem;
@@ -127,6 +130,59 @@ public class AsyncContentAssistTest {
}.waitForCondition(display, 2000));
}
+ @Test
+ public void testCompleteActivationChar() throws InterruptedException {
+ Shell shell= new Shell();
+ shell.setLayout(new FillLayout());
+ shell.setSize(500, 300);
+ SourceViewer viewer= new SourceViewer(shell, null, SWT.NONE);
+ Document document= new Document("b");
+ viewer.setDocument(document);
+ viewer.setSelectedRange(1, 0);
+ ContentAssistant contentAssistant= new ContentAssistant(true);
+ BarContentAssistProcessor processor= new BarContentAssistProcessor();
+ processor.setCompletionProposalAutoActivationChar('b');
+ contentAssistant.addContentAssistProcessor(processor, IDocument.DEFAULT_CONTENT_TYPE);
+ contentAssistant.enablePrefixCompletion(true);
+ contentAssistant.enableAutoActivation(true);
+ contentAssistant.setAutoActivationDelay(0);
+ contentAssistant.install(viewer);
+ shell.open();
+ Display display= shell.getDisplay();
+ final Set<Shell> beforeShells= Arrays.stream(display.getShells()).filter(Shell::isVisible).collect(Collectors.toSet());
+ Event keyEvent= new Event();
+ Control control= viewer.getTextWidget();
+ display.timerExec(200, new Runnable() {
+ @Override
+ public void run() {
+ control.forceFocus();
+ keyEvent.widget= control;
+ keyEvent.type= SWT.KeyDown;
+ keyEvent.character= 'b';
+ keyEvent.keyCode= 'b';
+ control.getDisplay().post(keyEvent);
+ keyEvent.type= SWT.KeyUp;
+ control.getDisplay().post(keyEvent);
+ DisplayHelper.driveEventQueue(control.getDisplay());
+ if (!document.get().startsWith("bb")) {
+ display.timerExec(200, this);
+ }
+ }
+ });
+ assertTrue("Completion item not shown", new DisplayHelper() {
+ @Override
+ protected boolean condition() {
+ Set<Shell> newShells= Arrays.stream(display.getShells()).filter(Shell::isVisible).collect(Collectors.toSet());
+ newShells.removeAll(beforeShells);
+ if (!newShells.isEmpty()) {
+ Table completionTable= findCompletionSelectionControl(newShells.iterator().next());
+ return Arrays.stream(completionTable.getItems()).map(TableItem::getText).anyMatch(item -> item.contains(BarContentAssistProcessor.PROPOSAL.substring(document.getLength())));
+ }
+ return false;
+ }
+ }.waitForCondition(display, 4000));
+ }
+
private static Table findCompletionSelectionControl(Widget control) {
if (control instanceof Table) {
return (Table)control;
diff --git a/org.eclipse.jface.text.tests/src/org/eclipse/jface/text/tests/contentassist/BarContentAssistProcessor.java b/org.eclipse.jface.text.tests/src/org/eclipse/jface/text/tests/contentassist/BarContentAssistProcessor.java
index 0cced65d683..fe6a3d66903 100644
--- a/org.eclipse.jface.text.tests/src/org/eclipse/jface/text/tests/contentassist/BarContentAssistProcessor.java
+++ b/org.eclipse.jface.text.tests/src/org/eclipse/jface/text/tests/contentassist/BarContentAssistProcessor.java
@@ -25,13 +25,13 @@ import org.eclipse.jface.text.IRegion;
import org.eclipse.jface.text.ITextViewer;
import org.eclipse.jface.text.contentassist.CompletionProposal;
import org.eclipse.jface.text.contentassist.ICompletionProposal;
-import org.eclipse.jface.text.contentassist.IContentAssistProcessor;
+import org.eclipse.jface.text.contentassist.IContentAssistProcessorExtension;
import org.eclipse.jface.text.contentassist.IContextInformation;
import org.eclipse.jface.text.contentassist.IContextInformationExtension;
import org.eclipse.jface.text.contentassist.IContextInformationValidator;
-public class BarContentAssistProcessor implements IContentAssistProcessor {
+public class BarContentAssistProcessor implements IContentAssistProcessorExtension {
public static final String PROPOSAL= "bars are good for a beer.";
@@ -107,6 +107,8 @@ public class BarContentAssistProcessor implements IContentAssistProcessor {
private final String completeString;
+ private char activationChar;
+
public BarContentAssistProcessor() {
this(PROPOSAL);
}
@@ -178,4 +180,18 @@ public class BarContentAssistProcessor implements IContentAssistProcessor {
return null;
}
+ @Override
+ public boolean isCompletionProposalAutoActivation(char c, ITextViewer viewer, int offset) {
+ return activationChar == c;
+ }
+
+ @Override
+ public boolean isContextInformationAutoActivation(char c, ITextViewer viewer, int offset) {
+ return false;
+ }
+
+ public void setCompletionProposalAutoActivationChar(char c) {
+ activationChar= c;
+ }
+
}
diff --git a/org.eclipse.jface.text/META-INF/MANIFEST.MF b/org.eclipse.jface.text/META-INF/MANIFEST.MF
index 082fb4f409f..5ef31a0ea50 100644
--- a/org.eclipse.jface.text/META-INF/MANIFEST.MF
+++ b/org.eclipse.jface.text/META-INF/MANIFEST.MF
@@ -2,7 +2,7 @@ Manifest-Version: 1.0
Bundle-ManifestVersion: 2
Bundle-Name: %pluginName
Bundle-SymbolicName: org.eclipse.jface.text
-Bundle-Version: 3.16.600.qualifier
+Bundle-Version: 3.17.0.qualifier
Bundle-Vendor: %providerName
Bundle-Localization: plugin
Export-Package:
diff --git a/org.eclipse.jface.text/src/org/eclipse/jface/internal/text/link/contentassist/ContentAssistant2.java b/org.eclipse.jface.text/src/org/eclipse/jface/internal/text/link/contentassist/ContentAssistant2.java
index 452455d9b22..7a6042143dc 100644
--- a/org.eclipse.jface.text/src/org/eclipse/jface/internal/text/link/contentassist/ContentAssistant2.java
+++ b/org.eclipse.jface.text/src/org/eclipse/jface/internal/text/link/contentassist/ContentAssistant2.java
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2000, 2018 IBM Corporation and others.
+ * Copyright (c) 2000, 2021 IBM Corporation and others.
*
* This program and the accompanying materials
* are made available under the terms of the Eclipse Public License 2.0
@@ -10,6 +10,7 @@
*
* Contributors:
* IBM Corporation - initial API and implementation
+ * Christoph Läubrich - Bug 508821 - [Content assist] More flexible API in IContentAssistProcessor to decide whether to auto-activate or not
*******************************************************************************/
package org.eclipse.jface.internal.text.link.contentassist;
@@ -63,6 +64,7 @@ import org.eclipse.jface.text.contentassist.CompletionProposal;
import org.eclipse.jface.text.contentassist.ICompletionProposal;
import org.eclipse.jface.text.contentassist.ICompletionProposalExtension6;
import org.eclipse.jface.text.contentassist.IContentAssistProcessor;
+import org.eclipse.jface.text.contentassist.IContentAssistProcessorExtension;
import org.eclipse.jface.text.contentassist.IContentAssistant;
import org.eclipse.jface.text.contentassist.IContentAssistantExtension;
import org.eclipse.jface.text.contentassist.IContextInformation;
@@ -261,17 +263,6 @@ public class ContentAssistant2 implements IContentAssistant, IContentAssistantEx
threadToStop.interrupt();
}
- private boolean contains(char[] characters, char character) {
- if (characters != null) {
- for (char c : characters) {
- if (character == c) {
- return true;
- }
- }
- }
- return false;
- }
-
@Override
public void verifyKey(VerifyEvent e) {
// Only act on typed characters and ignore modifier-only events
@@ -281,15 +272,23 @@ public class ContentAssistant2 implements IContentAssistant, IContentAssistantEx
if (e.character != 0 && (e.stateMask == SWT.ALT))
return;
+
+
int showStyle;
int pos= fViewer.getSelectedRange().x;
- char[] activation= getCompletionProposalAutoActivationCharacters(fViewer, pos);
+ IContentAssistProcessorExtension p= getProcessor(fViewer, pos);
+ if (p == null) {
+ stop();
+ return;
+ }
+
+
+
- if (contains(activation, e.character) && !fProposalPopup.isActive())
+ if (p.isCompletionProposalAutoActivation(e.character, fViewer, pos) && !fProposalPopup.isActive())
showStyle= SHOW_PROPOSALS;
else {
- activation= getContextInformationAutoActivationCharacters(fViewer, pos);
- if (contains(activation, e.character) && !fContextInfoPopup.isActive())
+ if (p.isContextInformationAutoActivation(e.character, fViewer, pos) && !fContextInfoPopup.isActive())
showStyle= SHOW_CONTEXT_INFO;
else {
if (fThread != null && fThread.isAlive())
@@ -1322,10 +1321,10 @@ public class ContentAssistant2 implements IContentAssistant, IContentAssistantEx
* @param offset a offset within the document
* @return a content-assist processor or <code>null</code> if none exists
*/
- private IContentAssistProcessor getProcessor(ITextViewer viewer, int offset) {
+ private IContentAssistProcessorExtension getProcessor(ITextViewer viewer, int offset) {
try {
String type= TextUtilities.getContentType(viewer.getDocument(), getDocumentPartitioning(), offset, true);
- return getContentAssistProcessor(type);
+ return IContentAssistProcessorExtension.adapt(getContentAssistProcessor(type));
} catch (BadLocationException x) {
}
return null;
@@ -1413,38 +1412,6 @@ public class ContentAssistant2 implements IContentAssistant, IContentAssistantEx
return null;
}
- /**
- * Returns the characters which when typed by the user should automatically
- * initiate proposing completions. The position is used to determine the
- * appropriate content assist processor to invoke.
- *
- * @param textViewer the text viewer
- * @param offset a document offset
- * @return the auto activation characters
- *
- * @see IContentAssistProcessor#getCompletionProposalAutoActivationCharacters
- */
- private char[] getCompletionProposalAutoActivationCharacters(ITextViewer textViewer, int offset) {
- IContentAssistProcessor p= getProcessor(textViewer, offset);
- return p != null ? p.getCompletionProposalAutoActivationCharacters() : null;
- }
-
- /**
- * Returns the characters which when typed by the user should automatically
- * initiate the presentation of context information. The position is used
- * to determine the appropriate content assist processor to invoke.
- *
- * @param textViewer the text viewer
- * @param offset a document offset
- * @return the auto activation characters
- *
- * @see IContentAssistProcessor#getContextInformationAutoActivationCharacters
- */
- private char[] getContextInformationAutoActivationCharacters(ITextViewer textViewer, int offset) {
- IContentAssistProcessor p= getProcessor(textViewer, offset);
- return p != null ? p.getContextInformationAutoActivationCharacters() : null;
- }
-
@Override
public boolean requestWidgetToken(IWidgetTokenOwner owner) {
hidePossibleCompletions();
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 128c97ae5d6..dcadb6e23f6 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
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2000, 2018 IBM Corporation and others.
+ * Copyright (c) 2000, 2021 IBM Corporation and others.
*
* This program and the accompanying materials
* are made available under the terms of the Eclipse Public License 2.0
@@ -15,6 +15,7 @@
* Terry Parker, tparker@google.com - Protect against poorly behaved completion proposers - http://bugs.eclipse.org/429925
* Lars Vogel <Lars.Vogel@vogella.com> - Bug 493649
* Mickael Istria (Red Hat Inc.) - [251156] Allow multiple contentAssitProviders internally & inheritance
+ * Christoph Läubrich - Bug 508821 - [Content assist] More flexible API in IContentAssistProcessor to decide whether to auto-activate or not
*******************************************************************************/
package org.eclipse.jface.text.contentassist;
@@ -99,6 +100,7 @@ import org.eclipse.jface.text.IRewriteTarget;
import org.eclipse.jface.text.ITextViewer;
import org.eclipse.jface.text.ITextViewerExtension;
import org.eclipse.jface.text.TextUtilities;
+import org.eclipse.jface.text.contentassist.ContentAssistant.TriggerType;
/**
@@ -376,7 +378,7 @@ class CompletionProposalPopup implements IContentAssistListener {
if (fContentAssistant.isAutoActivation() && offset > 0 && event != null) {
try {
char charBeforeOffset= event.getDocument().getChar(offset - 1);
- if (fContentAssistant.isAutoActivationTriggerChar(charBeforeOffset)) {
+ if (fContentAssistant.getAutoActivationTriggerType(charBeforeOffset) != TriggerType.NONE) {
fContentAssistant.fireSessionBeginEvent(true);
showProposals(true);
}
diff --git a/org.eclipse.jface.text/src/org/eclipse/jface/text/contentassist/ContentAssistSubjectControlAdapter.java b/org.eclipse.jface.text/src/org/eclipse/jface/text/contentassist/ContentAssistSubjectControlAdapter.java
index e1f6e72de5a..bbec6b22266 100644
--- a/org.eclipse.jface.text/src/org/eclipse/jface/text/contentassist/ContentAssistSubjectControlAdapter.java
+++ b/org.eclipse.jface.text/src/org/eclipse/jface/text/contentassist/ContentAssistSubjectControlAdapter.java
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2000, 2017 IBM Corporation and others.
+ * Copyright (c) 2000, 2021 IBM Corporation and others.
*
* This program and the accompanying materials
* are made available under the terms of the Eclipse Public License 2.0
@@ -12,11 +12,14 @@
* IBM Corporation - initial API and implementation
* Mickael Istria (Red Hat Inc.) - [251156] Allow multiple contentAssitProviders internally & inheritance
* Stephan Wahlbrink <sw@wahlbrink.eu> - Bug 512251 - Fix IllegalArgumentException in ContextInformationPopup
+ * Christoph Läubrich - Bug 508821 - [Content assist] More flexible API in IContentAssistProcessor to decide whether to auto-activate or not
*******************************************************************************/
package org.eclipse.jface.text.contentassist;
import static org.eclipse.jface.util.Util.isValid;
+import java.util.Set;
+
import org.eclipse.swt.custom.StyledText;
import org.eclipse.swt.custom.VerifyKeyListener;
import org.eclipse.swt.events.KeyListener;
@@ -241,38 +244,21 @@ class ContentAssistSubjectControlAdapter implements IContentAssistSubjectControl
return fContentAssistSubjectControl.supportsVerifyKeyListener();
return true;
}
+
/**
- * Returns the characters which when typed by the user should automatically
- * initiate proposing completions. The position is used to determine the
- * appropriate content assist processor to invoke.
+ * Returns the processors for the given offset
*
* @param contentAssistant the content assistant
* @param offset a document offset
- * @return the auto activation characters
+ * @return the processors set
* @see IContentAssistProcessor#getCompletionProposalAutoActivationCharacters()
*/
- public char[] getCompletionProposalAutoActivationCharacters(ContentAssistant contentAssistant, int offset) {
+ Set<IContentAssistProcessor> getContentAssistProcessors(ContentAssistant contentAssistant, int offset) {
if (fContentAssistSubjectControl != null)
- return contentAssistant.getCompletionProposalAutoActivationCharacters(fContentAssistSubjectControl, offset);
- return contentAssistant.getCompletionProposalAutoActivationCharacters(fViewer, offset);
+ return contentAssistant.getProcessors(fContentAssistSubjectControl, offset);
+ return contentAssistant.getProcessors(fViewer, offset);
}
- /**
- * Returns the characters which when typed by the user should automatically
- * initiate the presentation of context information. The position is used
- * to determine the appropriate content assist processor to invoke.
- *
- * @param contentAssistant the content assistant
- * @param offset a document offset
- * @return the auto activation characters
- *
- * @see IContentAssistProcessor#getContextInformationAutoActivationCharacters()
- */
- char[] getContextInformationAutoActivationCharacters(ContentAssistant contentAssistant, int offset) {
- if (fContentAssistSubjectControl != null)
- return contentAssistant.getContextInformationAutoActivationCharacters(fContentAssistSubjectControl, offset);
- return contentAssistant.getContextInformationAutoActivationCharacters(fViewer, offset);
- }
/**
* Creates and returns a completion proposal popup for the given content assistant.
@@ -347,7 +333,7 @@ class ContentAssistSubjectControlAdapter implements IContentAssistSubjectControl
public void installValidator(ContextFrame frame) {
if (fContentAssistSubjectControl != null) {
if (frame.fValidator instanceof ISubjectControlContextInformationValidator)
- ((ISubjectControlContextInformationValidator)frame.fValidator).install(frame.fInformation, fContentAssistSubjectControl, frame.fOffset);
+ ((ISubjectControlContextInformationValidator) frame.fValidator).install(frame.fInformation, fContentAssistSubjectControl, frame.fOffset);
} else
frame.fValidator.install(frame.fInformation, fViewer, frame.fOffset);
}
@@ -360,7 +346,7 @@ class ContentAssistSubjectControlAdapter implements IContentAssistSubjectControl
public void installContextInformationPresenter(ContextFrame frame) {
if (fContentAssistSubjectControl != null) {
if (frame.fPresenter instanceof ISubjectControlContextInformationPresenter)
- ((ISubjectControlContextInformationPresenter)frame.fValidator).install(frame.fInformation, fContentAssistSubjectControl, frame.fBeginOffset);
+ ((ISubjectControlContextInformationPresenter) frame.fValidator).install(frame.fInformation, fContentAssistSubjectControl, frame.fBeginOffset);
} else
frame.fPresenter.install(frame.fInformation, fViewer, frame.fBeginOffset);
}
@@ -396,4 +382,5 @@ class ContentAssistSubjectControlAdapter implements IContentAssistSubjectControl
else
fViewer.getTextWidget().removeSelectionListener(selectionListener);
}
+
}
diff --git a/org.eclipse.jface.text/src/org/eclipse/jface/text/contentassist/ContentAssistant.java b/org.eclipse.jface.text/src/org/eclipse/jface/text/contentassist/ContentAssistant.java
index e88c8f03422..2f92d9c4906 100644
--- a/org.eclipse.jface.text/src/org/eclipse/jface/text/contentassist/ContentAssistant.java
+++ b/org.eclipse.jface.text/src/org/eclipse/jface/text/contentassist/ContentAssistant.java
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2000, 2018 IBM Corporation and others.
+ * Copyright (c) 2000, 2021 IBM Corporation and others.
*
* This program and the accompanying materials
* are made available under the terms of the Eclipse Public License 2.0
@@ -15,6 +15,7 @@
* Marcel Bruch, bruch@cs.tu-darmstadt.de - [content assist] Allow to re-sort proposals - https://bugs.eclipse.org/bugs/show_bug.cgi?id=350991
* John Glassmyer, jogl@google.com - catch Content Assist exceptions to protect navigation keys - http://bugs.eclipse.org/434901
* Mickael Istria (Red Hat Inc.) - [251156] Allow multiple contentAssitProviders internally & inheritance
+ * Christoph Läubrich - Bug 508821 - [Content assist] More flexible API in IContentAssistProcessor to decide whether to auto-activate or not
*******************************************************************************/
package org.eclipse.jface.text.contentassist;
@@ -22,7 +23,6 @@ import static org.eclipse.jface.util.Util.isValid;
import java.util.ArrayList;
import java.util.Arrays;
-import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.LinkedHashSet;
@@ -30,7 +30,6 @@ import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.Set;
-import java.util.function.Function;
import org.eclipse.swt.SWT;
import org.eclipse.swt.SWTError;
@@ -114,6 +113,10 @@ public class ContentAssistant implements IContentAssistant, IContentAssistantExt
*/
public static final String SELECT_PREVIOUS_PROPOSAL_COMMAND_ID= "org.eclipse.ui.edit.text.contentAssist.selectPreviousProposal"; //$NON-NLS-1$
+ enum TriggerType {
+ CONTEXT_INFORMATION,
+ COMPLETION_PROPOSAL, NONE;
+ }
/**
* A generic closer class used to monitor various interface events in order to determine whether
@@ -303,17 +306,6 @@ public class ContentAssistant implements IContentAssistant, IContentAssistantExt
threadToStop.interrupt();
}
- private boolean contains(char[] characters, char character) {
- if (characters != null) {
- for (char c : characters) {
- if (character == c) {
- return true;
- }
- }
- }
- return false;
- }
-
@Override
public void keyPressed(KeyEvent e) {
// Only act on typed characters and ignore modifier-only events
@@ -323,24 +315,20 @@ public class ContentAssistant implements IContentAssistant, IContentAssistantExt
if (e.character != 0 && (e.stateMask == SWT.ALT))
return;
+ TriggerType triggerType= getAutoActivationTriggerType(e.character);
+
// Only act on characters that are trigger candidates. This
// avoids computing the model selection on every keystroke
- if (!isAutoActivationTriggerChar(e.character)) {
+ if (triggerType == TriggerType.NONE) {
stop();
return;
}
int showStyle;
- int pos= fContentAssistSubjectControlAdapter.getSelectedRange().x;
- char[] activation;
-
- activation= fContentAssistSubjectControlAdapter.getCompletionProposalAutoActivationCharacters(ContentAssistant.this, pos);
-
- if (contains(activation, e.character) && !isProposalPopupActive())
+ if (triggerType == TriggerType.COMPLETION_PROPOSAL && !isProposalPopupActive())
showStyle= SHOW_PROPOSALS;
else {
- activation= fContentAssistSubjectControlAdapter.getContextInformationAutoActivationCharacters(ContentAssistant.this, pos);
- if (contains(activation, e.character) && !isContextInfoPopupActive())
+ if (triggerType == TriggerType.CONTEXT_INFORMATION && !isContextInfoPopupActive())
showStyle= SHOW_CONTEXT_INFO;
else {
stop();
@@ -1187,26 +1175,28 @@ public class ContentAssistant implements IContentAssistant, IContentAssistantExt
}
/**
+ * @param c the character to check
* @return whether the given char is an auto-activation trigger char
* @since 3.15
*/
- boolean isAutoActivationTriggerChar(char c) {
+ TriggerType getAutoActivationTriggerType(char c) {
if (fProcessors == null)
- return false;
-
- for (Set<IContentAssistProcessor> processorsForContentType : fProcessors.values()) {
- for (IContentAssistProcessor processor : processorsForContentType) {
- char[] triggers= processor.getCompletionProposalAutoActivationCharacters();
- if (triggers != null && new String(triggers).indexOf(c) >= 0) {
- return true;
- }
- triggers= processor.getContextInformationAutoActivationCharacters();
- if (triggers != null && new String(triggers).indexOf(c) >= 0) {
- return true;
- }
+ return TriggerType.NONE;
+ int offset= fContentAssistSubjectControlAdapter.getSelectedRange().x;
+ Set<IContentAssistProcessor> processors= fContentAssistSubjectControlAdapter.getContentAssistProcessors(this, offset);
+ if (processors == null) {
+ return TriggerType.NONE;
+ }
+ for (IContentAssistProcessor processor : processors) {
+ IContentAssistProcessorExtension extension= IContentAssistProcessorExtension.adapt(processor);
+ if (extension.isCompletionProposalAutoActivation(c, fViewer, offset)) {
+ return TriggerType.COMPLETION_PROPOSAL;
+ }
+ if (extension.isContextInformationAutoActivation(c, fViewer, offset)) {
+ return TriggerType.CONTEXT_INFORMATION;
}
}
- return false;
+ return TriggerType.NONE;
}
/**
@@ -1916,7 +1906,7 @@ public class ContentAssistant implements IContentAssistant, IContentAssistantExt
* @return the content-assist processors or <code>null</code> if none exists
* @since 3.13
*/
- private Set<IContentAssistProcessor> getProcessors(ITextViewer viewer, int offset) {
+ Set<IContentAssistProcessor> getProcessors(ITextViewer viewer, int offset) {
try {
IDocument document= viewer.getDocument();
@@ -1938,7 +1928,7 @@ public class ContentAssistant implements IContentAssistant, IContentAssistantExt
* @return the content-assist processors or <code>null</code> if none exists
* @since 3.13
*/
- private Set<IContentAssistProcessor> getProcessors(IContentAssistSubjectControl contentAssistSubjectControl, int offset) {
+ Set<IContentAssistProcessor> getProcessors(IContentAssistSubjectControl contentAssistSubjectControl, int offset) {
try {
IDocument document= contentAssistSubjectControl.getDocument();
@@ -2188,95 +2178,6 @@ public class ContentAssistant implements IContentAssistant, IContentAssistantExt
return null;
}
- /**
- * Returns the characters which when typed by the user should automatically initiate proposing
- * completions. The position is used to determine the appropriate content assist processor to
- * invoke.
- *
- * @param contentAssistSubjectControl the content assist subject control
- * @param offset a document offset
- * @return the auto activation characters
- * @see IContentAssistProcessor#getCompletionProposalAutoActivationCharacters()
- * @since 3.0
- */
- char[] getCompletionProposalAutoActivationCharacters(IContentAssistSubjectControl contentAssistSubjectControl, int offset) {
- return mergeResults(getProcessors(contentAssistSubjectControl, offset), IContentAssistProcessor::getCompletionProposalAutoActivationCharacters);
- }
-
- /**
- * Returns the characters which when typed by the user should automatically initiate proposing
- * completions. The position is used to determine the appropriate content assist processor to
- * invoke.
- *
- * @param viewer the text viewer
- * @param offset a document offset
- * @return the auto activation characters
- * @see IContentAssistProcessor#getCompletionProposalAutoActivationCharacters()
- */
- char[] getCompletionProposalAutoActivationCharacters(ITextViewer viewer, int offset) {
- return mergeResults(getProcessors(viewer, offset), IContentAssistProcessor::getCompletionProposalAutoActivationCharacters);
- }
-
- /**
- * Returns the characters which when typed by the user should automatically initiate the
- * presentation of context information. The position is used to determine the appropriate
- * content assist processor to invoke.
- *
- * @param viewer the text viewer
- * @param offset a document offset
- * @return the auto activation characters
- * @see IContentAssistProcessor#getContextInformationAutoActivationCharacters()
- * @since 3.0
- */
- char[] getContextInformationAutoActivationCharacters(ITextViewer viewer, int offset) {
- return mergeResults(getProcessors(viewer, offset), IContentAssistProcessor::getContextInformationAutoActivationCharacters);
- }
-
- /**
- * Returns the characters which when typed by the user should automatically initiate the
- * presentation of context information. The position is used to determine the appropriate
- * content assist processor to invoke.
- *
- * @param contentAssistSubjectControl the content assist subject control
- * @param offset a document offset
- * @return the auto activation characters
- * @see IContentAssistProcessor#getContextInformationAutoActivationCharacters()
- * @since 3.0
- */
- char[] getContextInformationAutoActivationCharacters(IContentAssistSubjectControl contentAssistSubjectControl, int offset) {
- return mergeResults(getProcessors(contentAssistSubjectControl, offset), IContentAssistProcessor::getContextInformationAutoActivationCharacters);
- }
-
- private char[] mergeResults(Collection<IContentAssistProcessor> processors, Function<IContentAssistProcessor, char[]> f) {
- if (processors == null) {
- return null;
- }
- char[][] arrays = processors.stream()
- .map(f)
- .filter(Objects::nonNull)
- .filter(array -> array.length > 0)
- .toArray(char[][]::new);
- if (arrays.length == 0) {
- return null;
- } else if (arrays.length == 1) {
- return arrays[0];
- } else {
- LinkedHashSet<Character> res = new LinkedHashSet<>();
- for (char[] current : arrays) {
- for (char c : current) {
- res.add(Character.valueOf(c));
- }
- }
- char[] array = new char[res.size()];
- int index = 0;
- for (Character c : res) {
- array[index] = c.charValue();
- index++;
- }
- return array;
- }
- }
-
@Override
public boolean requestWidgetToken(IWidgetTokenOwner owner) {
return false;
diff --git a/org.eclipse.jface.text/src/org/eclipse/jface/text/contentassist/IContentAssistProcessor.java b/org.eclipse.jface.text/src/org/eclipse/jface/text/contentassist/IContentAssistProcessor.java
index 42ab49a8502..04d9e6b8c46 100644
--- a/org.eclipse.jface.text/src/org/eclipse/jface/text/contentassist/IContentAssistProcessor.java
+++ b/org.eclipse.jface.text/src/org/eclipse/jface/text/contentassist/IContentAssistProcessor.java
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2000, 2005 IBM Corporation and others.
+ * Copyright (c) 2000, 2021 IBM Corporation and others.
*
* This program and the accompanying materials
* are made available under the terms of the Eclipse Public License 2.0
@@ -10,6 +10,7 @@
*
* Contributors:
* IBM Corporation - initial API and implementation
+ * Christoph Läubrich - Bug 508821 - [Content assist] More flexible API in IContentAssistProcessor to decide whether to auto-activate or not
*******************************************************************************/
package org.eclipse.jface.text.contentassist;
@@ -17,16 +18,29 @@ import org.eclipse.jface.text.ITextViewer;
/**
- * A content assist processor proposes completions and
- * computes context information for a particular content type.
- * A content assist processor is a {@link org.eclipse.jface.text.contentassist.IContentAssistant}
- * plug-in.
+ * A content assist processor proposes completions and computes context information for a particular
+ * content type. A content assist processor is a
+ * {@link org.eclipse.jface.text.contentassist.IContentAssistant} plug-in.
* <p>
- * This interface must be implemented by clients. Implementers should be
- * registered with a content assistant in order to get involved in the
- * assisting process.
+ * This interface must be implemented by clients. Implementers should be registered with a content
+ * assistant in order to get involved in the assisting process.
* </p>
-*/
+ * In order to provide backward compatibility for clients of <code>IContentAssistProcessor</code>,
+ * extension interfaces are used to provide a means of evolution. The following extension interfaces
+ * exist:
+ * </p>
+ * <ul>
+ * <li>{@link org.eclipse.jface.text.contentassist.IContentAssistProcessorExtension} since version
+ * 3.17 introducing the following functions:
+ * <ul>
+ * <li>isCompletionProposalAutoActivation(char, ITextViewer, int) providing context information when
+ * calculating auto activation</li>
+ * <li>isContextInformationAutoActivation(char, ITextViewer, int) providing context information when
+ * calculating auto activation</li>
+ * </ul>
+ * </li>
+ * </ul>
+ */
public interface IContentAssistProcessor {
/**
diff --git a/org.eclipse.jface.text/src/org/eclipse/jface/text/contentassist/IContentAssistProcessorExtension.java b/org.eclipse.jface.text/src/org/eclipse/jface/text/contentassist/IContentAssistProcessorExtension.java
new file mode 100644
index 00000000000..2be67dc2e65
--- /dev/null
+++ b/org.eclipse.jface.text/src/org/eclipse/jface/text/contentassist/IContentAssistProcessorExtension.java
@@ -0,0 +1,141 @@
+/*******************************************************************************
+ * Copyright (c) 2021 Christoph Läubrich and others.
+ *
+ * This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License 2.0
+ * which accompanies this distribution, and is available at
+ * https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ *
+ * Contributors:
+ * Christoph Läubrich - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jface.text.contentassist;
+
+import org.eclipse.jface.text.ITextViewer;
+
+/**
+ * Extension interface of {@link IContentAssistProcessor} that allows to get additional information
+ * when queried for auto activation
+ *
+ * @since 3.17
+ */
+public interface IContentAssistProcessorExtension extends IContentAssistProcessor {
+
+ /**
+ * @deprecated use {@link #isCompletionProposalAutoActivation(char, ITextViewer, int)} instead
+ * @noreference use {@link #isCompletionProposalAutoActivation(char, ITextViewer, int)} instead
+ * @nooverride This default method is not intended to be re-implemented or extended by
+ * clients.noimplement implement
+ * {@link #isCompletionProposalAutoActivation(char, ITextViewer, int)} instead
+ */
+ @Deprecated
+ @Override
+ default char[] getCompletionProposalAutoActivationCharacters() {
+ throw new UnsupportedOperationException("use isCompletionProposalAutoActivation instead"); //$NON-NLS-1$
+ }
+
+
+ /**
+ * @deprecated use {@link #isContextInformationAutoActivation(char, ITextViewer, int)} instead
+ * @noreference use {@link #isContextInformationAutoActivation(char, ITextViewer, int)} instead
+ * @nooverride This default method is not intended to be re-implemented or extended by
+ * clients.noimplement implement
+ * {@link #isContextInformationAutoActivation(char, ITextViewer, int)} instead
+ */
+ @Deprecated
+ @Override
+ default char[] getContextInformationAutoActivationCharacters() {
+ throw new UnsupportedOperationException("use isContextInformationAutoActivation instead"); //$NON-NLS-1$
+ }
+
+ /**
+ * Check if the given event should trigger an automatic completion proposal activation
+ *
+ * @param c the character to check
+ * @param viewer the viewer
+ * @param offset the current offset
+ * @return <code>true</code> if auto activation is desired, <code>false</code> otherwise
+ */
+ boolean isCompletionProposalAutoActivation(char c, ITextViewer viewer, int offset);
+ /**
+ * Check if the given event should trigger an automatic context info activation
+ *
+ * @param c the character to check
+ * @param viewer the viewer
+ * @param offset the current offset
+ * @return <code>true</code> if auto activation is desired, <code>false</code> otherwise
+ */
+ boolean isContextInformationAutoActivation(char c, ITextViewer viewer, int offset);
+
+ static IContentAssistProcessorExtension adapt(IContentAssistProcessor processor) {
+ if (processor == null) {
+ return null;
+ }
+ if (processor instanceof IContentAssistProcessorExtension) {
+ return (IContentAssistProcessorExtension) processor;
+ }
+ return new IContentAssistProcessorExtension() {
+
+ @Override
+ public String getErrorMessage() {
+ return processor.getErrorMessage();
+ }
+
+ @Override
+ public IContextInformationValidator getContextInformationValidator() {
+ return processor.getContextInformationValidator();
+ }
+
+ @Override
+ public IContextInformation[] computeContextInformation(ITextViewer viewer, int offset) {
+ return processor.computeContextInformation(viewer, offset);
+ }
+
+ @Override
+ public ICompletionProposal[] computeCompletionProposals(ITextViewer viewer, int offset) {
+ return processor.computeCompletionProposals(viewer, offset);
+ }
+
+ @Deprecated
+ @Override
+ public char[] getCompletionProposalAutoActivationCharacters() {
+ return processor.getCompletionProposalAutoActivationCharacters();
+ }
+
+ @Deprecated
+ @Override
+ public char[] getContextInformationAutoActivationCharacters() {
+ return processor.getContextInformationAutoActivationCharacters();
+ }
+
+ @Override
+ public boolean isCompletionProposalAutoActivation(char c, ITextViewer viewer, int offset) {
+ char[] triggers= processor.getCompletionProposalAutoActivationCharacters();
+ if (triggers != null) {
+ for (char trigger : triggers) {
+ if (c == trigger) {
+ return true;
+ }
+ }
+ }
+ return false;
+ }
+
+ @Override
+ public boolean isContextInformationAutoActivation(char c, ITextViewer viewer, int offset) {
+ char[] triggers= processor.getContextInformationAutoActivationCharacters();
+ if (triggers != null) {
+ for (char trigger : triggers) {
+ if (c == trigger) {
+ return true;
+ }
+ }
+ }
+ return false;
+ }
+ };
+ }
+
+}
diff --git a/org.eclipse.ui.genericeditor/src/org/eclipse/ui/internal/genericeditor/CompositeContentAssistProcessor.java b/org.eclipse.ui.genericeditor/src/org/eclipse/ui/internal/genericeditor/CompositeContentAssistProcessor.java
index 2df42cd38b5..0992061e3a8 100644
--- a/org.eclipse.ui.genericeditor/src/org/eclipse/ui/internal/genericeditor/CompositeContentAssistProcessor.java
+++ b/org.eclipse.ui.genericeditor/src/org/eclipse/ui/internal/genericeditor/CompositeContentAssistProcessor.java
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2016 Red Hat Inc. and others.
+ * Copyright (c) 2016, 2021 Red Hat Inc. and others.
*
* This program and the accompanying materials
* are made available under the terms of the Eclipse Public License 2.0
@@ -9,40 +9,40 @@
* SPDX-License-Identifier: EPL-2.0
*
* Contributors:
- * - Mickael Istria (Red Hat Inc.)
+ * Mickael Istria (Red Hat Inc.) - Initial API and implementation
+ * Christoph Läubrich - Bug 508821 - [Content assist] More flexible API in IContentAssistProcessor to decide whether to auto-activate or not
*******************************************************************************/
package org.eclipse.ui.internal.genericeditor;
import java.util.ArrayList;
import java.util.Arrays;
-import java.util.HashSet;
import java.util.List;
-import java.util.Set;
import org.eclipse.jface.text.ITextViewer;
import org.eclipse.jface.text.contentassist.ICompletionProposal;
import org.eclipse.jface.text.contentassist.IContentAssistProcessor;
+import org.eclipse.jface.text.contentassist.IContentAssistProcessorExtension;
import org.eclipse.jface.text.contentassist.IContextInformation;
import org.eclipse.jface.text.contentassist.IContextInformationValidator;
/**
- * A content assist processor that delegates all content assist
- * operations to children provided in constructor and aggregates
- * the results.
+ * A content assist processor that delegates all content assist operations to
+ * children provided in constructor and aggregates the results.
*
* @since 1.0
*/
-public class CompositeContentAssistProcessor implements IContentAssistProcessor {
+public class CompositeContentAssistProcessor implements IContentAssistProcessorExtension, IContentAssistProcessor {
private List<IContentAssistProcessor> fContentAssistProcessors;
/**
* Constructor
- * @param contentAssistProcessors the children that will actually populate the output
- * of this content assist processor.
+ *
+ * @param contentAssistProcessors the children that will actually populate the
+ * output of this content assist processor.
*/
public CompositeContentAssistProcessor(List<IContentAssistProcessor> contentAssistProcessors) {
- fContentAssistProcessors= contentAssistProcessors;
+ fContentAssistProcessors = contentAssistProcessors;
}
@Override
@@ -70,44 +70,6 @@ public class CompositeContentAssistProcessor implements IContentAssistProcessor
}
@Override
- public char[] getCompletionProposalAutoActivationCharacters() {
- Set<Character> res = new HashSet<>();
- for (IContentAssistProcessor processor : this.fContentAssistProcessors) {
- char[] chars = processor.getCompletionProposalAutoActivationCharacters();
- if (chars != null) {
- for (char c : chars) {
- res.add(Character.valueOf(c));
- }
- }
- }
- return toCharArray(res);
- }
-
- private static char[] toCharArray(Set<Character> chars) {
- char[] res = new char[chars.size()];
- int i = 0;
- for (Character c : chars) {
- res[i] = c.charValue();
- i++;
- }
- return res;
- }
-
- @Override
- public char[] getContextInformationAutoActivationCharacters() {
- Set<Character> res = new HashSet<>();
- for (IContentAssistProcessor processor : this.fContentAssistProcessors) {
- char[] chars = processor.getContextInformationAutoActivationCharacters();
- if (chars != null) {
- for (char c : chars) {
- res.add(Character.valueOf(c));
- }
- }
- }
- return toCharArray(res);
- }
-
- @Override
public String getErrorMessage() {
StringBuilder res = new StringBuilder();
for (IContentAssistProcessor processor : this.fContentAssistProcessors) {
@@ -128,4 +90,26 @@ public class CompositeContentAssistProcessor implements IContentAssistProcessor
return null;
}
+ @Override
+ public boolean isCompletionProposalAutoActivation(char c, ITextViewer viewer, int offset) {
+ for (IContentAssistProcessor processor : this.fContentAssistProcessors) {
+ IContentAssistProcessorExtension adapt = IContentAssistProcessorExtension.adapt(processor);
+ if (adapt.isCompletionProposalAutoActivation(c, viewer, offset)) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ @Override
+ public boolean isContextInformationAutoActivation(char c, ITextViewer viewer, int offset) {
+ for (IContentAssistProcessor processor : this.fContentAssistProcessors) {
+ IContentAssistProcessorExtension adapt = IContentAssistProcessorExtension.adapt(processor);
+ if (adapt.isContextInformationAutoActivation(c, viewer, offset)) {
+ return true;
+ }
+ }
+ return false;
+ }
+
} \ No newline at end of file

Back to the top