stickyLinesProviders
extension point.
+ *
+ * @noextend This class is not intended to be extended by clients.
+ */
+class StickyLinesProviderDescriptor {
+ /** Name of the class
attribute. */
+ private static final String CLASS_ATTRIBUTE= "class"; //$NON-NLS-1$
+
+ /** Name of the id
attribute. */
+ private static final String ID_ATTRIBUTE= "id"; //$NON-NLS-1$
+
+ /** Name of the enabledWhen
attribute. **/
+ private static final String ENABLED_WHEN_ATTR= "enabledWhen"; //$NON-NLS-1$
+
+ /** The configuration element describing this extension. */
+ private IConfigurationElement configuration;
+
+ /** The value of the id
attribute, if read. */
+ private String id;
+
+ /** The expression value of the enabledWhen
attribute. */
+ private final Expression enabledWhen;
+
+ /**
+ * Creates a new descriptor for element
.
+ * + * This method is for internal use only. + *
+ * + * @param element the extension point element to be described. + * @throws CoreException whenenabledWhen
expression is not valid.
+ */
+ public StickyLinesProviderDescriptor(IConfigurationElement element) throws CoreException {
+ Assert.isLegal(element != null);
+ configuration= element;
+ enabledWhen= createEnabledWhen(configuration, getId());
+ }
+
+ /**
+ * Returns the expression {@link Expression} declared in the enabledWhen
element.
+ *
+ * @param configElement the configuration element
+ * @param id the id of the sticky lines provider.
+ * @return the expression {@link Expression} declared in the enabledWhen element.
+ * @throws CoreException when enabledWhen expression is not valid.
+ */
+ private static Expression createEnabledWhen(IConfigurationElement configElement, String id) throws CoreException {
+ final IConfigurationElement[] children= configElement.getChildren(ENABLED_WHEN_ATTR);
+ if (children.length > 0) {
+ IConfigurationElement[] subChildren= children[0].getChildren();
+ if (subChildren.length != 1) {
+ throw new CoreException(new Status(IStatus.ERROR, EditorsUI.PLUGIN_ID,
+ "One "stickyLinesProviders"
).
+ */
+ public static final String STICKY_LINES_PROVIDERS_EXTENSION_POINT = "stickyLinesProviders"; //$NON-NLS-1$
+
+ /** All descriptors */
+ private StickyLinesProviderDescriptor[] fDescriptors;
+
+ /** true
if the extensions have been loaded at least once */
+ private boolean fLoaded = false;
+
+ private IExtensionRegistry fExtensionRegistry;
+
+ private StickyLinesProviderDescriptorFactory descriptorFactory;
+
+ public StickyLinesProviderRegistry() {
+ this(Platform.getExtensionRegistry(), element -> new StickyLinesProviderDescriptor(element));
+ }
+
+ public StickyLinesProviderRegistry(IExtensionRegistry extensionRegistry,
+ StickyLinesProviderDescriptorFactory StickyLinesProviderDescriptorFactory) {
+ fExtensionRegistry = extensionRegistry;
+ this.descriptorFactory = StickyLinesProviderDescriptorFactory;
+ }
+
+ /**
+ * Returns the sticky lines providers for the given viewer and editor. If no
+ * specific provider is registered, a {@link DefaultStickyLinesProvider} is
+ * returned.
+ *
+ * @param viewer the viewer
+ * @param editor the editor
+ * @return the sticky lines providers for the given viewer and editor and a
+ * default provider otherwise.
+ */
+ public IStickyLinesProvider getProvider(ISourceViewer viewer, ITextEditor editor) {
+ for (StickyLinesProviderDescriptor descriptor : getDescriptors()) {
+ if (descriptor.matches(viewer, editor)) {
+ IStickyLinesProvider provider = descriptor.createStickyLinesProvider();
+ if (provider != null) {
+ return provider;
+ }
+ }
+ }
+ return new DefaultStickyLinesProvider();
+ }
+
+ /**
+ * Returns all descriptors.
+ *
+ * @return all descriptors
+ */
+ private StickyLinesProviderDescriptor[] getDescriptors() {
+ ensureExtensionsLoaded();
+ return fDescriptors;
+ }
+
+ /**
+ * Reads all extensions.
+ * + * This method can be called more than once in order to reload from a changed + * extension registry. + *
+ */ + public synchronized void reloadExtensions() { + List@@ -931,7 +939,8 @@ protected void handlePreferenceStoreChanged(PropertyChangeEvent event) { return; if (store.getBoolean(AbstractDecoratedTextEditorPreferenceConstants.EDITOR_STICKY_SCROLLING_ENABLED)) { - fStickyScrollingHandler= new StickyScrollingHandler(getSourceViewer(), getVerticalRuler(), store); + IStickyLinesProvider stickyLineProvider= getStickyLinesProvider(); + fStickyScrollingHandler= new StickyScrollingHandler(getSourceViewer(), getVerticalRuler(), getPreferenceStore(), stickyLineProvider, this); //fire once fStickyScrollingHandler.viewportChanged(getSourceViewer().getTextWidget().getTopPixel()); } else { diff --git a/bundles/org.eclipse.ui.editors/src/org/eclipse/ui/internal/texteditor/stickyscroll/IStickyLine.java b/bundles/org.eclipse.ui.editors/src/org/eclipse/ui/texteditor/stickyscroll/IStickyLine.java similarity index 94% rename from bundles/org.eclipse.ui.editors/src/org/eclipse/ui/internal/texteditor/stickyscroll/IStickyLine.java rename to bundles/org.eclipse.ui.editors/src/org/eclipse/ui/texteditor/stickyscroll/IStickyLine.java index 33e54dc9cc6..c715c9286fe 100644 --- a/bundles/org.eclipse.ui.editors/src/org/eclipse/ui/internal/texteditor/stickyscroll/IStickyLine.java +++ b/bundles/org.eclipse.ui.editors/src/org/eclipse/ui/texteditor/stickyscroll/IStickyLine.java @@ -11,12 +11,14 @@ * Contributors: * SAP SE - initial API and implementation *******************************************************************************/ -package org.eclipse.ui.internal.texteditor.stickyscroll; +package org.eclipse.ui.texteditor.stickyscroll; import org.eclipse.swt.custom.StyleRange; /** * Representation of a sticky line. + * + * since 3.20 */ public interface IStickyLine { diff --git a/bundles/org.eclipse.ui.editors/src/org/eclipse/ui/internal/texteditor/stickyscroll/IStickyLinesProvider.java b/bundles/org.eclipse.ui.editors/src/org/eclipse/ui/texteditor/stickyscroll/IStickyLinesProvider.java similarity index 85% rename from bundles/org.eclipse.ui.editors/src/org/eclipse/ui/internal/texteditor/stickyscroll/IStickyLinesProvider.java rename to bundles/org.eclipse.ui.editors/src/org/eclipse/ui/texteditor/stickyscroll/IStickyLinesProvider.java index cb677202fca..44a0e116892 100644 --- a/bundles/org.eclipse.ui.editors/src/org/eclipse/ui/internal/texteditor/stickyscroll/IStickyLinesProvider.java +++ b/bundles/org.eclipse.ui.editors/src/org/eclipse/ui/texteditor/stickyscroll/IStickyLinesProvider.java @@ -11,17 +11,19 @@ * Contributors: * SAP SE - initial API and implementation *******************************************************************************/ -package org.eclipse.ui.internal.texteditor.stickyscroll; +package org.eclipse.ui.texteditor.stickyscroll; import java.util.List; import org.eclipse.jface.text.source.ISourceViewer; +import org.eclipse.ui.IEditorPart; + /** * A sticky lines provider calculates the sticky lines for a given source viewer. The sticky lines * will be displayed in the top area of the editor. * - * TODO move to public package and add since 3.19 + * since 3.20 TODO: version bump in extra commit */ public interface IStickyLinesProvider { @@ -42,8 +44,9 @@ public interface IStickyLinesProvider { * Additional properties and access in order to calculate the sticky lines. * * @param tabWith The with of a tab + * @param editor The editor for which the sticky lines should be provided */ - record StickyLinesProperties(int tabWith) { + record StickyLinesProperties(int tabWith, IEditorPart editor) { } } diff --git a/bundles/org.eclipse.ui.editors/src/org/eclipse/ui/internal/texteditor/stickyscroll/StickyLine.java b/bundles/org.eclipse.ui.editors/src/org/eclipse/ui/texteditor/stickyscroll/StickyLine.java similarity index 71% rename from bundles/org.eclipse.ui.editors/src/org/eclipse/ui/internal/texteditor/stickyscroll/StickyLine.java rename to bundles/org.eclipse.ui.editors/src/org/eclipse/ui/texteditor/stickyscroll/StickyLine.java index 3533ad07c22..7488a28dcf5 100644 --- a/bundles/org.eclipse.ui.editors/src/org/eclipse/ui/internal/texteditor/stickyscroll/StickyLine.java +++ b/bundles/org.eclipse.ui.editors/src/org/eclipse/ui/texteditor/stickyscroll/StickyLine.java @@ -11,7 +11,7 @@ * Contributors: * SAP SE - initial API and implementation *******************************************************************************/ -package org.eclipse.ui.internal.texteditor.stickyscroll; +package org.eclipse.ui.texteditor.stickyscroll; import org.eclipse.swt.custom.StyleRange; import org.eclipse.swt.custom.StyledText; @@ -20,8 +20,10 @@ import org.eclipse.jface.text.source.ISourceViewer; /** - * Default implementation of {@link IStickyLine}. Information about the text and style ranges are - * calculated from the given text widget. + * Default implementation of {@link IStickyLine}. Information about the text and + * style ranges are calculated from the given text widget. + * + * since 3.20 */ public class StickyLine implements IStickyLine { @@ -32,8 +34,8 @@ public class StickyLine implements IStickyLine { protected ISourceViewer sourceViewer; public StickyLine(int lineNumber, ISourceViewer sourceViewer) { - this.lineNumber= lineNumber; - this.sourceViewer= sourceViewer; + this.lineNumber = lineNumber; + this.sourceViewer = sourceViewer; } @Override @@ -44,19 +46,19 @@ public int getLineNumber() { @Override public String getText() { if (text == null) { - StyledText textWidget= sourceViewer.getTextWidget(); - text= textWidget.getLine(getWidgetLineNumber()); + StyledText textWidget = sourceViewer.getTextWidget(); + text = textWidget.getLine(getWidgetLineNumber()); } return text; } @Override public StyleRange[] getStyleRanges() { - StyledText textWidget= sourceViewer.getTextWidget(); - int offsetAtLine= textWidget.getOffsetAtLine(getWidgetLineNumber()); - StyleRange[] styleRanges= textWidget.getStyleRanges(offsetAtLine, getText().length()); + StyledText textWidget = sourceViewer.getTextWidget(); + int offsetAtLine = textWidget.getOffsetAtLine(getWidgetLineNumber()); + StyleRange[] styleRanges = textWidget.getStyleRanges(offsetAtLine, getText().length()); for (StyleRange styleRange : styleRanges) { - styleRange.start= styleRange.start - offsetAtLine; + styleRange.start = styleRange.start - offsetAtLine; } return styleRanges; } diff --git a/tests/org.eclipse.ui.editors.tests/src/org/eclipse/ui/editors/tests/EditorsTestSuite.java b/tests/org.eclipse.ui.editors.tests/src/org/eclipse/ui/editors/tests/EditorsTestSuite.java index 5bea44de374..65c6adde4a3 100644 --- a/tests/org.eclipse.ui.editors.tests/src/org/eclipse/ui/editors/tests/EditorsTestSuite.java +++ b/tests/org.eclipse.ui.editors.tests/src/org/eclipse/ui/editors/tests/EditorsTestSuite.java @@ -22,9 +22,12 @@ import org.eclipse.jface.text.tests.codemining.CodeMiningTest; import org.eclipse.ui.internal.texteditor.stickyscroll.DefaultStickyLinesProviderTest; +import org.eclipse.ui.internal.texteditor.stickyscroll.StickyLinesProviderRegistryTest; import org.eclipse.ui.internal.texteditor.stickyscroll.StickyScrollingControlTest; import org.eclipse.ui.internal.texteditor.stickyscroll.StickyScrollingHandlerTest; +import org.eclipse.ui.texteditor.stickyscroll.StickyLineTest; + /** * Test Suite for org.eclipse.ui.editors. * @@ -51,6 +54,8 @@ StickyScrollingControlTest.class, StickyScrollingHandlerTest.class, DefaultStickyLinesProviderTest.class, + StickyLineTest.class, + StickyLinesProviderRegistryTest.class, CodeMiningTest.class, }) diff --git a/tests/org.eclipse.ui.editors.tests/src/org/eclipse/ui/internal/texteditor/stickyscroll/DefaultStickyLinesProviderTest.java b/tests/org.eclipse.ui.editors.tests/src/org/eclipse/ui/internal/texteditor/stickyscroll/DefaultStickyLinesProviderTest.java index 8aaf61e0310..87102871347 100644 --- a/tests/org.eclipse.ui.editors.tests/src/org/eclipse/ui/internal/texteditor/stickyscroll/DefaultStickyLinesProviderTest.java +++ b/tests/org.eclipse.ui.editors.tests/src/org/eclipse/ui/internal/texteditor/stickyscroll/DefaultStickyLinesProviderTest.java @@ -17,6 +17,7 @@ import static org.hamcrest.Matchers.empty; import static org.hamcrest.Matchers.is; import static org.junit.Assert.assertEquals; +import static org.mockito.Mockito.mock; import java.util.List; @@ -35,7 +36,10 @@ import org.eclipse.jface.text.source.IVerticalRuler; import org.eclipse.jface.text.source.SourceViewer; -import org.eclipse.ui.internal.texteditor.stickyscroll.IStickyLinesProvider.StickyLinesProperties; +import org.eclipse.ui.IEditorPart; + +import org.eclipse.ui.texteditor.stickyscroll.IStickyLine; +import org.eclipse.ui.texteditor.stickyscroll.IStickyLinesProvider.StickyLinesProperties; public class DefaultStickyLinesProviderTest { @@ -44,6 +48,7 @@ public class DefaultStickyLinesProviderTest { private DefaultStickyLinesProvider stickyLinesProvider; private StyledText textWidget; private StickyLinesProperties stickyLinesProperties; + private IEditorPart editorPart; @Before public void setup() { @@ -52,7 +57,8 @@ public void setup() { sourceViewer.setDocument(new Document()); stickyLinesProvider = new DefaultStickyLinesProvider(); textWidget = sourceViewer.getTextWidget(); - stickyLinesProperties = new StickyLinesProperties(4); + editorPart = mock(IEditorPart.class); + stickyLinesProperties = new StickyLinesProperties(4, editorPart); } @Test @@ -125,7 +131,7 @@ public void testIgnoreEmptyLines() { @Test public void testLinesWithTabs() { - stickyLinesProperties = new StickyLinesProperties(2); + stickyLinesProperties = new StickyLinesProperties(2, editorPart); String text = """ line 1 \tline 2 diff --git a/tests/org.eclipse.ui.editors.tests/src/org/eclipse/ui/internal/texteditor/stickyscroll/StickyLinesProviderRegistryTest.java b/tests/org.eclipse.ui.editors.tests/src/org/eclipse/ui/internal/texteditor/stickyscroll/StickyLinesProviderRegistryTest.java new file mode 100644 index 00000000000..165647e49bb --- /dev/null +++ b/tests/org.eclipse.ui.editors.tests/src/org/eclipse/ui/internal/texteditor/stickyscroll/StickyLinesProviderRegistryTest.java @@ -0,0 +1,63 @@ +package org.eclipse.ui.internal.texteditor.stickyscroll; + +import static org.eclipse.ui.editors.text.EditorsUI.PLUGIN_ID; +import static org.eclipse.ui.internal.texteditor.stickyscroll.StickyLinesProviderRegistry.STICKY_LINES_PROVIDERS_EXTENSION_POINT; +import static org.hamcrest.MatcherAssert.assertThat; +import static org.hamcrest.Matchers.instanceOf; +import static org.hamcrest.Matchers.is; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.when; + +import org.junit.Before; +import org.junit.Test; + +import org.eclipse.core.runtime.IConfigurationElement; +import org.eclipse.core.runtime.IExtensionRegistry; + +import org.eclipse.jface.text.source.ISourceViewer; + +import org.eclipse.ui.texteditor.ITextEditor; +import org.eclipse.ui.texteditor.stickyscroll.IStickyLinesProvider; + +public class StickyLinesProviderRegistryTest { + + private StickyLinesProviderDescriptor stickyLinesProviderDescriptor; + private StickyLinesProviderRegistry cut; + private ISourceViewer viewer; + private ITextEditor editor; + + @Before + public void setup() { + IConfigurationElement[] configurationElement = { mock(IConfigurationElement.class) }; + stickyLinesProviderDescriptor = mock(StickyLinesProviderDescriptor.class); + viewer = mock(ISourceViewer.class); + editor = mock(ITextEditor.class); + + IExtensionRegistry extensionRegistry = mock(IExtensionRegistry.class); + when(extensionRegistry.getConfigurationElementsFor(PLUGIN_ID, STICKY_LINES_PROVIDERS_EXTENSION_POINT)) + .thenReturn(configurationElement); + + cut = new StickyLinesProviderRegistry(extensionRegistry, e -> stickyLinesProviderDescriptor); + } + + @Test + public void testGetDefaultProviderIfNoMatch() { + when(stickyLinesProviderDescriptor.matches(viewer, editor)).thenReturn(false); + + IStickyLinesProvider provider = cut.getProvider(viewer, editor); + + assertThat(provider, instanceOf(DefaultStickyLinesProvider.class)); + } + + @Test + public void testGetProviderForMatch() { + IStickyLinesProvider expProvider = mock(IStickyLinesProvider.class); + when(stickyLinesProviderDescriptor.matches(viewer, editor)).thenReturn(true); + when(stickyLinesProviderDescriptor.createStickyLinesProvider()).thenReturn(expProvider); + + IStickyLinesProvider provider = cut.getProvider(viewer, editor); + + assertThat(provider, is(expProvider)); + } + +} diff --git a/tests/org.eclipse.ui.editors.tests/src/org/eclipse/ui/internal/texteditor/stickyscroll/StickyScrollingControlTest.java b/tests/org.eclipse.ui.editors.tests/src/org/eclipse/ui/internal/texteditor/stickyscroll/StickyScrollingControlTest.java index 4b8e63506de..c8d5faa1bad 100644 --- a/tests/org.eclipse.ui.editors.tests/src/org/eclipse/ui/internal/texteditor/stickyscroll/StickyScrollingControlTest.java +++ b/tests/org.eclipse.ui.editors.tests/src/org/eclipse/ui/internal/texteditor/stickyscroll/StickyScrollingControlTest.java @@ -46,6 +46,8 @@ import org.eclipse.jface.text.source.IVerticalRuler; import org.eclipse.jface.text.source.SourceViewer; +import org.eclipse.ui.texteditor.stickyscroll.IStickyLine; + public class StickyScrollingControlTest { private Shell shell; diff --git a/tests/org.eclipse.ui.editors.tests/src/org/eclipse/ui/internal/texteditor/stickyscroll/StickyScrollingHandlerTest.java b/tests/org.eclipse.ui.editors.tests/src/org/eclipse/ui/internal/texteditor/stickyscroll/StickyScrollingHandlerTest.java index 0856c70b19e..24bd8d9ce04 100644 --- a/tests/org.eclipse.ui.editors.tests/src/org/eclipse/ui/internal/texteditor/stickyscroll/StickyScrollingHandlerTest.java +++ b/tests/org.eclipse.ui.editors.tests/src/org/eclipse/ui/internal/texteditor/stickyscroll/StickyScrollingHandlerTest.java @@ -53,7 +53,11 @@ import org.eclipse.jface.text.source.CompositeRuler; import org.eclipse.jface.text.source.SourceViewer; -import org.eclipse.ui.internal.texteditor.stickyscroll.IStickyLinesProvider.StickyLinesProperties; +import org.eclipse.ui.IEditorPart; + +import org.eclipse.ui.texteditor.stickyscroll.IStickyLine; +import org.eclipse.ui.texteditor.stickyscroll.IStickyLinesProvider; +import org.eclipse.ui.texteditor.stickyscroll.IStickyLinesProvider.StickyLinesProperties; public class StickyScrollingHandlerTest { @@ -67,6 +71,7 @@ public class StickyScrollingHandlerTest { private StickyScrollingHandler stickyScrollingHandler; private StickyLinesProperties stickyLinesProperties; private StyledText textWidget; + private IEditorPart editorPart; @Before public void setup() { @@ -79,6 +84,7 @@ public void setup() { textWidget = sourceViewer.getTextWidget(); textWidget.setText("first 1 \nline 2 \nline 3 \nline 4 \nline 5 \nline 6 \nline 7 \nline 8 \nline 9 \nline 10"); textWidget.setTopIndex(1); + editorPart = mock(IEditorPart.class); lineNumberColor = new Color(0, 0, 0); hoverColor = new Color(1, 1, 1); @@ -86,8 +92,8 @@ public void setup() { store = createPreferenceStore(); linesProvider = mock(IStickyLinesProvider.class); - stickyScrollingHandler = new StickyScrollingHandler(sourceViewer, ruler, store, linesProvider); - stickyLinesProperties = new StickyLinesProperties(4); + stickyScrollingHandler = new StickyScrollingHandler(sourceViewer, ruler, store, linesProvider, editorPart); + stickyLinesProperties = new StickyLinesProperties(4, editorPart); } @After diff --git a/tests/org.eclipse.ui.editors.tests/src/org/eclipse/ui/internal/texteditor/stickyscroll/StickyLineTest.java b/tests/org.eclipse.ui.editors.tests/src/org/eclipse/ui/texteditor/stickyscroll/StickyLineTest.java similarity index 98% rename from tests/org.eclipse.ui.editors.tests/src/org/eclipse/ui/internal/texteditor/stickyscroll/StickyLineTest.java rename to tests/org.eclipse.ui.editors.tests/src/org/eclipse/ui/texteditor/stickyscroll/StickyLineTest.java index 99ee26000f0..0f85d861ba8 100644 --- a/tests/org.eclipse.ui.editors.tests/src/org/eclipse/ui/internal/texteditor/stickyscroll/StickyLineTest.java +++ b/tests/org.eclipse.ui.editors.tests/src/org/eclipse/ui/texteditor/stickyscroll/StickyLineTest.java @@ -11,7 +11,7 @@ * Contributors: * SAP SE - initial API and implementation *******************************************************************************/ -package org.eclipse.ui.internal.texteditor.stickyscroll; +package org.eclipse.ui.texteditor.stickyscroll; import static org.junit.Assert.assertEquals;