Skip to content

Commit

Permalink
Add support for "editor" content types for compare editor
Browse files Browse the repository at this point in the history
Extend `contentMergeViewers` extension point: add an attribute to
consider "linked" editor content type associations. The code checks if
contentMergeViewers contribution refers to such "linked" editor id in
extension, and check if editor supports other content types. In case
there are more content types supported by same "linked" editor, these
would be automatically considered as valid contentTypes for the
contentMergeViewers.

Updated CompareViewerSwitchingPane to consider more precise title
calculations for ContentMergeViewer instances (where concrete type info
is available after instantiation of a particular viewer).

Fixes eclipse-jdt/eclipse.jdt.ui#1294
  • Loading branch information
iloveeclipse committed Mar 29, 2024
1 parent 338cd76 commit 196b3d2
Show file tree
Hide file tree
Showing 6 changed files with 154 additions and 9 deletions.
11 changes: 11 additions & 0 deletions team/bundles/org.eclipse.compare/.settings/.api_filters
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<component id="org.eclipse.compare" version="2">
<resource path="META-INF/MANIFEST.MF">
<filter comment="Changed contentMergeViewers extension point" id="926941240">
<message_arguments>
<message_argument value="3.11.0"/>
<message_argument value="3.10.0"/>
</message_arguments>
</filter>
</resource>
</component>
2 changes: 1 addition & 1 deletion team/bundles/org.eclipse.compare/META-INF/MANIFEST.MF
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ Manifest-Version: 1.0
Bundle-ManifestVersion: 2
Bundle-Name: %pluginName
Bundle-SymbolicName: org.eclipse.compare; singleton:=true
Bundle-Version: 3.10.100.qualifier
Bundle-Version: 3.11.0.qualifier
Bundle-Activator: org.eclipse.compare.internal.CompareUIPlugin
Bundle-Vendor: %providerName
Bundle-Localization: plugin
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@

import java.text.MessageFormat;

import org.eclipse.compare.contentmergeviewer.ContentMergeViewer;
import org.eclipse.compare.contentmergeviewer.IFlushable;
import org.eclipse.compare.internal.CompareMessages;
import org.eclipse.compare.internal.IFlushable2;
Expand Down Expand Up @@ -279,9 +280,15 @@ public void setInput(Object input) {
if (fViewer != null) {
Control c= fViewer.getControl();
if (c != null) {
Object data= c.getData(CompareUI.COMPARE_VIEWER_TITLE);
if (data instanceof String)
title= (String) data;
if (fViewer instanceof ContentMergeViewer cmv) {
title = cmv.getTitle();
}
if (title == null || title.isBlank()) {
Object data = c.getData(CompareUI.COMPARE_VIEWER_TITLE);
if (data instanceof String) {
title = (String) data;
}
}
if (hadFocus)
c.setFocus();
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,9 +33,12 @@
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Optional;
import java.util.ResourceBundle;
import java.util.Set;
import java.util.StringTokenizer;
import java.util.stream.Collectors;
import java.util.stream.Stream;

import org.eclipse.compare.CompareConfiguration;
import org.eclipse.compare.CompareEditorInput;
Expand Down Expand Up @@ -77,6 +80,7 @@
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.ui.IEditorDescriptor;
import org.eclipse.ui.IEditorInput;
import org.eclipse.ui.IEditorPart;
import org.eclipse.ui.IEditorRegistry;
Expand Down Expand Up @@ -192,12 +196,16 @@ List<T> searchAll(String extension) {
return fExtensionMap.get(normalizeCase(extension));
return null;
}

Collection<T> getAll() {
return fIdMap.values();
}
}

/** Status code describing an internal error */
public static final int INTERNAL_ERROR= 1;

private static boolean NORMALIZE_CASE= true;
private static boolean NORMALIZE_CASE = true;

public static final String PLUGIN_ID= "org.eclipse.compare"; //$NON-NLS-1$

Expand Down Expand Up @@ -983,7 +991,7 @@ private Collection<Object> getContentTypes(Object in) {
}

public ViewerDescriptor[] findContentViewerDescriptor(Viewer oldViewer, Object in, CompareConfiguration cc) {
Set<ViewerDescriptor> result = new LinkedHashSet<>();
LinkedHashSet<ViewerDescriptor> result = new LinkedHashSet<>();
if (in instanceof IStreamContentAccessor) {
String type= ITypedElement.TEXT_TYPE;

Expand All @@ -1007,6 +1015,7 @@ public ViewerDescriptor[] findContentViewerDescriptor(Viewer oldViewer, Object i
List<ViewerDescriptor> list = fContentViewers.searchAll(type);
if (list != null)
result.addAll(list);

// fallback
result.add(fContentViewers.search(Platform.getContentTypeManager().getContentType(IContentTypeManager.CT_TEXT)));
return result.toArray(new ViewerDescriptor[0]);
Expand All @@ -1016,6 +1025,7 @@ public ViewerDescriptor[] findContentViewerDescriptor(Viewer oldViewer, Object i
return null;

ICompareInput input= (ICompareInput) in;
String name = input.getName();

IContentType ctype = getCommonType(input);
if (ctype != null) {
Expand Down Expand Up @@ -1054,6 +1064,9 @@ public ViewerDescriptor[] findContentViewerDescriptor(Viewer oldViewer, Object i
result.addAll(list);
}

Set<ViewerDescriptor> editorLinkedDescriptors = findEditorLinkedDescriptors(name, ctype, false);
result.addAll(editorLinkedDescriptors);

// fallback
String leftType= guessType(input.getLeft());
String rightType= guessType(input.getRight());
Expand All @@ -1069,14 +1082,74 @@ public ViewerDescriptor[] findContentViewerDescriptor(Viewer oldViewer, Object i
result.addAll(list);
}
List<ViewerDescriptor> list = fContentMergeViewers.searchAll(ITypedElement.TEXT_TYPE);
if (list != null)
if (list != null) {
result.addAll(list);

return result.toArray(new ViewerDescriptor[0]);
}
}

ensureTextIsLast(result);
return result.isEmpty() ? null : result.toArray(new ViewerDescriptor[0]);
}

/**
* Modifies given set to move "fallback" text descriptor to be the last one.
* This is needed because we want more specific descriptors used first by default.
*/
private static void ensureTextIsLast(LinkedHashSet<ViewerDescriptor> result) {
if (result.size() > 1) {
ViewerDescriptor first = result.iterator().next();
if (TextMergeViewerCreator.class.getName().equals(first.getViewerClass())) {
result.remove(first);
result.add(first);
}
}
}

/**
* @param fileName possible file name for content in compare editor, may be
* null
* @param contentType possible content type for content in compare editor, may
* be null
* @param firstIsEnough stop searching once first match is found
* @return set of descriptors which could be found for given content type via
* "linked" editor
*/
Set<ViewerDescriptor> findEditorLinkedDescriptors(String fileName, IContentType contentType,
boolean firstIsEnough) {
if (fileName == null) {
if (contentType == null) {
contentType = fgContentTypeManager.findContentTypeFor(fileName);
} else {
return Collections.emptySet();
}
}
IEditorRegistry editorReg = PlatformUI.getWorkbench().getEditorRegistry();
LinkedHashSet<ViewerDescriptor> result = new LinkedHashSet<>();
IEditorDescriptor[] editors = editorReg.getEditors(fileName, contentType);
for (IEditorDescriptor ed : editors) {
addLinkedEditorContentTypes(firstIsEnough, ed.getId(), result);
if (firstIsEnough && !result.isEmpty()) {
return result;
}
}
return result;
}

private void addLinkedEditorContentTypes(boolean firstIsEnough, String editorId, Set<ViewerDescriptor> result) {
Collection<ViewerDescriptor> viewers = new LinkedHashSet<>(fContentMergeViewers.getAll());
Stream<ViewerDescriptor> stream = viewers.stream()
.filter(vd -> vd.getLinkedEditorId() != null)
.filter(vd -> editorId.equals(vd.getLinkedEditorId()));
if (firstIsEnough) {
Optional<ViewerDescriptor> first = stream.findFirst();
if (first.isPresent()) {
result.add(first.get());
}
} else {
stream.collect(Collectors.toCollection(() -> result));
}
}

/**
* Returns a content compare viewer based on an old viewer and an input object.
* If the old viewer is suitable for showing the input the old viewer
Expand Down Expand Up @@ -1483,6 +1556,11 @@ String findContentTypeNameOrType(ICompareInput input, ViewerDescriptor vd, Compa
return type;
}

Set<ViewerDescriptor> editorLinkedDescriptors = findEditorLinkedDescriptors(input.getName(), ctype, true);
if (!editorLinkedDescriptors.isEmpty()) {
return type;
}

// fallback
String leftType= guessType(input.getLeft());
String rightType= guessType(input.getRight());
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@
public class ViewerDescriptor implements IViewerDescriptor {
private final static String CLASS_ATTRIBUTE= "class"; //$NON-NLS-1$
private final static String EXTENSIONS_ATTRIBUTE= "extensions"; //$NON-NLS-1$
private final static String LINKED_EDITOR_ATTRIBUTE = "linkedEditor"; //$NON-NLS-1$
private final static String LABEL_ATTRIBUTE = "label"; //$NON-NLS-1$

private final IConfigurationElement fConfiguration;
Expand Down Expand Up @@ -79,4 +80,42 @@ public String getExtension() {
String getLabel() {
return fConfiguration.getAttribute(LABEL_ATTRIBUTE);
}

String getLinkedEditorId() {
return fConfiguration.getAttribute(LINKED_EDITOR_ATTRIBUTE);
}

String getViewerClass() {
return fConfiguration.getAttribute(CLASS_ATTRIBUTE);
}

@SuppressWarnings("nls")
@Override
public String toString() {
StringBuilder sb = new StringBuilder();
sb.append("ViewerDescriptor [");
if (fViewerClass != null) {
sb.append("viewerClass=");
sb.append(fViewerClass);
sb.append(", ");
}
if (fViewerCreator != null) {
sb.append("viewerCreator=");
sb.append(fViewerCreator);
sb.append(", ");
}
String viewerClass = getViewerClass();
if (viewerClass != null) {
sb.append("viewerClass=");
sb.append(viewerClass);
sb.append(", ");
}
if (fConfiguration != null) {
sb.append("configuration=");
sb.append(fConfiguration);
}
sb.append("]");
return sb.toString();
}

}
10 changes: 10 additions & 0 deletions team/bundles/org.eclipse.compare/schema/contentMergeViewers.exsd
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,16 @@ content merge viewer and implements &lt;samp&gt;org.eclipse.compare.IViewerCreat
</appInfo>
</annotation>
</attribute>
<attribute name="linkedEditor" type="string">
<annotation>
<documentation>
Since 3.11. Editor id to consider editor content type associations to be used also for content type bindings of this viewer
</documentation>
<appInfo>
<meta.attribute kind="identifier" basedOn="org.eclipse.ui.editors/editor/@id"/>
</appInfo>
</annotation>
</attribute>
</complexType>
</element>

Expand Down

0 comments on commit 196b3d2

Please sign in to comment.