diff --git a/org.eclipse.jface.text/META-INF/MANIFEST.MF b/org.eclipse.jface.text/META-INF/MANIFEST.MF
index 1bb52ab9f..0c38fd340 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.21.100.qualifier
+Bundle-Version: 3.22.0.qualifier
Bundle-Vendor: %providerName
Bundle-Localization: plugin
Export-Package:
diff --git a/org.eclipse.jface.text/src/org/eclipse/jface/text/ITextViewerLifecycle.java b/org.eclipse.jface.text/src/org/eclipse/jface/text/ITextViewerLifecycle.java
new file mode 100644
index 000000000..d9823c67b
--- /dev/null
+++ b/org.eclipse.jface.text/src/org/eclipse/jface/text/ITextViewerLifecycle.java
@@ -0,0 +1,64 @@
+/*******************************************************************************
+ * Copyright (c) 2022 Red Hat Inc. 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:
+ * - Angelo ZERR (Red Hat Inc.) - initial implementation
+ *******************************************************************************/
+package org.eclipse.jface.text;
+
+import org.eclipse.jface.text.DefaultInformationControl.IInformationPresenter;
+import org.eclipse.jface.text.contentassist.IContentAssistant;
+import org.eclipse.jface.text.hyperlink.IHyperlinkPresenter;
+import org.eclipse.jface.text.presentation.IPresentationReconciler;
+import org.eclipse.jface.text.reconciler.IReconciler;
+import org.eclipse.jface.text.reconciler.IReconcilingStrategy;
+import org.eclipse.jface.text.source.ISourceViewer;
+import org.eclipse.jface.text.source.ISourceViewerExtension2;
+
+/**
+ * {@link ITextViewer} lifecycle API to track install / uninstall of a given {@link ITextViewer} for
+ * the given contribution which extends {@link ITextViewerLifecycle}:
+ *
+ *
+ * - {@link IReconciler}
+ * - {@link IPresentationReconciler}
+ * - {@link IHyperlinkPresenter}
+ * - {@link IInformationPresenter}
+ * - {@link IContentAssistant}
+ *
+ *
+ * It is possible too to implement {@link ITextViewerLifecycle} to track install / uninstall of a
+ * given {@link ITextViewer} for implementation of:
+ *
+ *
+ * - {@link IReconcilingStrategy}
+ * - {@link IAutoEditStrategy}
+ *
+ *
+ * @since 3.22
+ *
+ */
+public interface ITextViewerLifecycle {
+
+ /**
+ * Installs a text viewer. This method is called when
+ * {@link ISourceViewer#configure(org.eclipse.jface.text.source.SourceViewerConfiguration)} is
+ * called.
+ *
+ * @param textViewer the text viewer
+ */
+ void install(ITextViewer textViewer);
+
+ /**
+ * Uninstalls the registered text viewer. This method is called when
+ * {@link ISourceViewerExtension2#unconfigure()} is called.
+ */
+ void uninstall();
+}
diff --git a/org.eclipse.jface.text/src/org/eclipse/jface/text/contentassist/IContentAssistant.java b/org.eclipse.jface.text/src/org/eclipse/jface/text/contentassist/IContentAssistant.java
index f6954cda6..a6f76494a 100644
--- a/org.eclipse.jface.text/src/org/eclipse/jface/text/contentassist/IContentAssistant.java
+++ b/org.eclipse.jface.text/src/org/eclipse/jface/text/contentassist/IContentAssistant.java
@@ -14,6 +14,7 @@
package org.eclipse.jface.text.contentassist;
import org.eclipse.jface.text.ITextViewer;
+import org.eclipse.jface.text.ITextViewerLifecycle;
/**
@@ -76,7 +77,7 @@
* @see org.eclipse.jface.text.ITextViewer
* @see org.eclipse.jface.text.contentassist.IContentAssistProcessor
*/
- public interface IContentAssistant {
+public interface IContentAssistant extends ITextViewerLifecycle {
//------ proposal popup orientation styles ------------
/** The context info list will overlay the list of completion proposals. */
@@ -98,12 +99,14 @@ public interface IContentAssistant {
*
* @param textViewer the text viewer on which content assist will work
*/
+ @Override
void install(ITextViewer textViewer);
/**
* Uninstalls content assist support from the text viewer it has
* previously be installed on.
*/
+ @Override
void uninstall();
/**
diff --git a/org.eclipse.jface.text/src/org/eclipse/jface/text/hyperlink/IHyperlinkPresenter.java b/org.eclipse.jface.text/src/org/eclipse/jface/text/hyperlink/IHyperlinkPresenter.java
index f926faccd..5ea7d1bfb 100644
--- a/org.eclipse.jface.text/src/org/eclipse/jface/text/hyperlink/IHyperlinkPresenter.java
+++ b/org.eclipse.jface.text/src/org/eclipse/jface/text/hyperlink/IHyperlinkPresenter.java
@@ -14,6 +14,7 @@
package org.eclipse.jface.text.hyperlink;
import org.eclipse.jface.text.ITextViewer;
+import org.eclipse.jface.text.ITextViewerLifecycle;
/**
@@ -39,7 +40,7 @@
* @see IHyperlinkPresenterExtension2
* @since 3.1
*/
-public interface IHyperlinkPresenter {
+public interface IHyperlinkPresenter extends ITextViewerLifecycle {
/**
* Tells whether this presenter is able to handle
@@ -73,10 +74,12 @@ public interface IHyperlinkPresenter {
*
* @param textViewer the text viewer
*/
+ @Override
void install(ITextViewer textViewer);
/**
* Uninstalls this hyperlink presenter.
*/
+ @Override
void uninstall();
}
diff --git a/org.eclipse.jface.text/src/org/eclipse/jface/text/information/IInformationPresenter.java b/org.eclipse.jface.text/src/org/eclipse/jface/text/information/IInformationPresenter.java
index 2874e9ae1..263aae15e 100644
--- a/org.eclipse.jface.text/src/org/eclipse/jface/text/information/IInformationPresenter.java
+++ b/org.eclipse.jface.text/src/org/eclipse/jface/text/information/IInformationPresenter.java
@@ -14,6 +14,7 @@
package org.eclipse.jface.text.information;
import org.eclipse.jface.text.ITextViewer;
+import org.eclipse.jface.text.ITextViewerLifecycle;
/**
@@ -46,7 +47,7 @@
* @see org.eclipse.jface.text.information.IInformationProvider
* @since 2.0
*/
-public interface IInformationPresenter {
+public interface IInformationPresenter extends ITextViewerLifecycle {
/**
* Installs the information presenter on the given text viewer. After this method has been
@@ -55,12 +56,14 @@ public interface IInformationPresenter {
*
* @param textViewer the viewer on which the presenter is installed
*/
+ @Override
void install(ITextViewer textViewer);
/**
* Removes the information presenter from the text viewer it has previously been
* installed on.
*/
+ @Override
void uninstall();
/**
diff --git a/org.eclipse.jface.text/src/org/eclipse/jface/text/presentation/IPresentationReconciler.java b/org.eclipse.jface.text/src/org/eclipse/jface/text/presentation/IPresentationReconciler.java
index 222233ed5..03338a60d 100644
--- a/org.eclipse.jface.text/src/org/eclipse/jface/text/presentation/IPresentationReconciler.java
+++ b/org.eclipse.jface.text/src/org/eclipse/jface/text/presentation/IPresentationReconciler.java
@@ -15,6 +15,7 @@
import org.eclipse.jface.text.ITextViewer;
+import org.eclipse.jface.text.ITextViewerLifecycle;
/**
@@ -55,7 +56,7 @@
* @see org.eclipse.jface.text.presentation.IPresentationRepairer
* @see org.eclipse.jface.text.TextPresentation
*/
-public interface IPresentationReconciler {
+public interface IPresentationReconciler extends ITextViewerLifecycle {
/**
* Installs this presentation reconciler on the given text viewer. After
@@ -71,12 +72,14 @@ public interface IPresentationReconciler {
* @param viewer the viewer on which this presentation reconciler is
* installed
*/
+ @Override
void install(ITextViewer viewer);
/**
* Removes the reconciler from the text viewer it has previously been
* installed on.
*/
+ @Override
void uninstall();
/**
diff --git a/org.eclipse.jface.text/src/org/eclipse/jface/text/reconciler/IReconciler.java b/org.eclipse.jface.text/src/org/eclipse/jface/text/reconciler/IReconciler.java
index fc3fa2c32..06419f15c 100644
--- a/org.eclipse.jface.text/src/org/eclipse/jface/text/reconciler/IReconciler.java
+++ b/org.eclipse.jface.text/src/org/eclipse/jface/text/reconciler/IReconciler.java
@@ -14,6 +14,7 @@
package org.eclipse.jface.text.reconciler;
import org.eclipse.jface.text.ITextViewer;
+import org.eclipse.jface.text.ITextViewerLifecycle;
/**
@@ -47,7 +48,7 @@
* @see ITextViewer
* @see IReconcilingStrategy
*/
-public interface IReconciler {
+public interface IReconciler extends ITextViewerLifecycle {
/**
* Installs the reconciler on the given text viewer. After this method has been
@@ -56,12 +57,14 @@ public interface IReconciler {
*
* @param textViewer the viewer on which the reconciler is installed
*/
+ @Override
void install(ITextViewer textViewer);
/**
* Removes the reconciler from the text viewer it has
* previously been installed on.
*/
+ @Override
void uninstall();
/**
diff --git a/org.eclipse.jface.text/src/org/eclipse/jface/text/reconciler/MonoReconciler.java b/org.eclipse.jface.text/src/org/eclipse/jface/text/reconciler/MonoReconciler.java
index 176c6e1da..eba0502c4 100644
--- a/org.eclipse.jface.text/src/org/eclipse/jface/text/reconciler/MonoReconciler.java
+++ b/org.eclipse.jface.text/src/org/eclipse/jface/text/reconciler/MonoReconciler.java
@@ -17,6 +17,8 @@
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.jface.text.IDocument;
+import org.eclipse.jface.text.ITextViewer;
+import org.eclipse.jface.text.ITextViewerLifecycle;
import org.eclipse.jface.text.Region;
@@ -98,4 +100,20 @@ protected void initialProcess() {
extension.initialReconcile();
}
}
+
+ @Override
+ public void install(ITextViewer textViewer) {
+ super.install(textViewer);
+ if (fStrategy instanceof ITextViewerLifecycle) {
+ ((ITextViewerLifecycle) fStrategy).install(textViewer);
+ }
+ }
+
+ @Override
+ public void uninstall() {
+ if (fStrategy instanceof ITextViewerLifecycle) {
+ ((ITextViewerLifecycle) fStrategy).uninstall();
+ }
+ super.uninstall();
+ }
}
diff --git a/org.eclipse.jface.text/src/org/eclipse/jface/text/reconciler/Reconciler.java b/org.eclipse.jface.text/src/org/eclipse/jface/text/reconciler/Reconciler.java
index 4a7eea840..3cfbefc48 100644
--- a/org.eclipse.jface.text/src/org/eclipse/jface/text/reconciler/Reconciler.java
+++ b/org.eclipse.jface.text/src/org/eclipse/jface/text/reconciler/Reconciler.java
@@ -26,6 +26,8 @@
import org.eclipse.jface.text.IDocument;
import org.eclipse.jface.text.IDocumentExtension3;
import org.eclipse.jface.text.IRegion;
+import org.eclipse.jface.text.ITextViewer;
+import org.eclipse.jface.text.ITextViewerLifecycle;
import org.eclipse.jface.text.ITypedRegion;
import org.eclipse.jface.text.Region;
import org.eclipse.jface.text.TextUtilities;
@@ -161,6 +163,35 @@ protected void reconcilerDocumentChanged(IDocument document) {
}
}
+
+ @Override
+ public void install(ITextViewer textViewer) {
+ super.install(textViewer);
+ if (fStrategies != null) {
+ Iterator e= fStrategies.values().iterator();
+ while (e.hasNext()) {
+ IReconcilingStrategy strategy= e.next();
+ if (strategy instanceof ITextViewerLifecycle) {
+ ((ITextViewerLifecycle) strategy).install(textViewer);
+ }
+ }
+ }
+ }
+
+ @Override
+ public void uninstall() {
+ if (fStrategies != null) {
+ Iterator e= fStrategies.values().iterator();
+ while (e.hasNext()) {
+ IReconcilingStrategy strategy= e.next();
+ if (strategy instanceof ITextViewerLifecycle) {
+ ((ITextViewerLifecycle) strategy).uninstall();
+ }
+ }
+ }
+ super.uninstall();
+ }
+
@Override
public void setProgressMonitor(IProgressMonitor monitor) {
super.setProgressMonitor(monitor);
diff --git a/org.eclipse.jface.text/src/org/eclipse/jface/text/source/SourceViewer.java b/org.eclipse.jface.text/src/org/eclipse/jface/text/source/SourceViewer.java
index 85395bd7b..8a171acc9 100644
--- a/org.eclipse.jface.text/src/org/eclipse/jface/text/source/SourceViewer.java
+++ b/org.eclipse.jface.text/src/org/eclipse/jface/text/source/SourceViewer.java
@@ -17,7 +17,9 @@
*******************************************************************************/
package org.eclipse.jface.text.source;
+import java.util.HashSet;
import java.util.Iterator;
+import java.util.Set;
import java.util.Stack;
import org.eclipse.swt.SWT;
@@ -40,6 +42,7 @@
import org.eclipse.jface.text.BlockTextSelection;
import org.eclipse.jface.text.DocumentRewriteSession;
import org.eclipse.jface.text.DocumentRewriteSessionType;
+import org.eclipse.jface.text.IAutoEditStrategy;
import org.eclipse.jface.text.IBlockTextSelection;
import org.eclipse.jface.text.IDocument;
import org.eclipse.jface.text.IDocumentExtension4;
@@ -51,6 +54,7 @@
import org.eclipse.jface.text.ISynchronizable;
import org.eclipse.jface.text.ITextSelection;
import org.eclipse.jface.text.ITextViewerExtension2;
+import org.eclipse.jface.text.ITextViewerLifecycle;
import org.eclipse.jface.text.Position;
import org.eclipse.jface.text.Region;
import org.eclipse.jface.text.TextViewer;
@@ -89,8 +93,8 @@
*
* Clients may subclass this class but should expect some breakage by future releases.
*/
-public class SourceViewer extends TextViewer implements ISourceViewer, ISourceViewerExtension, ISourceViewerExtension2, ISourceViewerExtension3, ISourceViewerExtension4, ISourceViewerExtension5 {
-
+public class SourceViewer extends TextViewer
+ implements ISourceViewer, ISourceViewerExtension, ISourceViewerExtension2, ISourceViewerExtension3, ISourceViewerExtension4, ISourceViewerExtension5 {
/**
* Layout of a source viewer. Vertical ruler, text widget, and overview ruler are shown side by side.
@@ -389,6 +393,8 @@ private int[] computeScrollArrowHeights(StyledText textWidget, int bottomOffset)
*/
private CodeMiningManager fCodeMiningManager;
+ private final Set lifecycles;
+
/**
* Constructs a new source viewer. The vertical ruler is initially visible.
* The viewer has not yet been initialized with a source viewer configuration.
@@ -422,7 +428,7 @@ public SourceViewer(Composite parent, IVerticalRuler verticalRuler, IOverviewRul
fIsVerticalRulerVisible= (verticalRuler != null);
fOverviewRuler= overviewRuler;
fIsOverviewRulerVisible= (showAnnotationsOverview && overviewRuler != null);
-
+ this.lifecycles= new HashSet<>();
createControl(parent, styles);
}
@@ -490,16 +496,14 @@ public void configure(SourceViewerConfiguration configuration) {
// install content type independent plug-ins
fPresentationReconciler= configuration.getPresentationReconciler(this);
- if (fPresentationReconciler != null)
- fPresentationReconciler.install(this);
+ addTextViewerLifecycle(fPresentationReconciler);
fReconciler= configuration.getReconciler(this);
- if (fReconciler != null)
- fReconciler.install(this);
+ addTextViewerLifecycle(fReconciler);
fContentAssistant= configuration.getContentAssistant(this);
+ addTextViewerLifecycle(fContentAssistant);
if (fContentAssistant != null) {
- fContentAssistant.install(this);
if (fContentAssistant instanceof IContentAssistantExtension2 && fContentAssistant instanceof IContentAssistantExtension4)
fContentAssistantFacade= new ContentAssistantFacade(fContentAssistant);
fContentAssistantInstalled= true;
@@ -514,8 +518,7 @@ public void configure(SourceViewerConfiguration configuration) {
fContentFormatter= configuration.getContentFormatter(this);
fInformationPresenter= configuration.getInformationPresenter(this);
- if (fInformationPresenter != null)
- fInformationPresenter.install(this);
+ addTextViewerLifecycle(fInformationPresenter);
setUndoManager(configuration.getUndoManager(this));
@@ -535,7 +538,7 @@ public void configure(SourceViewerConfiguration configuration) {
String[] types= configuration.getConfiguredContentTypes(this);
for (String t : types) {
- setAutoEditStrategies(configuration.getAutoEditStrategies(this, t), t);
+ doSetAutoEditStrategies(configuration.getAutoEditStrategies(this, t), t);
setTextDoubleClickStrategy(configuration.getDoubleClickStrategy(this, t), t);
int[] stateMasks= configuration.getConfiguredTextHoverStateMasks(this, t);
@@ -556,10 +559,21 @@ public void configure(SourceViewerConfiguration configuration) {
setDefaultPrefixes(prefixes, t);
}
setCodeMiningProviders(configuration.getCodeMiningProviders(this));
-
+ installTextViewer();
activatePlugins();
}
+ private void doSetAutoEditStrategies(IAutoEditStrategy[] strategies, String contentType) {
+ super.setAutoEditStrategies(strategies, contentType);
+ if (strategies != null) {
+ for (IAutoEditStrategy strategy : strategies) {
+ if (strategy instanceof ITextViewerLifecycle) {
+ addTextViewerLifecycle((ITextViewerLifecycle) strategy);
+ }
+ }
+ }
+ }
+
/**
* After this method has been executed the caller knows that any installed annotation hover has been installed.
*/
@@ -710,18 +724,11 @@ public IAnnotationModel getVisualAnnotationModel() {
public void unconfigure() {
clearRememberedSelection();
- if (fPresentationReconciler != null) {
- fPresentationReconciler.uninstall();
- fPresentationReconciler= null;
- }
-
- if (fReconciler != null) {
- fReconciler.uninstall();
- fReconciler= null;
- }
+ uninstallTextViewer();
+ fPresentationReconciler= null;
+ fReconciler= null;
if (fContentAssistant != null) {
- fContentAssistant.uninstall();
fContentAssistantInstalled= false;
fContentAssistant= null;
if (fContentAssistantFacade != null)
@@ -1320,4 +1327,23 @@ public void setCodeMiningAnnotationPainter(AnnotationPainter painter) {
ensureCodeMiningManagerInstalled();
}
+ private void addTextViewerLifecycle(ITextViewerLifecycle lifecycle) {
+ if (lifecycle != null) {
+ lifecycles.add(lifecycle);
+ }
+ }
+
+ private void installTextViewer() {
+ for (ITextViewerLifecycle lifecycle : lifecycles) {
+ lifecycle.install(this);
+ }
+ }
+
+ private void uninstallTextViewer() {
+ for (ITextViewerLifecycle lifecycle : lifecycles) {
+ lifecycle.uninstall();
+ }
+ lifecycles.clear();
+ }
+
}
diff --git a/org.eclipse.ui.genericeditor/src/org/eclipse/ui/internal/genericeditor/CompositeReconcilerStrategy.java b/org.eclipse.ui.genericeditor/src/org/eclipse/ui/internal/genericeditor/CompositeReconcilerStrategy.java
index bdd731c35..2c50ac3ad 100644
--- a/org.eclipse.ui.genericeditor/src/org/eclipse/ui/internal/genericeditor/CompositeReconcilerStrategy.java
+++ b/org.eclipse.ui.genericeditor/src/org/eclipse/ui/internal/genericeditor/CompositeReconcilerStrategy.java
@@ -18,52 +18,74 @@
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.jface.text.IDocument;
import org.eclipse.jface.text.IRegion;
+import org.eclipse.jface.text.ITextViewer;
+import org.eclipse.jface.text.ITextViewerLifecycle;
import org.eclipse.jface.text.reconciler.DirtyRegion;
import org.eclipse.jface.text.reconciler.IReconcilingStrategy;
import org.eclipse.jface.text.reconciler.IReconcilingStrategyExtension;
-public class CompositeReconcilerStrategy implements IReconcilingStrategy, IReconcilingStrategyExtension{
+public class CompositeReconcilerStrategy
+ implements IReconcilingStrategy, IReconcilingStrategyExtension, ITextViewerLifecycle {
private List fReconcilingStrategies;
public CompositeReconcilerStrategy(List strategies) {
this.fReconcilingStrategies = strategies;
}
+
@Override
public void setProgressMonitor(IProgressMonitor monitor) {
- for (IReconcilingStrategy iReconcilingStrategy : fReconcilingStrategies) {
- if (iReconcilingStrategy instanceof IReconcilingStrategyExtension) {
- ((IReconcilingStrategyExtension) iReconcilingStrategy).setProgressMonitor(monitor);
+ for (IReconcilingStrategy strategy : fReconcilingStrategies) {
+ if (strategy instanceof IReconcilingStrategyExtension) {
+ ((IReconcilingStrategyExtension) strategy).setProgressMonitor(monitor);
}
}
}
@Override
public void initialReconcile() {
- for (IReconcilingStrategy iReconcilingStrategy : fReconcilingStrategies) {
- if (iReconcilingStrategy instanceof IReconcilingStrategyExtension) {
- ((IReconcilingStrategyExtension) iReconcilingStrategy).initialReconcile();
+ for (IReconcilingStrategy strategy : fReconcilingStrategies) {
+ if (strategy instanceof IReconcilingStrategyExtension) {
+ ((IReconcilingStrategyExtension) strategy).initialReconcile();
}
}
}
@Override
public void setDocument(IDocument document) {
- for (IReconcilingStrategy iReconcilingStrategy : fReconcilingStrategies) {
- iReconcilingStrategy.setDocument(document);
+ for (IReconcilingStrategy strategy : fReconcilingStrategies) {
+ strategy.setDocument(document);
}
}
@Override
public void reconcile(DirtyRegion dirtyRegion, IRegion subRegion) {
- for (IReconcilingStrategy iReconcilingStrategy : fReconcilingStrategies) {
- iReconcilingStrategy.reconcile(dirtyRegion, subRegion);
+ for (IReconcilingStrategy strategy : fReconcilingStrategies) {
+ strategy.reconcile(dirtyRegion, subRegion);
}
}
@Override
public void reconcile(IRegion partition) {
- for (IReconcilingStrategy iReconcilingStrategy : fReconcilingStrategies) {
- iReconcilingStrategy.reconcile(partition);
+ for (IReconcilingStrategy strategy : fReconcilingStrategies) {
+ strategy.reconcile(partition);
+ }
+ }
+
+ @Override
+ public void install(ITextViewer textViewer) {
+ for (IReconcilingStrategy strategy : fReconcilingStrategies) {
+ if (strategy instanceof ITextViewerLifecycle) {
+ ((ITextViewerLifecycle) strategy).install(textViewer);
+ }
+ }
+ }
+
+ @Override
+ public void uninstall() {
+ for (IReconcilingStrategy strategy : fReconcilingStrategies) {
+ if (strategy instanceof ITextViewerLifecycle) {
+ ((ITextViewerLifecycle) strategy).uninstall();
+ }
}
}