From 683eaf9347d21ed67d56ccd7b59932025cf40018 Mon Sep 17 00:00:00 2001 From: Marcus Hoepfner Date: Tue, 19 Dec 2023 16:37:43 +0100 Subject: [PATCH 01/13] Show ZWSP (zero with space) as code mining Issue: https://github.com/eclipse-platform/eclipse.platform.ui/issues/1002 For more information refer to https://www.compart.com/en/unicode/U+200B To get a ZWSP refer to https://zerowidthspace.me/ --- .../TextEditorDefaultsPreferencePage.java | 17 +++- .../editors/text/TextEditorMessages.java | 1 + .../text/TextEditorMessages.properties | 1 + ...ecoratedTextEditorPreferenceConstants.java | 17 +++- .../plugin.properties | 2 + .../plugin.xml | 10 +- .../ZeroWidthSpaceLineContentCodeMining.java | 37 +++++++ ...dthSpaceLineContentCodeMiningProvider.java | 97 +++++++++++++++++++ .../ui/texteditor/AbstractTextEditor.java | 15 ++- 9 files changed, 192 insertions(+), 5 deletions(-) create mode 100644 bundles/org.eclipse.ui.workbench.texteditor/src/org/eclipse/ui/internal/texteditor/codemining/ZeroWidthSpaceLineContentCodeMining.java create mode 100644 bundles/org.eclipse.ui.workbench.texteditor/src/org/eclipse/ui/internal/texteditor/codemining/ZeroWidthSpaceLineContentCodeMiningProvider.java diff --git a/bundles/org.eclipse.ui.editors/src/org/eclipse/ui/internal/editors/text/TextEditorDefaultsPreferencePage.java b/bundles/org.eclipse.ui.editors/src/org/eclipse/ui/internal/editors/text/TextEditorDefaultsPreferencePage.java index 0c2f05e44c1f..01b1a5c67144 100644 --- a/bundles/org.eclipse.ui.editors/src/org/eclipse/ui/internal/editors/text/TextEditorDefaultsPreferencePage.java +++ b/bundles/org.eclipse.ui.editors/src/org/eclipse/ui/internal/editors/text/TextEditorDefaultsPreferencePage.java @@ -68,6 +68,8 @@ import org.eclipse.jface.viewers.SelectionChangedEvent; import org.eclipse.jface.viewers.StructuredSelection; import org.eclipse.jface.viewers.TableViewer; +import org.eclipse.jface.widgets.ButtonFactory; +import org.eclipse.jface.widgets.WidgetFactory; import org.eclipse.ui.IWorkbench; import org.eclipse.ui.IWorkbenchPreferencePage; @@ -451,7 +453,9 @@ private OverlayPreferenceStore createDialogOverlayStore() { overlayKeys.add(new OverlayPreferenceStore.OverlayKey(OverlayPreferenceStore.BOOLEAN, AbstractDecoratedTextEditorPreferenceConstants.EDITOR_SHOW_ENCLOSED_TABS)); overlayKeys.add(new OverlayPreferenceStore.OverlayKey(OverlayPreferenceStore.BOOLEAN, AbstractDecoratedTextEditorPreferenceConstants.EDITOR_SHOW_TRAILING_TABS)); overlayKeys.add(new OverlayPreferenceStore.OverlayKey(OverlayPreferenceStore.BOOLEAN, AbstractDecoratedTextEditorPreferenceConstants.EDITOR_SHOW_CARRIAGE_RETURN)); - overlayKeys.add(new OverlayPreferenceStore.OverlayKey(OverlayPreferenceStore.BOOLEAN, AbstractDecoratedTextEditorPreferenceConstants.EDITOR_SHOW_LINE_FEED)); + overlayKeys.add(new OverlayPreferenceStore.OverlayKey(OverlayPreferenceStore.BOOLEAN, AbstractDecoratedTextEditorPreferenceConstants.EDITOR_SHOW_LINE_FEED)); + overlayKeys.add(new OverlayPreferenceStore.OverlayKey(OverlayPreferenceStore.BOOLEAN, + AbstractDecoratedTextEditorPreferenceConstants.EDITOR_SHOW_ZWSP)); overlayKeys.add(new OverlayPreferenceStore.OverlayKey(OverlayPreferenceStore.INT, AbstractDecoratedTextEditorPreferenceConstants.EDITOR_WHITESPACE_CHARACTER_ALPHA_VALUE)); OverlayPreferenceStore.OverlayKey[] keys= new OverlayPreferenceStore.OverlayKey[overlayKeys.size()]; @@ -571,6 +575,15 @@ protected Control createDialogArea(Composite parent) { preference= new Preference(AbstractDecoratedTextEditorPreferenceConstants.EDITOR_SHOW_LINE_FEED, "", null); //$NON-NLS-1$ addCheckBox(tabularComposite, preference, new BooleanDomain(), 0); + WidgetFactory.label(SWT.NONE).text(TextEditorMessages.TextEditorDefaultsPreferencePage_zwsp) + .layoutData(new GridData(SWT.BEGINNING, SWT.CENTER, false, false)).create(tabularComposite); + ButtonFactory checkboxFactory = WidgetFactory.button(SWT.CHECK) + .supplyLayoutData(() -> new GridData(SWT.CENTER, SWT.CENTER, false, false)).enabled(false); + checkboxFactory.create(tabularComposite); + preference = new Preference(AbstractDecoratedTextEditorPreferenceConstants.EDITOR_SHOW_ZWSP, "", null); //$NON-NLS-1$ + addCheckBox(tabularComposite, preference, new BooleanDomain(), 0); + checkboxFactory.create(tabularComposite); + Composite alphaComposite= new Composite(composite, SWT.NONE); layout= new GridLayout(); layout.numColumns= 2; @@ -809,6 +822,8 @@ private OverlayPreferenceStore createOverlayStore() { overlayKeys.add(new OverlayPreferenceStore.OverlayKey(OverlayPreferenceStore.BOOLEAN, AbstractDecoratedTextEditorPreferenceConstants.EDITOR_SHOW_TRAILING_TABS)); overlayKeys.add(new OverlayPreferenceStore.OverlayKey(OverlayPreferenceStore.BOOLEAN, AbstractDecoratedTextEditorPreferenceConstants.EDITOR_SHOW_CARRIAGE_RETURN)); overlayKeys.add(new OverlayPreferenceStore.OverlayKey(OverlayPreferenceStore.BOOLEAN, AbstractDecoratedTextEditorPreferenceConstants.EDITOR_SHOW_LINE_FEED)); + overlayKeys.add(new OverlayPreferenceStore.OverlayKey(OverlayPreferenceStore.BOOLEAN, + AbstractDecoratedTextEditorPreferenceConstants.EDITOR_SHOW_ZWSP)); overlayKeys.add(new OverlayPreferenceStore.OverlayKey(OverlayPreferenceStore.INT, AbstractDecoratedTextEditorPreferenceConstants.EDITOR_WHITESPACE_CHARACTER_ALPHA_VALUE)); OverlayPreferenceStore.OverlayKey[] keys= new OverlayPreferenceStore.OverlayKey[overlayKeys.size()]; diff --git a/bundles/org.eclipse.ui.editors/src/org/eclipse/ui/internal/editors/text/TextEditorMessages.java b/bundles/org.eclipse.ui.editors/src/org/eclipse/ui/internal/editors/text/TextEditorMessages.java index 92a3d48a385b..05cbdbefd4f3 100644 --- a/bundles/org.eclipse.ui.editors/src/org/eclipse/ui/internal/editors/text/TextEditorMessages.java +++ b/bundles/org.eclipse.ui.editors/src/org/eclipse/ui/internal/editors/text/TextEditorMessages.java @@ -159,6 +159,7 @@ private TextEditorMessages() { public static String TextEditorDefaultsPreferencePage_ideographicSpace; public static String TextEditorDefaultsPreferencePage_leading; public static String TextEditorDefaultsPreferencePage_lineFeed; + public static String TextEditorDefaultsPreferencePage_zwsp; public static String TextEditorDefaultsPreferencePage_range_indicator; public static String TextEditorDefaultsPreferencePage_smartHomeEnd; public static String TextEditorDefaultsPreferencePage_warn_if_derived; diff --git a/bundles/org.eclipse.ui.editors/src/org/eclipse/ui/internal/editors/text/TextEditorMessages.properties b/bundles/org.eclipse.ui.editors/src/org/eclipse/ui/internal/editors/text/TextEditorMessages.properties index 2e5a7267edc7..5fea721c2adc 100644 --- a/bundles/org.eclipse.ui.editors/src/org/eclipse/ui/internal/editors/text/TextEditorMessages.properties +++ b/bundles/org.eclipse.ui.editors/src/org/eclipse/ui/internal/editors/text/TextEditorMessages.properties @@ -61,6 +61,7 @@ TextEditorDefaultsPreferencePage_enrichHover_onClick=Enrich on click TextEditorDefaultsPreferencePage_ideographicSpace=Ideographic space ( \u00b0 ) TextEditorDefaultsPreferencePage_leading=Leading TextEditorDefaultsPreferencePage_lineFeed=Line Feed ( \u00b6 ) +TextEditorDefaultsPreferencePage_zwsp=ZWSP (Zero-Width Space) TextEditorDefaultsPreferencePage_range_indicator=Show &range indicator TextEditorDefaultsPreferencePage_warn_if_derived= War&n before editing a derived file TextEditorDefaultsPreferencePage_smartHomeEnd= &Smart caret positioning at line start and end diff --git a/bundles/org.eclipse.ui.editors/src/org/eclipse/ui/texteditor/AbstractDecoratedTextEditorPreferenceConstants.java b/bundles/org.eclipse.ui.editors/src/org/eclipse/ui/texteditor/AbstractDecoratedTextEditorPreferenceConstants.java index 3c1a98e38e58..19a68b60f126 100644 --- a/bundles/org.eclipse.ui.editors/src/org/eclipse/ui/texteditor/AbstractDecoratedTextEditorPreferenceConstants.java +++ b/bundles/org.eclipse.ui.editors/src/org/eclipse/ui/texteditor/AbstractDecoratedTextEditorPreferenceConstants.java @@ -502,7 +502,8 @@ private AbstractDecoratedTextEditorPreferenceConstants() { *

* *

- * The following preferences can be used for fine-grained configuration when enabled. + * The following preferences can be used for fine-grained configuration when + * enabled. *

* * @@ -647,6 +649,18 @@ private AbstractDecoratedTextEditorPreferenceConstants() { */ public static final String EDITOR_SHOW_LINE_FEED= AbstractTextEditor.PREFERENCE_SHOW_LINE_FEED; + /** + * A named preference that controls the display of ZWSP (zero-with space) + * characters. The value is used only if the value of + * {@link #EDITOR_SHOW_WHITESPACE_CHARACTERS} is true. + *

+ * Value is of type Boolean. + *

+ * + * @since 3.? + */ + public static final String EDITOR_SHOW_ZWSP = AbstractTextEditor.PREFERENCE_SHOW_ZWSP; + /** * A named preference that controls the alpha value of whitespace characters. The value is used * only if the value of {@link #EDITOR_SHOW_WHITESPACE_CHARACTERS} is true. @@ -858,6 +872,7 @@ public static void initializeDefaultValues(IPreferenceStore store) { store.setDefault(EDITOR_SHOW_TRAILING_TABS, true); store.setDefault(EDITOR_SHOW_CARRIAGE_RETURN, true); store.setDefault(EDITOR_SHOW_LINE_FEED, true); + store.setDefault(EDITOR_SHOW_ZWSP, true); store.setDefault(EDITOR_WHITESPACE_CHARACTER_ALPHA_VALUE, 80); store.setDefault(EDITOR_TEXT_DRAG_AND_DROP_ENABLED, true); diff --git a/bundles/org.eclipse.ui.workbench.texteditor/plugin.properties b/bundles/org.eclipse.ui.workbench.texteditor/plugin.properties index f647d810d8d9..309a98d74290 100644 --- a/bundles/org.eclipse.ui.workbench.texteditor/plugin.properties +++ b/bundles/org.eclipse.ui.workbench.texteditor/plugin.properties @@ -215,3 +215,5 @@ blockSelectionModeFont.label= Text Editor Block Selection Font blockSelectionModeFont.description= The block selection mode font is used by text editors in block (column) mode. A monospace font should be used. MinimapView.name=Minimap + +CodeMining.show.ZWSP=Show ZWSP (Zero-Width Space) diff --git a/bundles/org.eclipse.ui.workbench.texteditor/plugin.xml b/bundles/org.eclipse.ui.workbench.texteditor/plugin.xml index e2ef210299f6..e36930a7a0fa 100644 --- a/bundles/org.eclipse.ui.workbench.texteditor/plugin.xml +++ b/bundles/org.eclipse.ui.workbench.texteditor/plugin.xml @@ -1491,5 +1491,13 @@ visible="false"> - + + + + + diff --git a/bundles/org.eclipse.ui.workbench.texteditor/src/org/eclipse/ui/internal/texteditor/codemining/ZeroWidthSpaceLineContentCodeMining.java b/bundles/org.eclipse.ui.workbench.texteditor/src/org/eclipse/ui/internal/texteditor/codemining/ZeroWidthSpaceLineContentCodeMining.java new file mode 100644 index 000000000000..09ae2ef72044 --- /dev/null +++ b/bundles/org.eclipse.ui.workbench.texteditor/src/org/eclipse/ui/internal/texteditor/codemining/ZeroWidthSpaceLineContentCodeMining.java @@ -0,0 +1,37 @@ +/******************************************************************************* + * Copyright (c) 2025 SAP S.E. 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: + * SAP S.E. - initial API and implementation + *******************************************************************************/ +package org.eclipse.ui.internal.texteditor.codemining; + +import org.eclipse.jface.text.Position; +import org.eclipse.jface.text.codemining.ICodeMiningProvider; +import org.eclipse.jface.text.codemining.LineContentCodeMining; + +class ZeroWidthSpaceLineContentCodeMining extends LineContentCodeMining { + + private static final String ZWSP_ANNOTATION = "ZWSP"; //$NON-NLS-1$ + + ZeroWidthSpaceLineContentCodeMining(Position position, ICodeMiningProvider provider) { + super(position, true, provider); + } + + @Override + public boolean isResolved() { + return true; + } + + @Override + public String getLabel() { + return ZWSP_ANNOTATION; + } +} diff --git a/bundles/org.eclipse.ui.workbench.texteditor/src/org/eclipse/ui/internal/texteditor/codemining/ZeroWidthSpaceLineContentCodeMiningProvider.java b/bundles/org.eclipse.ui.workbench.texteditor/src/org/eclipse/ui/internal/texteditor/codemining/ZeroWidthSpaceLineContentCodeMiningProvider.java new file mode 100644 index 000000000000..29bd4d29d86d --- /dev/null +++ b/bundles/org.eclipse.ui.workbench.texteditor/src/org/eclipse/ui/internal/texteditor/codemining/ZeroWidthSpaceLineContentCodeMiningProvider.java @@ -0,0 +1,97 @@ +/******************************************************************************* + * Copyright (c) 2025 SAP S.E. 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: + * SAP S.E. - initial API and implementation + *******************************************************************************/ +package org.eclipse.ui.internal.texteditor.codemining; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; +import java.util.concurrent.CompletableFuture; + +import org.eclipse.core.runtime.IProgressMonitor; + +import org.eclipse.jface.preference.IPreferenceStore; +import org.eclipse.jface.util.IPropertyChangeListener; +import org.eclipse.jface.util.PropertyChangeEvent; + +import org.eclipse.jface.text.ITextViewer; +import org.eclipse.jface.text.Position; +import org.eclipse.jface.text.codemining.AbstractCodeMiningProvider; +import org.eclipse.jface.text.codemining.ICodeMining; +import org.eclipse.jface.text.source.ISourceViewerExtension5; + +import org.eclipse.ui.texteditor.AbstractTextEditor; + +public class ZeroWidthSpaceLineContentCodeMiningProvider extends AbstractCodeMiningProvider + implements IPropertyChangeListener { + + private static final char ZWSP_SIGN = '\u200b'; + private IPreferenceStore store; + private boolean showZwsp = false; + + @Override + public CompletableFuture> provideCodeMinings(ITextViewer viewer, + IProgressMonitor monitor) { + if (store == null) { + loadStoreAndReadProperty(); + } + + if (!showZwsp) { + return CompletableFuture.completedFuture(Collections.emptyList()); + } + + List list = new ArrayList<>(); + String content = viewer.getDocument().get(); + for (int i = 0; i < content.length(); i++) { + if (content.charAt(i) == ZWSP_SIGN) { + list.add(createCodeMining(i)); + } + } + return CompletableFuture.completedFuture(list); + } + + @Override + public void propertyChange(PropertyChangeEvent event) { + if (event.getProperty().equals(AbstractTextEditor.PREFERENCE_SHOW_ZWSP)) { + readShowZwspFromStore(); + updateCodeMinings(); + } + } + + private void updateCodeMinings() { + ITextViewer viewer = getAdapter(ITextViewer.class); + if (viewer instanceof ISourceViewerExtension5 codeMiningExtension) { + codeMiningExtension.updateCodeMinings(); + } + } + + @Override + public void dispose() { + store.removePropertyChangeListener(this); + super.dispose(); + } + + private void loadStoreAndReadProperty() { + store = getAdapter(IPreferenceStore.class); + readShowZwspFromStore(); + store.addPropertyChangeListener(this); + } + + private ICodeMining createCodeMining(int offset) { + return new ZeroWidthSpaceLineContentCodeMining(new Position(offset, 1), this); + } + + private void readShowZwspFromStore() { + showZwsp = store.getBoolean(AbstractTextEditor.PREFERENCE_SHOW_ZWSP); + } +} diff --git a/bundles/org.eclipse.ui.workbench.texteditor/src/org/eclipse/ui/texteditor/AbstractTextEditor.java b/bundles/org.eclipse.ui.workbench.texteditor/src/org/eclipse/ui/texteditor/AbstractTextEditor.java index 2b6c418fc017..9b34d7570bfb 100644 --- a/bundles/org.eclipse.ui.workbench.texteditor/src/org/eclipse/ui/texteditor/AbstractTextEditor.java +++ b/bundles/org.eclipse.ui.workbench.texteditor/src/org/eclipse/ui/texteditor/AbstractTextEditor.java @@ -2335,10 +2335,21 @@ private int computeOffsetAtLocation(ITextViewer textViewer, int x, int y) { public static final String PREFERENCE_SHOW_LINE_FEED = "showLineFeed"; //$NON-NLS-1$ /** - * A named preference that controls the alpha value of whitespace characters. - * The value is used only if the value of + * A named preference that controls the display of zero-width characters like + * zero-width space. The value is used only if the value of * {@link #PREFERENCE_SHOW_WHITESPACE_CHARACTERS} is true. *

+ * Value is of type Boolean. + *

+ * + * @since 3.? + */ + public static final String PREFERENCE_SHOW_ZW_CHARACTERS = "showZwsp"; //$NON-NLS-1$ + + /** + * A named preference that controls the alpha value of whitespace characters. The value is used + * only if the value of {@link #PREFERENCE_SHOW_WHITESPACE_CHARACTERS} is true. + *

* Value is of type Integer. *

* From 7e4f6d89950c00cb3c9b4d1ec1501810a6e7bad7 Mon Sep 17 00:00:00 2001 From: Marcus Hoepfner Date: Mon, 11 Aug 2025 16:05:39 +0200 Subject: [PATCH 02/13] add other characters --- .../ZeroWidthSpaceLineContentCodeMiningProvider.java | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/bundles/org.eclipse.ui.workbench.texteditor/src/org/eclipse/ui/internal/texteditor/codemining/ZeroWidthSpaceLineContentCodeMiningProvider.java b/bundles/org.eclipse.ui.workbench.texteditor/src/org/eclipse/ui/internal/texteditor/codemining/ZeroWidthSpaceLineContentCodeMiningProvider.java index 29bd4d29d86d..8467138d13d7 100644 --- a/bundles/org.eclipse.ui.workbench.texteditor/src/org/eclipse/ui/internal/texteditor/codemining/ZeroWidthSpaceLineContentCodeMiningProvider.java +++ b/bundles/org.eclipse.ui.workbench.texteditor/src/org/eclipse/ui/internal/texteditor/codemining/ZeroWidthSpaceLineContentCodeMiningProvider.java @@ -16,6 +16,7 @@ import java.util.ArrayList; import java.util.Collections; import java.util.List; +import java.util.Set; import java.util.concurrent.CompletableFuture; import org.eclipse.core.runtime.IProgressMonitor; @@ -35,7 +36,13 @@ public class ZeroWidthSpaceLineContentCodeMiningProvider extends AbstractCodeMiningProvider implements IPropertyChangeListener { - private static final char ZWSP_SIGN = '\u200b'; + private static final char ZW_SPACE = '\u200b'; + private static final char ZW_NON_JOINER = '\u200c'; + private static final char ZW_JOINER = '\u200d'; + private static final char ZW_NO_BREAK_SPACE = '\ufeff'; + + private static final Set ZW_CHARACTERS = Set.of(ZW_SPACE, ZW_NON_JOINER, ZW_JOINER, ZW_NO_BREAK_SPACE); + private IPreferenceStore store; private boolean showZwsp = false; @@ -53,7 +60,8 @@ public CompletableFuture> provideCodeMinings(ITextVi List list = new ArrayList<>(); String content = viewer.getDocument().get(); for (int i = 0; i < content.length(); i++) { - if (content.charAt(i) == ZWSP_SIGN) { + boolean isZwCharacter = ZW_CHARACTERS.contains(content.charAt(i)); + if (isZwCharacter) { list.add(createCodeMining(i)); } } From dc90be09d8573f3e57ddec442a04936e972b709e Mon Sep 17 00:00:00 2001 From: Marcus Hoepfner Date: Mon, 11 Aug 2025 16:07:08 +0200 Subject: [PATCH 03/13] rename constants --- .../editors/text/TextEditorDefaultsPreferencePage.java | 6 +++--- ...AbstractDecoratedTextEditorPreferenceConstants.java | 10 +++++----- .../ZeroWidthSpaceLineContentCodeMiningProvider.java | 4 ++-- 3 files changed, 10 insertions(+), 10 deletions(-) diff --git a/bundles/org.eclipse.ui.editors/src/org/eclipse/ui/internal/editors/text/TextEditorDefaultsPreferencePage.java b/bundles/org.eclipse.ui.editors/src/org/eclipse/ui/internal/editors/text/TextEditorDefaultsPreferencePage.java index 01b1a5c67144..cb9cffc1d8c1 100644 --- a/bundles/org.eclipse.ui.editors/src/org/eclipse/ui/internal/editors/text/TextEditorDefaultsPreferencePage.java +++ b/bundles/org.eclipse.ui.editors/src/org/eclipse/ui/internal/editors/text/TextEditorDefaultsPreferencePage.java @@ -455,7 +455,7 @@ private OverlayPreferenceStore createDialogOverlayStore() { overlayKeys.add(new OverlayPreferenceStore.OverlayKey(OverlayPreferenceStore.BOOLEAN, AbstractDecoratedTextEditorPreferenceConstants.EDITOR_SHOW_CARRIAGE_RETURN)); overlayKeys.add(new OverlayPreferenceStore.OverlayKey(OverlayPreferenceStore.BOOLEAN, AbstractDecoratedTextEditorPreferenceConstants.EDITOR_SHOW_LINE_FEED)); overlayKeys.add(new OverlayPreferenceStore.OverlayKey(OverlayPreferenceStore.BOOLEAN, - AbstractDecoratedTextEditorPreferenceConstants.EDITOR_SHOW_ZWSP)); + AbstractDecoratedTextEditorPreferenceConstants.EDITOR_SHOW_ZW_CHARACTERS)); overlayKeys.add(new OverlayPreferenceStore.OverlayKey(OverlayPreferenceStore.INT, AbstractDecoratedTextEditorPreferenceConstants.EDITOR_WHITESPACE_CHARACTER_ALPHA_VALUE)); OverlayPreferenceStore.OverlayKey[] keys= new OverlayPreferenceStore.OverlayKey[overlayKeys.size()]; @@ -580,7 +580,7 @@ protected Control createDialogArea(Composite parent) { ButtonFactory checkboxFactory = WidgetFactory.button(SWT.CHECK) .supplyLayoutData(() -> new GridData(SWT.CENTER, SWT.CENTER, false, false)).enabled(false); checkboxFactory.create(tabularComposite); - preference = new Preference(AbstractDecoratedTextEditorPreferenceConstants.EDITOR_SHOW_ZWSP, "", null); //$NON-NLS-1$ + preference = new Preference(AbstractDecoratedTextEditorPreferenceConstants.EDITOR_SHOW_ZW_CHARACTERS, "", null); //$NON-NLS-1$ addCheckBox(tabularComposite, preference, new BooleanDomain(), 0); checkboxFactory.create(tabularComposite); @@ -823,7 +823,7 @@ private OverlayPreferenceStore createOverlayStore() { overlayKeys.add(new OverlayPreferenceStore.OverlayKey(OverlayPreferenceStore.BOOLEAN, AbstractDecoratedTextEditorPreferenceConstants.EDITOR_SHOW_CARRIAGE_RETURN)); overlayKeys.add(new OverlayPreferenceStore.OverlayKey(OverlayPreferenceStore.BOOLEAN, AbstractDecoratedTextEditorPreferenceConstants.EDITOR_SHOW_LINE_FEED)); overlayKeys.add(new OverlayPreferenceStore.OverlayKey(OverlayPreferenceStore.BOOLEAN, - AbstractDecoratedTextEditorPreferenceConstants.EDITOR_SHOW_ZWSP)); + AbstractDecoratedTextEditorPreferenceConstants.EDITOR_SHOW_ZW_CHARACTERS)); overlayKeys.add(new OverlayPreferenceStore.OverlayKey(OverlayPreferenceStore.INT, AbstractDecoratedTextEditorPreferenceConstants.EDITOR_WHITESPACE_CHARACTER_ALPHA_VALUE)); OverlayPreferenceStore.OverlayKey[] keys= new OverlayPreferenceStore.OverlayKey[overlayKeys.size()]; diff --git a/bundles/org.eclipse.ui.editors/src/org/eclipse/ui/texteditor/AbstractDecoratedTextEditorPreferenceConstants.java b/bundles/org.eclipse.ui.editors/src/org/eclipse/ui/texteditor/AbstractDecoratedTextEditorPreferenceConstants.java index 19a68b60f126..a1ca2f26191d 100644 --- a/bundles/org.eclipse.ui.editors/src/org/eclipse/ui/texteditor/AbstractDecoratedTextEditorPreferenceConstants.java +++ b/bundles/org.eclipse.ui.editors/src/org/eclipse/ui/texteditor/AbstractDecoratedTextEditorPreferenceConstants.java @@ -517,7 +517,7 @@ private AbstractDecoratedTextEditorPreferenceConstants() { *
  • {@link #EDITOR_SHOW_TRAILING_TABS}
  • *
  • {@link #EDITOR_SHOW_CARRIAGE_RETURN}
  • *
  • {@link #EDITOR_SHOW_LINE_FEED}
  • - *
  • {@link #EDITOR_SHOW_ZWSP}
  • + *
  • {@link #EDITOR_SHOW_ZW_CHARACTERS}
  • *
  • {@link #EDITOR_WHITESPACE_CHARACTER_ALPHA_VALUE}
  • * * @@ -650,8 +650,8 @@ private AbstractDecoratedTextEditorPreferenceConstants() { public static final String EDITOR_SHOW_LINE_FEED= AbstractTextEditor.PREFERENCE_SHOW_LINE_FEED; /** - * A named preference that controls the display of ZWSP (zero-with space) - * characters. The value is used only if the value of + * A named preference that controls the display of zero-width characters like + * zero-width space. The value is used only if the value of * {@link #EDITOR_SHOW_WHITESPACE_CHARACTERS} is true. *

    * Value is of type Boolean. @@ -659,7 +659,7 @@ private AbstractDecoratedTextEditorPreferenceConstants() { * * @since 3.? */ - public static final String EDITOR_SHOW_ZWSP = AbstractTextEditor.PREFERENCE_SHOW_ZWSP; + public static final String EDITOR_SHOW_ZW_CHARACTERS = AbstractTextEditor.PREFERENCE_SHOW_ZW_CHARACTERS; /** * A named preference that controls the alpha value of whitespace characters. The value is used @@ -872,7 +872,7 @@ public static void initializeDefaultValues(IPreferenceStore store) { store.setDefault(EDITOR_SHOW_TRAILING_TABS, true); store.setDefault(EDITOR_SHOW_CARRIAGE_RETURN, true); store.setDefault(EDITOR_SHOW_LINE_FEED, true); - store.setDefault(EDITOR_SHOW_ZWSP, true); + store.setDefault(EDITOR_SHOW_ZW_CHARACTERS, true); store.setDefault(EDITOR_WHITESPACE_CHARACTER_ALPHA_VALUE, 80); store.setDefault(EDITOR_TEXT_DRAG_AND_DROP_ENABLED, true); diff --git a/bundles/org.eclipse.ui.workbench.texteditor/src/org/eclipse/ui/internal/texteditor/codemining/ZeroWidthSpaceLineContentCodeMiningProvider.java b/bundles/org.eclipse.ui.workbench.texteditor/src/org/eclipse/ui/internal/texteditor/codemining/ZeroWidthSpaceLineContentCodeMiningProvider.java index 8467138d13d7..3f48f45c6a23 100644 --- a/bundles/org.eclipse.ui.workbench.texteditor/src/org/eclipse/ui/internal/texteditor/codemining/ZeroWidthSpaceLineContentCodeMiningProvider.java +++ b/bundles/org.eclipse.ui.workbench.texteditor/src/org/eclipse/ui/internal/texteditor/codemining/ZeroWidthSpaceLineContentCodeMiningProvider.java @@ -70,7 +70,7 @@ public CompletableFuture> provideCodeMinings(ITextVi @Override public void propertyChange(PropertyChangeEvent event) { - if (event.getProperty().equals(AbstractTextEditor.PREFERENCE_SHOW_ZWSP)) { + if (event.getProperty().equals(AbstractTextEditor.PREFERENCE_SHOW_ZW_CHARACTERS)) { readShowZwspFromStore(); updateCodeMinings(); } @@ -100,6 +100,6 @@ private ICodeMining createCodeMining(int offset) { } private void readShowZwspFromStore() { - showZwsp = store.getBoolean(AbstractTextEditor.PREFERENCE_SHOW_ZWSP); + showZwsp = store.getBoolean(AbstractTextEditor.PREFERENCE_SHOW_ZW_CHARACTERS); } } From f4e2e57f6c951fd4ef78a89b3a595e0ae0c456df Mon Sep 17 00:00:00 2001 From: Marcus Hoepfner Date: Mon, 11 Aug 2025 16:10:39 +0200 Subject: [PATCH 04/13] rename preference --- .../internal/editors/text/TextEditorDefaultsPreferencePage.java | 2 +- .../eclipse/ui/internal/editors/text/TextEditorMessages.java | 2 +- .../ui/internal/editors/text/TextEditorMessages.properties | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/bundles/org.eclipse.ui.editors/src/org/eclipse/ui/internal/editors/text/TextEditorDefaultsPreferencePage.java b/bundles/org.eclipse.ui.editors/src/org/eclipse/ui/internal/editors/text/TextEditorDefaultsPreferencePage.java index cb9cffc1d8c1..2efdf7a5cd35 100644 --- a/bundles/org.eclipse.ui.editors/src/org/eclipse/ui/internal/editors/text/TextEditorDefaultsPreferencePage.java +++ b/bundles/org.eclipse.ui.editors/src/org/eclipse/ui/internal/editors/text/TextEditorDefaultsPreferencePage.java @@ -575,7 +575,7 @@ protected Control createDialogArea(Composite parent) { preference= new Preference(AbstractDecoratedTextEditorPreferenceConstants.EDITOR_SHOW_LINE_FEED, "", null); //$NON-NLS-1$ addCheckBox(tabularComposite, preference, new BooleanDomain(), 0); - WidgetFactory.label(SWT.NONE).text(TextEditorMessages.TextEditorDefaultsPreferencePage_zwsp) + WidgetFactory.label(SWT.NONE).text(TextEditorMessages.TextEditorDefaultsPreferencePage_zwcharacters) .layoutData(new GridData(SWT.BEGINNING, SWT.CENTER, false, false)).create(tabularComposite); ButtonFactory checkboxFactory = WidgetFactory.button(SWT.CHECK) .supplyLayoutData(() -> new GridData(SWT.CENTER, SWT.CENTER, false, false)).enabled(false); diff --git a/bundles/org.eclipse.ui.editors/src/org/eclipse/ui/internal/editors/text/TextEditorMessages.java b/bundles/org.eclipse.ui.editors/src/org/eclipse/ui/internal/editors/text/TextEditorMessages.java index 05cbdbefd4f3..fdcd10917980 100644 --- a/bundles/org.eclipse.ui.editors/src/org/eclipse/ui/internal/editors/text/TextEditorMessages.java +++ b/bundles/org.eclipse.ui.editors/src/org/eclipse/ui/internal/editors/text/TextEditorMessages.java @@ -159,7 +159,7 @@ private TextEditorMessages() { public static String TextEditorDefaultsPreferencePage_ideographicSpace; public static String TextEditorDefaultsPreferencePage_leading; public static String TextEditorDefaultsPreferencePage_lineFeed; - public static String TextEditorDefaultsPreferencePage_zwsp; + public static String TextEditorDefaultsPreferencePage_zwcharacters; public static String TextEditorDefaultsPreferencePage_range_indicator; public static String TextEditorDefaultsPreferencePage_smartHomeEnd; public static String TextEditorDefaultsPreferencePage_warn_if_derived; diff --git a/bundles/org.eclipse.ui.editors/src/org/eclipse/ui/internal/editors/text/TextEditorMessages.properties b/bundles/org.eclipse.ui.editors/src/org/eclipse/ui/internal/editors/text/TextEditorMessages.properties index 5fea721c2adc..0193e8143792 100644 --- a/bundles/org.eclipse.ui.editors/src/org/eclipse/ui/internal/editors/text/TextEditorMessages.properties +++ b/bundles/org.eclipse.ui.editors/src/org/eclipse/ui/internal/editors/text/TextEditorMessages.properties @@ -61,7 +61,7 @@ TextEditorDefaultsPreferencePage_enrichHover_onClick=Enrich on click TextEditorDefaultsPreferencePage_ideographicSpace=Ideographic space ( \u00b0 ) TextEditorDefaultsPreferencePage_leading=Leading TextEditorDefaultsPreferencePage_lineFeed=Line Feed ( \u00b6 ) -TextEditorDefaultsPreferencePage_zwsp=ZWSP (Zero-Width Space) +TextEditorDefaultsPreferencePage_zwcharacters=Zero-Width Characters TextEditorDefaultsPreferencePage_range_indicator=Show &range indicator TextEditorDefaultsPreferencePage_warn_if_derived= War&n before editing a derived file TextEditorDefaultsPreferencePage_smartHomeEnd= &Smart caret positioning at line start and end From 531d922a52dcb895760c1a195b77b8f3d43e67e2 Mon Sep 17 00:00:00 2001 From: Marcus Hoepfner Date: Mon, 11 Aug 2025 16:11:51 +0200 Subject: [PATCH 05/13] rename files --- .../plugin.xml | 2 +- ...eroWidthCharactersLineContentCodeMining.java} | 16 +++++++++++----- ...CharactersLineContentCodeMiningProvider.java} | 12 +++++++++--- 3 files changed, 21 insertions(+), 9 deletions(-) rename bundles/org.eclipse.ui.workbench.texteditor/src/org/eclipse/ui/internal/texteditor/codemining/{ZeroWidthSpaceLineContentCodeMining.java => ZeroWidthCharactersLineContentCodeMining.java} (63%) rename bundles/org.eclipse.ui.workbench.texteditor/src/org/eclipse/ui/internal/texteditor/codemining/{ZeroWidthSpaceLineContentCodeMiningProvider.java => ZeroWidthCharactersLineContentCodeMiningProvider.java} (89%) diff --git a/bundles/org.eclipse.ui.workbench.texteditor/plugin.xml b/bundles/org.eclipse.ui.workbench.texteditor/plugin.xml index e36930a7a0fa..aaf9928b5119 100644 --- a/bundles/org.eclipse.ui.workbench.texteditor/plugin.xml +++ b/bundles/org.eclipse.ui.workbench.texteditor/plugin.xml @@ -1495,7 +1495,7 @@ diff --git a/bundles/org.eclipse.ui.workbench.texteditor/src/org/eclipse/ui/internal/texteditor/codemining/ZeroWidthSpaceLineContentCodeMining.java b/bundles/org.eclipse.ui.workbench.texteditor/src/org/eclipse/ui/internal/texteditor/codemining/ZeroWidthCharactersLineContentCodeMining.java similarity index 63% rename from bundles/org.eclipse.ui.workbench.texteditor/src/org/eclipse/ui/internal/texteditor/codemining/ZeroWidthSpaceLineContentCodeMining.java rename to bundles/org.eclipse.ui.workbench.texteditor/src/org/eclipse/ui/internal/texteditor/codemining/ZeroWidthCharactersLineContentCodeMining.java index 09ae2ef72044..9f8853487280 100644 --- a/bundles/org.eclipse.ui.workbench.texteditor/src/org/eclipse/ui/internal/texteditor/codemining/ZeroWidthSpaceLineContentCodeMining.java +++ b/bundles/org.eclipse.ui.workbench.texteditor/src/org/eclipse/ui/internal/texteditor/codemining/ZeroWidthCharactersLineContentCodeMining.java @@ -17,12 +17,18 @@ import org.eclipse.jface.text.codemining.ICodeMiningProvider; import org.eclipse.jface.text.codemining.LineContentCodeMining; -class ZeroWidthSpaceLineContentCodeMining extends LineContentCodeMining { +/** + * A code mining that draws zero-width characters (like zero-width spaces) as + * line content code minings. + * + * @see ZeroWidthCharactersLineContentCodeMiningProvider + */ +class ZeroWidthCharactersLineContentCodeMining extends LineContentCodeMining { - private static final String ZWSP_ANNOTATION = "ZWSP"; //$NON-NLS-1$ + private static final String ZW_CHARACTERS_MINING = "ZWSP"; //$NON-NLS-1$ - ZeroWidthSpaceLineContentCodeMining(Position position, ICodeMiningProvider provider) { - super(position, true, provider); + public ZeroWidthCharactersLineContentCodeMining(int offset, ICodeMiningProvider provider) { + super(new Position(offset, 1), true, provider); } @Override @@ -32,6 +38,6 @@ public boolean isResolved() { @Override public String getLabel() { - return ZWSP_ANNOTATION; + return ZW_CHARACTERS_MINING; } } diff --git a/bundles/org.eclipse.ui.workbench.texteditor/src/org/eclipse/ui/internal/texteditor/codemining/ZeroWidthSpaceLineContentCodeMiningProvider.java b/bundles/org.eclipse.ui.workbench.texteditor/src/org/eclipse/ui/internal/texteditor/codemining/ZeroWidthCharactersLineContentCodeMiningProvider.java similarity index 89% rename from bundles/org.eclipse.ui.workbench.texteditor/src/org/eclipse/ui/internal/texteditor/codemining/ZeroWidthSpaceLineContentCodeMiningProvider.java rename to bundles/org.eclipse.ui.workbench.texteditor/src/org/eclipse/ui/internal/texteditor/codemining/ZeroWidthCharactersLineContentCodeMiningProvider.java index 3f48f45c6a23..4e1ef15c102f 100644 --- a/bundles/org.eclipse.ui.workbench.texteditor/src/org/eclipse/ui/internal/texteditor/codemining/ZeroWidthSpaceLineContentCodeMiningProvider.java +++ b/bundles/org.eclipse.ui.workbench.texteditor/src/org/eclipse/ui/internal/texteditor/codemining/ZeroWidthCharactersLineContentCodeMiningProvider.java @@ -26,14 +26,20 @@ import org.eclipse.jface.util.PropertyChangeEvent; import org.eclipse.jface.text.ITextViewer; -import org.eclipse.jface.text.Position; import org.eclipse.jface.text.codemining.AbstractCodeMiningProvider; import org.eclipse.jface.text.codemining.ICodeMining; import org.eclipse.jface.text.source.ISourceViewerExtension5; import org.eclipse.ui.texteditor.AbstractTextEditor; -public class ZeroWidthSpaceLineContentCodeMiningProvider extends AbstractCodeMiningProvider +/** + * A code mining provider that draws zero-width characters (like zero-width + * spaces) as line content code minings. + *

    + * The code mining is only shown if configured in the preferences. + *

    + */ +public class ZeroWidthCharactersLineContentCodeMiningProvider extends AbstractCodeMiningProvider implements IPropertyChangeListener { private static final char ZW_SPACE = '\u200b'; @@ -96,7 +102,7 @@ private void loadStoreAndReadProperty() { } private ICodeMining createCodeMining(int offset) { - return new ZeroWidthSpaceLineContentCodeMining(new Position(offset, 1), this); + return new ZeroWidthCharactersLineContentCodeMining(offset, this); } private void readShowZwspFromStore() { From baf92cec97fc9c439cd1d94f5ae0a8307e1d4680 Mon Sep 17 00:00:00 2001 From: Marcus Hoepfner Date: Thu, 9 Oct 2025 14:56:49 +0200 Subject: [PATCH 06/13] react on toolbar action or general switch-on/off --- ...eroWidthCharactersLineContentCodeMining.java | 17 +++++++++++++++++ ...CharactersLineContentCodeMiningProvider.java | 12 ++++++++---- 2 files changed, 25 insertions(+), 4 deletions(-) diff --git a/bundles/org.eclipse.ui.workbench.texteditor/src/org/eclipse/ui/internal/texteditor/codemining/ZeroWidthCharactersLineContentCodeMining.java b/bundles/org.eclipse.ui.workbench.texteditor/src/org/eclipse/ui/internal/texteditor/codemining/ZeroWidthCharactersLineContentCodeMining.java index 9f8853487280..31979a0096c9 100644 --- a/bundles/org.eclipse.ui.workbench.texteditor/src/org/eclipse/ui/internal/texteditor/codemining/ZeroWidthCharactersLineContentCodeMining.java +++ b/bundles/org.eclipse.ui.workbench.texteditor/src/org/eclipse/ui/internal/texteditor/codemining/ZeroWidthCharactersLineContentCodeMining.java @@ -13,6 +13,13 @@ *******************************************************************************/ package org.eclipse.ui.internal.texteditor.codemining; +import org.eclipse.swt.SWT; +import org.eclipse.swt.custom.StyledText; +import org.eclipse.swt.graphics.Color; +import org.eclipse.swt.graphics.GC; +import org.eclipse.swt.graphics.Point; +import org.eclipse.swt.widgets.Display; + import org.eclipse.jface.text.Position; import org.eclipse.jface.text.codemining.ICodeMiningProvider; import org.eclipse.jface.text.codemining.LineContentCodeMining; @@ -26,9 +33,11 @@ class ZeroWidthCharactersLineContentCodeMining extends LineContentCodeMining { private static final String ZW_CHARACTERS_MINING = "ZWSP"; //$NON-NLS-1$ + private Color fgColor; public ZeroWidthCharactersLineContentCodeMining(int offset, ICodeMiningProvider provider) { super(new Position(offset, 1), true, provider); + fgColor = Display.getCurrent().getSystemColor(SWT.COLOR_LIST_FOREGROUND); } @Override @@ -40,4 +49,12 @@ public boolean isResolved() { public String getLabel() { return ZW_CHARACTERS_MINING; } + + @Override + public Point draw(GC gc, StyledText textWidget, Color color, int x, int y) { + gc.setForeground(fgColor); + Point point = super.draw(gc, textWidget, fgColor, x, y); + gc.setForeground(color); + return point; + } } diff --git a/bundles/org.eclipse.ui.workbench.texteditor/src/org/eclipse/ui/internal/texteditor/codemining/ZeroWidthCharactersLineContentCodeMiningProvider.java b/bundles/org.eclipse.ui.workbench.texteditor/src/org/eclipse/ui/internal/texteditor/codemining/ZeroWidthCharactersLineContentCodeMiningProvider.java index 4e1ef15c102f..49fb9369161e 100644 --- a/bundles/org.eclipse.ui.workbench.texteditor/src/org/eclipse/ui/internal/texteditor/codemining/ZeroWidthCharactersLineContentCodeMiningProvider.java +++ b/bundles/org.eclipse.ui.workbench.texteditor/src/org/eclipse/ui/internal/texteditor/codemining/ZeroWidthCharactersLineContentCodeMiningProvider.java @@ -13,6 +13,9 @@ *******************************************************************************/ package org.eclipse.ui.internal.texteditor.codemining; +import static org.eclipse.ui.texteditor.AbstractTextEditor.PREFERENCE_SHOW_WHITESPACE_CHARACTERS; +import static org.eclipse.ui.texteditor.AbstractTextEditor.PREFERENCE_SHOW_ZW_CHARACTERS; + import java.util.ArrayList; import java.util.Collections; import java.util.List; @@ -30,8 +33,6 @@ import org.eclipse.jface.text.codemining.ICodeMining; import org.eclipse.jface.text.source.ISourceViewerExtension5; -import org.eclipse.ui.texteditor.AbstractTextEditor; - /** * A code mining provider that draws zero-width characters (like zero-width * spaces) as line content code minings. @@ -76,7 +77,8 @@ public CompletableFuture> provideCodeMinings(ITextVi @Override public void propertyChange(PropertyChangeEvent event) { - if (event.getProperty().equals(AbstractTextEditor.PREFERENCE_SHOW_ZW_CHARACTERS)) { + if (PREFERENCE_SHOW_ZW_CHARACTERS.equals(event.getProperty()) + || PREFERENCE_SHOW_WHITESPACE_CHARACTERS.equals(event.getProperty())) { readShowZwspFromStore(); updateCodeMinings(); } @@ -89,6 +91,7 @@ private void updateCodeMinings() { } } + @Override public void dispose() { store.removePropertyChangeListener(this); @@ -106,6 +109,7 @@ private ICodeMining createCodeMining(int offset) { } private void readShowZwspFromStore() { - showZwsp = store.getBoolean(AbstractTextEditor.PREFERENCE_SHOW_ZW_CHARACTERS); + showZwsp = store.getBoolean(PREFERENCE_SHOW_ZW_CHARACTERS) + && store.getBoolean(PREFERENCE_SHOW_WHITESPACE_CHARACTERS); } } From d06af9bacaafc1ae4b0c18224a25c640d2b67db0 Mon Sep 17 00:00:00 2001 From: Marcus Hoepfner Date: Mon, 13 Oct 2025 07:37:03 +0200 Subject: [PATCH 07/13] fix NPE --- .../ZeroWidthCharactersLineContentCodeMining.java | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/bundles/org.eclipse.ui.workbench.texteditor/src/org/eclipse/ui/internal/texteditor/codemining/ZeroWidthCharactersLineContentCodeMining.java b/bundles/org.eclipse.ui.workbench.texteditor/src/org/eclipse/ui/internal/texteditor/codemining/ZeroWidthCharactersLineContentCodeMining.java index 31979a0096c9..4995b8e707f7 100644 --- a/bundles/org.eclipse.ui.workbench.texteditor/src/org/eclipse/ui/internal/texteditor/codemining/ZeroWidthCharactersLineContentCodeMining.java +++ b/bundles/org.eclipse.ui.workbench.texteditor/src/org/eclipse/ui/internal/texteditor/codemining/ZeroWidthCharactersLineContentCodeMining.java @@ -33,11 +33,9 @@ class ZeroWidthCharactersLineContentCodeMining extends LineContentCodeMining { private static final String ZW_CHARACTERS_MINING = "ZWSP"; //$NON-NLS-1$ - private Color fgColor; public ZeroWidthCharactersLineContentCodeMining(int offset, ICodeMiningProvider provider) { super(new Position(offset, 1), true, provider); - fgColor = Display.getCurrent().getSystemColor(SWT.COLOR_LIST_FOREGROUND); } @Override @@ -52,9 +50,14 @@ public String getLabel() { @Override public Point draw(GC gc, StyledText textWidget, Color color, int x, int y) { - gc.setForeground(fgColor); - Point point = super.draw(gc, textWidget, fgColor, x, y); + gc.setForeground(getColor(color)); + Point point = super.draw(gc, textWidget, color, x, y); gc.setForeground(color); return point; } + + private Color getColor(Color predefinedColor) { + return Display.getCurrent() != null ? Display.getCurrent().getSystemColor(SWT.COLOR_LIST_FOREGROUND) + : predefinedColor; + } } From 7c18681e9166e7ebbfb1c90d3068a133e3b0ee54 Mon Sep 17 00:00:00 2001 From: Tobias Melcher Date: Fri, 23 Jan 2026 17:12:43 +0100 Subject: [PATCH 08/13] uses color config from whitespace character painter for code minings --- ...oWidthCharactersLineContentCodeMining.java | 55 ++++++++++++++++--- ...aractersLineContentCodeMiningProvider.java | 3 +- 2 files changed, 47 insertions(+), 11 deletions(-) diff --git a/bundles/org.eclipse.ui.workbench.texteditor/src/org/eclipse/ui/internal/texteditor/codemining/ZeroWidthCharactersLineContentCodeMining.java b/bundles/org.eclipse.ui.workbench.texteditor/src/org/eclipse/ui/internal/texteditor/codemining/ZeroWidthCharactersLineContentCodeMining.java index 4995b8e707f7..d4b250728b3d 100644 --- a/bundles/org.eclipse.ui.workbench.texteditor/src/org/eclipse/ui/internal/texteditor/codemining/ZeroWidthCharactersLineContentCodeMining.java +++ b/bundles/org.eclipse.ui.workbench.texteditor/src/org/eclipse/ui/internal/texteditor/codemining/ZeroWidthCharactersLineContentCodeMining.java @@ -14,16 +14,20 @@ package org.eclipse.ui.internal.texteditor.codemining; import org.eclipse.swt.SWT; +import org.eclipse.swt.custom.StyleRange; import org.eclipse.swt.custom.StyledText; import org.eclipse.swt.graphics.Color; import org.eclipse.swt.graphics.GC; import org.eclipse.swt.graphics.Point; -import org.eclipse.swt.widgets.Display; + +import org.eclipse.jface.preference.IPreferenceStore; import org.eclipse.jface.text.Position; import org.eclipse.jface.text.codemining.ICodeMiningProvider; import org.eclipse.jface.text.codemining.LineContentCodeMining; +import org.eclipse.ui.texteditor.AbstractTextEditor; + /** * A code mining that draws zero-width characters (like zero-width spaces) as * line content code minings. @@ -33,9 +37,13 @@ class ZeroWidthCharactersLineContentCodeMining extends LineContentCodeMining { private static final String ZW_CHARACTERS_MINING = "ZWSP"; //$NON-NLS-1$ + private final IPreferenceStore store; + private final int offset; - public ZeroWidthCharactersLineContentCodeMining(int offset, ICodeMiningProvider provider) { + public ZeroWidthCharactersLineContentCodeMining(int offset, ICodeMiningProvider provider, IPreferenceStore store) { super(new Position(offset, 1), true, provider); + this.store = store; + this.offset = offset; } @Override @@ -50,14 +58,43 @@ public String getLabel() { @Override public Point draw(GC gc, StyledText textWidget, Color color, int x, int y) { - gc.setForeground(getColor(color)); - Point point = super.draw(gc, textWidget, color, x, y); - gc.setForeground(color); - return point; + int oldAlpha = -1; + boolean isAdvancedGraphicsPresent = gc.getAdvanced(); + if (isAdvancedGraphicsPresent) { + int alpha = store.getInt(AbstractTextEditor.PREFERENCE_WHITESPACE_CHARACTER_ALPHA_VALUE); + oldAlpha = gc.getAlpha(); + gc.setAlpha(alpha); + } + try { + gc.setForeground(getColor(textWidget)); + Point point = super.draw(gc, textWidget, color, x, y); + gc.setForeground(color); + return point; + } finally { + if (oldAlpha != -1) { + gc.setAlpha(oldAlpha); + } + } + } + + private Color getColor(StyledText textWidget) { + Color fg; + boolean isFullSelectionStyle = (textWidget.getStyle() & SWT.FULL_SELECTION) != SWT.NONE; + if (!textWidget.getBlockSelection() && isFullSelectionStyle && isOffsetSelected(textWidget, offset)) { + fg = textWidget.getSelectionForeground(); + } else { + StyleRange styleRange = textWidget.getStyleRangeAtOffset(offset); + if (styleRange == null || styleRange.foreground == null) { + fg = textWidget.getForeground(); + } else { + fg = styleRange.foreground; + } + } + return fg; } - private Color getColor(Color predefinedColor) { - return Display.getCurrent() != null ? Display.getCurrent().getSystemColor(SWT.COLOR_LIST_FOREGROUND) - : predefinedColor; + private static final boolean isOffsetSelected(StyledText widget, int offset) { + Point selection = widget.getSelection(); + return offset >= selection.x && offset < selection.y; } } diff --git a/bundles/org.eclipse.ui.workbench.texteditor/src/org/eclipse/ui/internal/texteditor/codemining/ZeroWidthCharactersLineContentCodeMiningProvider.java b/bundles/org.eclipse.ui.workbench.texteditor/src/org/eclipse/ui/internal/texteditor/codemining/ZeroWidthCharactersLineContentCodeMiningProvider.java index 49fb9369161e..76de264d25dc 100644 --- a/bundles/org.eclipse.ui.workbench.texteditor/src/org/eclipse/ui/internal/texteditor/codemining/ZeroWidthCharactersLineContentCodeMiningProvider.java +++ b/bundles/org.eclipse.ui.workbench.texteditor/src/org/eclipse/ui/internal/texteditor/codemining/ZeroWidthCharactersLineContentCodeMiningProvider.java @@ -91,7 +91,6 @@ private void updateCodeMinings() { } } - @Override public void dispose() { store.removePropertyChangeListener(this); @@ -105,7 +104,7 @@ private void loadStoreAndReadProperty() { } private ICodeMining createCodeMining(int offset) { - return new ZeroWidthCharactersLineContentCodeMining(offset, this); + return new ZeroWidthCharactersLineContentCodeMining(offset, this, store); } private void readShowZwspFromStore() { From 9b6ffbcd1f19b3e362534dc4a8bd7b2156b00604 Mon Sep 17 00:00:00 2001 From: Tobias Melcher Date: Fri, 23 Jan 2026 17:36:04 +0100 Subject: [PATCH 09/13] fix IllegalArgumentException --- .../ZeroWidthCharactersLineContentCodeMining.java | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/bundles/org.eclipse.ui.workbench.texteditor/src/org/eclipse/ui/internal/texteditor/codemining/ZeroWidthCharactersLineContentCodeMining.java b/bundles/org.eclipse.ui.workbench.texteditor/src/org/eclipse/ui/internal/texteditor/codemining/ZeroWidthCharactersLineContentCodeMining.java index d4b250728b3d..031e22c5b61e 100644 --- a/bundles/org.eclipse.ui.workbench.texteditor/src/org/eclipse/ui/internal/texteditor/codemining/ZeroWidthCharactersLineContentCodeMining.java +++ b/bundles/org.eclipse.ui.workbench.texteditor/src/org/eclipse/ui/internal/texteditor/codemining/ZeroWidthCharactersLineContentCodeMining.java @@ -83,11 +83,15 @@ private Color getColor(StyledText textWidget) { if (!textWidget.getBlockSelection() && isFullSelectionStyle && isOffsetSelected(textWidget, offset)) { fg = textWidget.getSelectionForeground(); } else { - StyleRange styleRange = textWidget.getStyleRangeAtOffset(offset); - if (styleRange == null || styleRange.foreground == null) { + if (offset < 0 || offset >= textWidget.getCharCount()) { fg = textWidget.getForeground(); } else { - fg = styleRange.foreground; + StyleRange styleRange = textWidget.getStyleRangeAtOffset(offset); + if (styleRange == null || styleRange.foreground == null) { + fg = textWidget.getForeground(); + } else { + fg = styleRange.foreground; + } } } return fg; From 3a09d997f956b0ed9e45b36ebaa4c7613e1df096 Mon Sep 17 00:00:00 2001 From: Tobias Melcher Date: Mon, 26 Jan 2026 18:10:29 +0100 Subject: [PATCH 10/13] fix code mining rendering with zero width characters --- .../codemining/ZeroWidthCharactersLineContentCodeMining.java | 2 +- .../ZeroWidthCharactersLineContentCodeMiningProvider.java | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/bundles/org.eclipse.ui.workbench.texteditor/src/org/eclipse/ui/internal/texteditor/codemining/ZeroWidthCharactersLineContentCodeMining.java b/bundles/org.eclipse.ui.workbench.texteditor/src/org/eclipse/ui/internal/texteditor/codemining/ZeroWidthCharactersLineContentCodeMining.java index 031e22c5b61e..9ddd2d341075 100644 --- a/bundles/org.eclipse.ui.workbench.texteditor/src/org/eclipse/ui/internal/texteditor/codemining/ZeroWidthCharactersLineContentCodeMining.java +++ b/bundles/org.eclipse.ui.workbench.texteditor/src/org/eclipse/ui/internal/texteditor/codemining/ZeroWidthCharactersLineContentCodeMining.java @@ -41,7 +41,7 @@ class ZeroWidthCharactersLineContentCodeMining extends LineContentCodeMining { private final int offset; public ZeroWidthCharactersLineContentCodeMining(int offset, ICodeMiningProvider provider, IPreferenceStore store) { - super(new Position(offset, 1), true, provider); + super(new Position(offset, 1), false, provider); this.store = store; this.offset = offset; } diff --git a/bundles/org.eclipse.ui.workbench.texteditor/src/org/eclipse/ui/internal/texteditor/codemining/ZeroWidthCharactersLineContentCodeMiningProvider.java b/bundles/org.eclipse.ui.workbench.texteditor/src/org/eclipse/ui/internal/texteditor/codemining/ZeroWidthCharactersLineContentCodeMiningProvider.java index 76de264d25dc..29b6071fa9b2 100644 --- a/bundles/org.eclipse.ui.workbench.texteditor/src/org/eclipse/ui/internal/texteditor/codemining/ZeroWidthCharactersLineContentCodeMiningProvider.java +++ b/bundles/org.eclipse.ui.workbench.texteditor/src/org/eclipse/ui/internal/texteditor/codemining/ZeroWidthCharactersLineContentCodeMiningProvider.java @@ -104,7 +104,7 @@ private void loadStoreAndReadProperty() { } private ICodeMining createCodeMining(int offset) { - return new ZeroWidthCharactersLineContentCodeMining(offset, this, store); + return new ZeroWidthCharactersLineContentCodeMining(offset + 1, this, store); } private void readShowZwspFromStore() { From 3b4a1cacc82d1ffeaf6c0388b15cc4f6bec5bb90 Mon Sep 17 00:00:00 2001 From: Tobias Melcher Date: Mon, 26 Jan 2026 18:38:06 +0100 Subject: [PATCH 11/13] fix selection color of code mining --- .../ZeroWidthCharactersLineContentCodeMining.java | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/bundles/org.eclipse.ui.workbench.texteditor/src/org/eclipse/ui/internal/texteditor/codemining/ZeroWidthCharactersLineContentCodeMining.java b/bundles/org.eclipse.ui.workbench.texteditor/src/org/eclipse/ui/internal/texteditor/codemining/ZeroWidthCharactersLineContentCodeMining.java index 9ddd2d341075..c78ba39d108b 100644 --- a/bundles/org.eclipse.ui.workbench.texteditor/src/org/eclipse/ui/internal/texteditor/codemining/ZeroWidthCharactersLineContentCodeMining.java +++ b/bundles/org.eclipse.ui.workbench.texteditor/src/org/eclipse/ui/internal/texteditor/codemining/ZeroWidthCharactersLineContentCodeMining.java @@ -78,15 +78,16 @@ public Point draw(GC gc, StyledText textWidget, Color color, int x, int y) { } private Color getColor(StyledText textWidget) { + int off = offset - 1; Color fg; boolean isFullSelectionStyle = (textWidget.getStyle() & SWT.FULL_SELECTION) != SWT.NONE; - if (!textWidget.getBlockSelection() && isFullSelectionStyle && isOffsetSelected(textWidget, offset)) { + if (!textWidget.getBlockSelection() && isFullSelectionStyle && isOffsetSelected(textWidget, off)) { fg = textWidget.getSelectionForeground(); } else { - if (offset < 0 || offset >= textWidget.getCharCount()) { + if (off < 0 || off >= textWidget.getCharCount()) { fg = textWidget.getForeground(); } else { - StyleRange styleRange = textWidget.getStyleRangeAtOffset(offset); + StyleRange styleRange = textWidget.getStyleRangeAtOffset(off); if (styleRange == null || styleRange.foreground == null) { fg = textWidget.getForeground(); } else { From 9c125e8d7ea6a31e996f2bee3b2d4a0993885f66 Mon Sep 17 00:00:00 2001 From: Marcus Hoepfner Date: Thu, 12 Feb 2026 10:16:42 +0100 Subject: [PATCH 12/13] adapt version --- .../org.eclipse.ui.workbench.texteditor/META-INF/MANIFEST.MF | 2 +- .../src/org/eclipse/ui/texteditor/AbstractTextEditor.java | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/bundles/org.eclipse.ui.workbench.texteditor/META-INF/MANIFEST.MF b/bundles/org.eclipse.ui.workbench.texteditor/META-INF/MANIFEST.MF index 7f40fef68bba..1f64abc9eb4d 100644 --- a/bundles/org.eclipse.ui.workbench.texteditor/META-INF/MANIFEST.MF +++ b/bundles/org.eclipse.ui.workbench.texteditor/META-INF/MANIFEST.MF @@ -2,7 +2,7 @@ Manifest-Version: 1.0 Bundle-ManifestVersion: 2 Bundle-Name: %pluginName Bundle-SymbolicName: org.eclipse.ui.workbench.texteditor; singleton:=true -Bundle-Version: 3.20.0.qualifier +Bundle-Version: 3.21.0.qualifier Bundle-Activator: org.eclipse.ui.internal.texteditor.TextEditorPlugin Bundle-ActivationPolicy: lazy Bundle-Vendor: %providerName diff --git a/bundles/org.eclipse.ui.workbench.texteditor/src/org/eclipse/ui/texteditor/AbstractTextEditor.java b/bundles/org.eclipse.ui.workbench.texteditor/src/org/eclipse/ui/texteditor/AbstractTextEditor.java index 9b34d7570bfb..61f8efa2d754 100644 --- a/bundles/org.eclipse.ui.workbench.texteditor/src/org/eclipse/ui/texteditor/AbstractTextEditor.java +++ b/bundles/org.eclipse.ui.workbench.texteditor/src/org/eclipse/ui/texteditor/AbstractTextEditor.java @@ -2342,7 +2342,7 @@ private int computeOffsetAtLocation(ITextViewer textViewer, int x, int y) { * Value is of type Boolean. *

    * - * @since 3.? + * @since 3.21 */ public static final String PREFERENCE_SHOW_ZW_CHARACTERS = "showZwsp"; //$NON-NLS-1$ From b81cb31a04c534f14a5e8baf4bf96856c25a2097 Mon Sep 17 00:00:00 2001 From: Marcus Hoepfner Date: Thu, 12 Feb 2026 12:28:36 +0100 Subject: [PATCH 13/13] version adapted --- bundles/org.eclipse.ui.editors/META-INF/MANIFEST.MF | 2 +- .../AbstractDecoratedTextEditorPreferenceConstants.java | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/bundles/org.eclipse.ui.editors/META-INF/MANIFEST.MF b/bundles/org.eclipse.ui.editors/META-INF/MANIFEST.MF index 5a78bb6d2b6f..8e375d7187a2 100644 --- a/bundles/org.eclipse.ui.editors/META-INF/MANIFEST.MF +++ b/bundles/org.eclipse.ui.editors/META-INF/MANIFEST.MF @@ -2,7 +2,7 @@ Manifest-Version: 1.0 Bundle-ManifestVersion: 2 Bundle-Name: %pluginName Bundle-SymbolicName: org.eclipse.ui.editors; singleton:=true -Bundle-Version: 3.21.0.qualifier +Bundle-Version: 3.22.0.qualifier Bundle-Activator: org.eclipse.ui.internal.editors.text.EditorsPlugin Bundle-ActivationPolicy: lazy Bundle-Vendor: %providerName diff --git a/bundles/org.eclipse.ui.editors/src/org/eclipse/ui/texteditor/AbstractDecoratedTextEditorPreferenceConstants.java b/bundles/org.eclipse.ui.editors/src/org/eclipse/ui/texteditor/AbstractDecoratedTextEditorPreferenceConstants.java index a1ca2f26191d..2f50bf9e00eb 100644 --- a/bundles/org.eclipse.ui.editors/src/org/eclipse/ui/texteditor/AbstractDecoratedTextEditorPreferenceConstants.java +++ b/bundles/org.eclipse.ui.editors/src/org/eclipse/ui/texteditor/AbstractDecoratedTextEditorPreferenceConstants.java @@ -657,7 +657,7 @@ private AbstractDecoratedTextEditorPreferenceConstants() { * Value is of type Boolean. *

    * - * @since 3.? + * @since 3.22 */ public static final String EDITOR_SHOW_ZW_CHARACTERS = AbstractTextEditor.PREFERENCE_SHOW_ZW_CHARACTERS;