Skip to main content
aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorChristoph Läubrich2021-01-21 13:58:55 +0000
committerMickael Istria2021-01-22 13:05:16 +0000
commit02497e3b6625f487edaa64d0276cb77e29d9af42 (patch)
tree19f32e76b0bfd7f96cf1387b05cd0b6f4577a6ba
parent0ff22b3f712a6838f4d1c5b31656e0df1eeb122a (diff)
downloadeclipse.platform.text-02497e3b6625f487edaa64d0276cb77e29d9af42.tar.gz
eclipse.platform.text-02497e3b6625f487edaa64d0276cb77e29d9af42.tar.xz
eclipse.platform.text-02497e3b6625f487edaa64d0276cb77e29d9af42.zip
Bug 570459 - [genericeditor] Support ContentAssistProcessors to be
registered as OSGi-Services Change-Id: Ie642d4f401646ff2b186166ec3a5c9ef484f0e4f Signed-off-by: Christoph Läubrich <laeubi@laeubi-soft.de>
-rw-r--r--org.eclipse.jface.text/src/org/eclipse/jface/text/contentassist/ContentAssistant.java22
-rw-r--r--org.eclipse.ui.genericeditor.tests/src/org/eclipse/ui/genericeditor/tests/CompletionTest.java67
-rw-r--r--org.eclipse.ui.genericeditor/src/org/eclipse/ui/internal/genericeditor/ContentTypeRelatedExtensionTracker.java137
-rw-r--r--org.eclipse.ui.genericeditor/src/org/eclipse/ui/internal/genericeditor/ExtensionBasedTextViewerConfiguration.java47
-rw-r--r--org.eclipse.ui.genericeditor/src/org/eclipse/ui/internal/genericeditor/GenericEditorContentAssistant.java145
5 files changed, 381 insertions, 37 deletions
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 2f92d9c4906..3c4a8349dca 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
@@ -16,6 +16,7 @@
* 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
+ * Bug 570459 - [genericeditor] Support ContentAssistProcessors to be registered as OSGi-Services
*******************************************************************************/
package org.eclipse.jface.text.contentassist;
@@ -1131,10 +1132,22 @@ public class ContentAssistant implements IContentAssistant, IContentAssistantExt
if (processor == null) {
fProcessors.remove(contentType);
} else {
- if (!fProcessors.containsKey(contentType)) {
- fProcessors.put(contentType, new LinkedHashSet<>());
- }
- fProcessors.get(contentType).add(processor);
+ fProcessors.computeIfAbsent(contentType, key -> new LinkedHashSet<>()).add(processor);
+ }
+ }
+
+ /**
+ * removes the given processor from all content types in this {@link ContentAssistant}
+ *
+ * @param processor The content-assist process to remove
+ * @since 3.17
+ */
+ public void removeContentAssistProcessor(IContentAssistProcessor processor) {
+ if (fProcessors == null || processor == null) {
+ return;
+ }
+ for (Set<IContentAssistProcessor> set : fProcessors.values()) {
+ set.remove(processor);
}
}
@@ -2705,4 +2718,5 @@ public class ContentAssistant implements IContentAssistant, IContentAssistantExt
boolean isAutoActivation() {
return fIsAutoActivated;
}
+
}
diff --git a/org.eclipse.ui.genericeditor.tests/src/org/eclipse/ui/genericeditor/tests/CompletionTest.java b/org.eclipse.ui.genericeditor.tests/src/org/eclipse/ui/genericeditor/tests/CompletionTest.java
index dd18ceaf298..dcf4a7d27c0 100644
--- a/org.eclipse.ui.genericeditor.tests/src/org/eclipse/ui/genericeditor/tests/CompletionTest.java
+++ b/org.eclipse.ui.genericeditor.tests/src/org/eclipse/ui/genericeditor/tests/CompletionTest.java
@@ -20,12 +20,18 @@ import static org.junit.Assert.assertTrue;
import java.util.ArrayList;
import java.util.Arrays;
+import java.util.Collections;
+import java.util.Hashtable;
import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;
import org.junit.After;
import org.junit.Test;
+import org.osgi.framework.Bundle;
+import org.osgi.framework.BundleContext;
+import org.osgi.framework.FrameworkUtil;
+import org.osgi.framework.ServiceRegistration;
import org.eclipse.swt.SWT;
import org.eclipse.swt.custom.ST;
@@ -45,7 +51,11 @@ import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.Platform;
import org.eclipse.jface.text.ITextSelection;
+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.IContextInformation;
+import org.eclipse.jface.text.contentassist.IContextInformationValidator;
import org.eclipse.jface.text.tests.util.DisplayHelper;
import org.eclipse.ui.genericeditor.tests.contributions.BarContentAssistProcessor;
@@ -87,6 +97,26 @@ public class CompletionTest extends AbstratGenericEditorTest {
}
@Test
+ public void testCompletionService() throws Exception {
+ Bundle bundle= FrameworkUtil.getBundle(CompletionTest.class);
+ assertNotNull(bundle);
+ BundleContext bundleContext= bundle.getBundleContext();
+ assertNotNull(bundleContext);
+ MockContentAssistProcessor service= new MockContentAssistProcessor();
+ ServiceRegistration<IContentAssistProcessor> registration= bundleContext.registerService(IContentAssistProcessor.class, service,
+ new Hashtable<>(Collections.singletonMap("contentType", "org.eclipse.ui.genericeditor.tests.content-type")));
+ DisplayHelper.driveEventQueue(Display.getCurrent());
+ final Set<Shell> beforeShells= Arrays.stream(editor.getSite().getShell().getDisplay().getShells()).filter(Shell::isVisible).collect(Collectors.toSet());
+ editor.selectAndReveal(3, 0);
+ openConentAssist();
+ this.completionShell= findNewShell(beforeShells, editor.getSite().getShell().getDisplay());
+ final Table completionProposalList= findCompletionSelectionControl(completionShell);
+ checkCompletionContent(completionProposalList);
+ assertTrue("Service was not called!", service.called);
+ registration.unregister();
+ }
+
+ @Test
public void testCompletionUsingViewerSelection() throws Exception {
final Set<Shell> beforeShells = Arrays.stream(editor.getSite().getShell().getDisplay().getShells()).filter(Shell::isVisible).collect(Collectors.toSet());
editor.getDocumentProvider().getDocument(editor.getEditorInput()).set("abc");
@@ -257,4 +287,41 @@ public class CompletionTest extends AbstratGenericEditorTest {
}
}
+
+ private static final class MockContentAssistProcessor implements IContentAssistProcessor {
+
+ private boolean called;
+
+ @Override
+ public ICompletionProposal[] computeCompletionProposals(ITextViewer viewer, int offset) {
+ called= true;
+ return null;
+ }
+
+ @Override
+ public IContextInformation[] computeContextInformation(ITextViewer viewer, int offset) {
+ return null;
+ }
+
+ @Override
+ public char[] getCompletionProposalAutoActivationCharacters() {
+ return null;
+ }
+
+ @Override
+ public char[] getContextInformationAutoActivationCharacters() {
+ return null;
+ }
+
+ @Override
+ public String getErrorMessage() {
+ return null;
+ }
+
+ @Override
+ public IContextInformationValidator getContextInformationValidator() {
+ return null;
+ }
+
+ }
}
diff --git a/org.eclipse.ui.genericeditor/src/org/eclipse/ui/internal/genericeditor/ContentTypeRelatedExtensionTracker.java b/org.eclipse.ui.genericeditor/src/org/eclipse/ui/internal/genericeditor/ContentTypeRelatedExtensionTracker.java
new file mode 100644
index 00000000000..d2d5b9176a7
--- /dev/null
+++ b/org.eclipse.ui.genericeditor/src/org/eclipse/ui/internal/genericeditor/ContentTypeRelatedExtensionTracker.java
@@ -0,0 +1,137 @@
+/*******************************************************************************
+ * 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 - Inital API and implementation
+ *******************************************************************************/
+package org.eclipse.ui.internal.genericeditor;
+
+import java.util.Collection;
+import java.util.function.Consumer;
+import java.util.function.Supplier;
+
+import org.eclipse.core.runtime.Platform;
+import org.eclipse.core.runtime.content.IContentType;
+import org.eclipse.swt.widgets.Display;
+import org.eclipse.ui.internal.genericeditor.ContentTypeRelatedExtensionTracker.LazyServiceSupplier;
+import org.osgi.framework.BundleContext;
+import org.osgi.framework.ServiceReference;
+import org.osgi.util.tracker.ServiceTracker;
+import org.osgi.util.tracker.ServiceTrackerCustomizer;
+
+/**
+ * {@link ServiceTrackerCustomizer} that maps OSGi-Services to
+ * ContentTypeRelatedExtensions
+ *
+ * @param <T> the type of extension to map
+ */
+final class ContentTypeRelatedExtensionTracker<T> implements ServiceTrackerCustomizer<T, LazyServiceSupplier<T>> {
+
+ private BundleContext bundleContext;
+ private ServiceTracker<T, LazyServiceSupplier<T>> serviceTracker;
+ private Consumer<LazyServiceSupplier<T>> addAction;
+ private Consumer<LazyServiceSupplier<T>> removeAction;
+ private Display display;
+
+ ContentTypeRelatedExtensionTracker(BundleContext bundleContext, Class<T> serviceType, Display display) {
+ this.bundleContext = bundleContext;
+ this.display = display;
+ serviceTracker = new ServiceTracker<>(bundleContext, serviceType, this);
+ }
+
+ public void stopTracking() {
+ serviceTracker.close();
+ }
+
+ @Override
+ public LazyServiceSupplier<T> addingService(ServiceReference<T> reference) {
+ LazyServiceSupplier<T> supplier = new LazyServiceSupplier<>(bundleContext, reference);
+ if (addAction != null) {
+ display.asyncExec(() -> addAction.accept(supplier));
+ }
+ return supplier;
+ }
+
+ @Override
+ public void modifiedService(ServiceReference<T> reference, LazyServiceSupplier<T> service) {
+ service.update();
+ }
+
+ @Override
+ public void removedService(ServiceReference<T> reference, LazyServiceSupplier<T> service) {
+ service.dispose();
+ if (removeAction != null) {
+ display.asyncExec(() -> removeAction.accept(service));
+ }
+ }
+
+ public void onAdd(Consumer<LazyServiceSupplier<T>> action) {
+ this.addAction = action;
+ }
+
+ public void onRemove(Consumer<LazyServiceSupplier<T>> action) {
+ this.removeAction = action;
+ }
+
+ public void startTracking() {
+ serviceTracker.open();
+ }
+
+ public Collection<LazyServiceSupplier<T>> getTracked() {
+ return serviceTracker.getTracked().values();
+ }
+
+ public static final class LazyServiceSupplier<S> implements Supplier<S> {
+ private ServiceReference<S> reference;
+ private BundleContext bundleContext;
+ private boolean disposed;
+ private S serviceObject;
+ private IContentType contentType;
+
+ LazyServiceSupplier(BundleContext bundleContext, ServiceReference<S> reference) {
+ this.reference = reference;
+ this.bundleContext = bundleContext;
+ update();
+ }
+
+ private String getProperty(String attribute) {
+ return (String) reference.getProperty(attribute);
+ }
+
+ synchronized void update() {
+ contentType = Platform.getContentTypeManager()
+ .getContentType(getProperty(GenericContentTypeRelatedExtension.CONTENT_TYPE_ATTRIBUTE));
+ }
+
+ public synchronized IContentType getContentType() {
+ return contentType;
+ }
+
+ synchronized void dispose() {
+ disposed = true;
+ if (serviceObject != null) {
+ bundleContext.ungetService(reference);
+ }
+ }
+
+ @Override
+ public synchronized S get() {
+ if (!disposed && serviceObject == null) {
+ serviceObject = bundleContext.getService(reference);
+ }
+ return serviceObject;
+ }
+
+ public synchronized boolean isPresent() {
+ return serviceObject != null;
+ }
+ }
+
+}
diff --git a/org.eclipse.ui.genericeditor/src/org/eclipse/ui/internal/genericeditor/ExtensionBasedTextViewerConfiguration.java b/org.eclipse.ui.genericeditor/src/org/eclipse/ui/internal/genericeditor/ExtensionBasedTextViewerConfiguration.java
index 41ae32499e3..2ef26c14123 100644
--- a/org.eclipse.ui.genericeditor/src/org/eclipse/ui/internal/genericeditor/ExtensionBasedTextViewerConfiguration.java
+++ b/org.eclipse.ui.genericeditor/src/org/eclipse/ui/internal/genericeditor/ExtensionBasedTextViewerConfiguration.java
@@ -14,6 +14,7 @@
* - Bug 521382 default highlight reconciler
* Simon Scholz <simon.scholz@vogella.com> - Bug 527830
* Angelo Zerr <angelo.zerr@gmail.com> - [generic editor] Default Code folding for generic editor should use IndentFoldingStrategy - Bug 520659
+ * Christoph Läubrich - Bug 570459 - [genericeditor] Support ContentAssistProcessors to be registered as OSGi-Services
*******************************************************************************/
package org.eclipse.ui.internal.genericeditor;
@@ -33,14 +34,12 @@ import org.eclipse.core.runtime.IAdaptable;
import org.eclipse.core.runtime.Platform;
import org.eclipse.core.runtime.content.IContentType;
import org.eclipse.jface.preference.IPreferenceStore;
-import org.eclipse.jface.text.AbstractReusableInformationControlCreator;
import org.eclipse.jface.text.DefaultInformationControl;
import org.eclipse.jface.text.IAutoEditStrategy;
import org.eclipse.jface.text.IDocument;
import org.eclipse.jface.text.IDocumentPartitioningListener;
-import org.eclipse.jface.text.IInformationControl;
import org.eclipse.jface.text.ITextHover;
-import org.eclipse.jface.text.contentassist.ContentAssistant;
+import org.eclipse.jface.text.ITextViewer;
import org.eclipse.jface.text.contentassist.IContentAssistProcessor;
import org.eclipse.jface.text.contentassist.IContentAssistant;
import org.eclipse.jface.text.presentation.IPresentationReconciler;
@@ -49,7 +48,6 @@ import org.eclipse.jface.text.quickassist.IQuickAssistProcessor;
import org.eclipse.jface.text.quickassist.QuickAssistAssistant;
import org.eclipse.jface.text.reconciler.IReconciler;
import org.eclipse.jface.text.source.ISourceViewer;
-import org.eclipse.swt.widgets.Shell;
import org.eclipse.ui.editors.text.TextSourceViewerConfiguration;
import org.eclipse.ui.internal.editors.text.EditorsPlugin;
import org.eclipse.ui.internal.genericeditor.folding.DefaultFoldingReconciler;
@@ -72,8 +70,7 @@ public final class ExtensionBasedTextViewerConfiguration extends TextSourceViewe
private Set<IContentType> contentTypes;
private IDocument document;
- private ContentAssistant contentAssistant;
- private List<IContentAssistProcessor> processors;
+ private GenericEditorContentAssistant contentAssistant;
/**
*
@@ -85,7 +82,7 @@ public final class ExtensionBasedTextViewerConfiguration extends TextSourceViewe
this.editor = editor;
}
- Set<IContentType> getContentTypes(ISourceViewer viewer) {
+ Set<IContentType> getContentTypes(ITextViewer viewer) {
if (this.contentTypes == null) {
this.contentTypes = new LinkedHashSet<>();
String fileName = null;
@@ -107,7 +104,7 @@ public final class ExtensionBasedTextViewerConfiguration extends TextSourceViewe
return this.contentTypes;
}
- private String getCurrentFileName(ISourceViewer viewer) {
+ private String getCurrentFileName(ITextViewer viewer) {
String fileName = null;
if (this.editor != null) {
fileName = editor.getEditorInput().getName();
@@ -140,28 +137,15 @@ public final class ExtensionBasedTextViewerConfiguration extends TextSourceViewe
@Override
public IContentAssistant getContentAssistant(ISourceViewer sourceViewer) {
ContentAssistProcessorRegistry registry = GenericEditorPlugin.getDefault().getContentAssistProcessorRegistry();
- contentAssistant = new ContentAssistant(true);
- contentAssistant.setContextInformationPopupOrientation(IContentAssistant.CONTEXT_INFO_BELOW);
- contentAssistant.setProposalPopupOrientation(IContentAssistant.PROPOSAL_REMOVE);
- contentAssistant.setAutoActivationDelay(0);
- contentAssistant.enableColoredLabels(true);
- contentAssistant.enableAutoActivation(true);
- this.processors = registry.getContentAssistProcessors(sourceViewer, editor, getContentTypes(sourceViewer));
- if (this.processors.isEmpty()) {
- this.processors.add(new DefaultContentAssistProcessor());
- }
- for (IContentAssistProcessor processor : this.processors) {
- contentAssistant.addContentAssistProcessor(processor, IDocument.DEFAULT_CONTENT_TYPE);
- }
+ ContentTypeRelatedExtensionTracker<IContentAssistProcessor> contentAssistProcessorTracker = new ContentTypeRelatedExtensionTracker<>(
+ GenericEditorPlugin.getDefault().getBundle().getBundleContext(), IContentAssistProcessor.class,
+ sourceViewer.getTextWidget().getDisplay());
+ Set<IContentType> types = getContentTypes(sourceViewer);
+ contentAssistant = new GenericEditorContentAssistant(contentAssistProcessorTracker,
+ registry.getContentAssistProcessors(sourceViewer, editor, types), types);
if (this.document != null) {
associateTokenContentTypes(this.document);
}
- contentAssistant.setInformationControlCreator(new AbstractReusableInformationControlCreator() {
- @Override
- protected IInformationControl doCreateInformationControl(Shell parent) {
- return new DefaultInformationControl(parent);
- }
- });
watchDocument(sourceViewer.getDocument());
return contentAssistant;
}
@@ -197,14 +181,10 @@ public final class ExtensionBasedTextViewerConfiguration extends TextSourceViewe
}
private void associateTokenContentTypes(IDocument document) {
- if (contentAssistant == null || this.processors == null) {
+ if (contentAssistant == null) {
return;
}
- for (String legalTokenContentType : document.getLegalContentTypes()) {
- for (IContentAssistProcessor processor : this.processors) {
- contentAssistant.addContentAssistProcessor(processor, legalTokenContentType);
- }
- }
+ contentAssistant.updateTokens(document);
}
@Override
@@ -268,4 +248,5 @@ public final class ExtensionBasedTextViewerConfiguration extends TextSourceViewe
targets.put(ExtensionBasedTextEditor.GENERIC_EDITOR_ID, editor);
return targets;
}
+
}
diff --git a/org.eclipse.ui.genericeditor/src/org/eclipse/ui/internal/genericeditor/GenericEditorContentAssistant.java b/org.eclipse.ui.genericeditor/src/org/eclipse/ui/internal/genericeditor/GenericEditorContentAssistant.java
new file mode 100644
index 00000000000..62953a95310
--- /dev/null
+++ b/org.eclipse.ui.genericeditor/src/org/eclipse/ui/internal/genericeditor/GenericEditorContentAssistant.java
@@ -0,0 +1,145 @@
+/*******************************************************************************
+ * 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 - Inital API and implementation
+ *******************************************************************************/
+package org.eclipse.ui.internal.genericeditor;
+
+import java.util.Collections;
+import java.util.List;
+import java.util.Objects;
+import java.util.Set;
+
+import org.eclipse.core.runtime.content.IContentType;
+import org.eclipse.jface.text.AbstractReusableInformationControlCreator;
+import org.eclipse.jface.text.DefaultInformationControl;
+import org.eclipse.jface.text.IDocument;
+import org.eclipse.jface.text.IInformationControl;
+import org.eclipse.jface.text.ITextViewer;
+import org.eclipse.jface.text.contentassist.ContentAssistant;
+import org.eclipse.jface.text.contentassist.IContentAssistProcessor;
+import org.eclipse.jface.text.contentassist.IContentAssistant;
+import org.eclipse.swt.widgets.Shell;
+
+/**
+ * Extension of the ContentAssistant that supports the following additional
+ * features:
+ * <ul>
+ * <li>#updateTokens refresh the registration of
+ * {@link IContentAssistProcessor}s on document changes</li>
+ * <li>Using a ContentTypeRelatedExtensionTracker to dynamically track
+ * IContentAssistProcessor in the OSGi service registry
+ * </ul>
+ *
+ * @author christoph
+ *
+ */
+public class GenericEditorContentAssistant extends ContentAssistant {
+ private static final DefaultContentAssistProcessor DEFAULT_CONTENT_ASSIST_PROCESSOR = new DefaultContentAssistProcessor();
+ private ContentTypeRelatedExtensionTracker<IContentAssistProcessor> contentAssistProcessorTracker;
+ private Set<IContentType> types;
+ private List<IContentAssistProcessor> processors;
+
+ /**
+ * Creates a new GenericEditorContentAssistant instance for the given content
+ * types and contentAssistProcessorTracker
+ *
+ * @param contentAssistProcessorTracker the tracker to use for tracking
+ * additional
+ * {@link IContentAssistProcessor}s in the
+ * OSGi service factory
+ * @param processors the static processor list
+ * @param types the {@link IContentType} that are used
+ * to filter appropriate candidates from
+ * the registry
+ */
+ public GenericEditorContentAssistant(
+ ContentTypeRelatedExtensionTracker<IContentAssistProcessor> contentAssistProcessorTracker,
+ List<IContentAssistProcessor> processors, Set<IContentType> types) {
+ super(true);
+ this.contentAssistProcessorTracker = contentAssistProcessorTracker;
+ this.processors = Objects.requireNonNullElseGet(processors, () -> Collections.emptyList());
+ this.types = types;
+
+ setContextInformationPopupOrientation(IContentAssistant.CONTEXT_INFO_BELOW);
+ setProposalPopupOrientation(IContentAssistant.PROPOSAL_REMOVE);
+ setAutoActivationDelay(0);
+ enableColoredLabels(true);
+ enableAutoActivation(true);
+ setInformationControlCreator(new AbstractReusableInformationControlCreator() {
+ @Override
+ protected IInformationControl doCreateInformationControl(Shell parent) {
+ return new DefaultInformationControl(parent);
+ }
+ });
+ }
+
+ /**
+ * Updates the {@link IContentAssistProcessor} registrations according to the
+ * documents content-type tokens
+ *
+ * @param document the document to use for updating the tokens
+ */
+ public void updateTokens(IDocument document) {
+ updateProcessors(document);
+ contentAssistProcessorTracker.getTracked().stream().filter(s -> s.isPresent()).map(s -> s.get())
+ .forEach(p -> updateProcessorToken(p, document));
+ }
+
+ private void updateProcessors(IDocument iDocument) {
+ if (processors.isEmpty()) {
+ updateProcessorToken(DEFAULT_CONTENT_ASSIST_PROCESSOR, iDocument);
+ } else {
+ for (IContentAssistProcessor processor : processors) {
+ updateProcessorToken(processor, iDocument);
+ }
+ }
+ }
+
+ private void updateProcessorToken(IContentAssistProcessor processor, IDocument document) {
+ removeContentAssistProcessor(processor);
+ addContentAssistProcessor(processor, IDocument.DEFAULT_CONTENT_TYPE);
+ if (document != null) {
+ for (String contentType : document.getLegalContentTypes()) {
+ addContentAssistProcessor(processor, contentType);
+ }
+ }
+ if (processor != DEFAULT_CONTENT_ASSIST_PROCESSOR) {
+ removeContentAssistProcessor(DEFAULT_CONTENT_ASSIST_PROCESSOR);
+ }
+ }
+
+ @Override
+ public void uninstall() {
+ contentAssistProcessorTracker.stopTracking();
+ super.uninstall();
+ }
+
+ @Override
+ public void install(ITextViewer textViewer) {
+ super.install(textViewer);
+ updateProcessors(textViewer.getDocument());
+ contentAssistProcessorTracker.onAdd(added -> {
+ if (types.contains(added.getContentType())) {
+ IContentAssistProcessor processor = added.get();
+ if (processor != null) {
+ updateProcessorToken(processor, textViewer.getDocument());
+ }
+ }
+ });
+ contentAssistProcessorTracker.onRemove(removed -> {
+ if (removed.isPresent()) {
+ removeContentAssistProcessor(removed.get());
+ }
+ });
+ contentAssistProcessorTracker.startTracking();
+ }
+}

Back to the top