From e400d773b859ce626f6ee35c0de185c3054406e9 Mon Sep 17 00:00:00 2001 From: Andrey Loskutov Date: Fri, 3 Jul 2026 17:28:13 +0200 Subject: [PATCH] Show proper symlink decorations for broken symlinks Requires fix in platform, see https://github.com/eclipse-platform/eclipse.platform/pull/2798 See https://github.com/eclipse-platform/eclipse.platform/issues/2797 --- .../ui/internal/ide/SymlinkDecorator.java | 21 +++++++++++++++++-- 1 file changed, 19 insertions(+), 2 deletions(-) diff --git a/bundles/org.eclipse.ui.ide/src/org/eclipse/ui/internal/ide/SymlinkDecorator.java b/bundles/org.eclipse.ui.ide/src/org/eclipse/ui/internal/ide/SymlinkDecorator.java index cd82135a07d..a7f0c04c574 100644 --- a/bundles/org.eclipse.ui.ide/src/org/eclipse/ui/internal/ide/SymlinkDecorator.java +++ b/bundles/org.eclipse.ui.ide/src/org/eclipse/ui/internal/ide/SymlinkDecorator.java @@ -14,8 +14,11 @@ *******************************************************************************/ package org.eclipse.ui.internal.ide; +import java.net.URI; import java.util.Optional; +import org.eclipse.core.filesystem.EFS; +import org.eclipse.core.filesystem.IFileInfo; import org.eclipse.core.resources.IResource; import org.eclipse.core.resources.ResourceAttributes; import org.eclipse.core.resources.mapping.ResourceMapping; @@ -25,6 +28,7 @@ import org.eclipse.jface.viewers.IDecoration; import org.eclipse.jface.viewers.ILabelProviderListener; import org.eclipse.jface.viewers.ILightweightLabelDecorator; +import org.eclipse.ui.internal.ide.dialogs.IDEResourceInfoUtils; /** * Decorate symbolic links @@ -33,12 +37,15 @@ public class SymlinkDecorator implements ILightweightLabelDecorator { private static Optional SYMLINK; + private static final Optional LINK_WARNING; static { SYMLINK = ResourceLocator.imageDescriptorFromBundle( IDEWorkbenchPlugin.IDE_WORKBENCH, "$nl$/icons/full/ovr16/symlink_ovr.svg"); //$NON-NLS-1$ + LINK_WARNING = ResourceLocator.imageDescriptorFromBundle(IDEWorkbenchPlugin.IDE_WORKBENCH, + "$nl$/icons/full/ovr16/linkwarn_ovr.svg"); //$NON-NLS-1$ } @Override @@ -68,8 +75,18 @@ public void decorate(Object element, IDecoration decoration) { IResource resource = Adapters.adapt(element, IResource.class); if (resource != null) { ResourceAttributes resourceAttributes = resource.getResourceAttributes(); - if (resourceAttributes != null && resourceAttributes.isSymbolicLink()) { - SYMLINK.ifPresent(decoration::addOverlay); + if (resourceAttributes != null) { + if (resourceAttributes.isSymbolicLink()) { + SYMLINK.ifPresent(decoration::addOverlay); + URI location = resource.getLocationURI(); + if (location != null) { + IFileInfo fileInfo = IDEResourceInfoUtils.getFileInfo(location); + String linkTarget = fileInfo.getStringAttribute(EFS.ATTRIBUTE_LINK_TARGET); + if (linkTarget != null && !fileInfo.exists()) { + LINK_WARNING.ifPresent(t -> decoration.addOverlay(t, IDecoration.TOP_LEFT)); + } + } + } } } }