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-platform/eclipse.platform.ui#1747
  • Loading branch information
iloveeclipse committed Apr 3, 2024
1 parent dbb36aa commit 6de5471
Show file tree
Hide file tree
Showing 6 changed files with 159 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,6 +196,10 @@ List<T> searchAll(String extension) {
return fExtensionMap.get(normalizeCase(extension));
return null;
}

Collection<T> getAll() {
return fIdMap == null ? Collections.emptySet() : fIdMap.values();
}
}

/** Status code describing an internal error */
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 Down Expand Up @@ -1016,6 +1024,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 +1063,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 +1081,79 @@ 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();
}
}

LinkedHashSet<ViewerDescriptor> viewers = fContentMergeViewers.getAll().stream()
.filter(vd -> vd.getLinkedEditorId() != null).collect(Collectors.toCollection(LinkedHashSet::new));
if (viewers.isEmpty()) {
return Collections.emptySet();
}

IEditorRegistry editorReg = PlatformUI.getWorkbench().getEditorRegistry();
LinkedHashSet<ViewerDescriptor> result = new LinkedHashSet<>();
IEditorDescriptor[] editors = editorReg.getEditors(fileName, contentType);
for (IEditorDescriptor ed : editors) {
addLinkedEditorContentTypes(viewers, firstIsEnough, ed.getId(), result);
if (firstIsEnough && !result.isEmpty()) {
return result;
}
}
return result;
}

private void addLinkedEditorContentTypes(LinkedHashSet<ViewerDescriptor> viewers, boolean firstIsEnough,
String editorId, Set<ViewerDescriptor> result) {
Stream<ViewerDescriptor> stream = viewers.stream().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 +1560,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();
}

}
13 changes: 12 additions & 1 deletion team/bundles/org.eclipse.compare/schema/contentMergeViewers.exsd
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,17 @@ 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 while searching for a viewer matching a content type.
If the specified &quot;linked&quot; editor has content type associations, they will be also considered as possible bindings for this viewer. This is useful in cases where viewer supports same content types as &quot;linked&quot; editor (like in generic editor).
</documentation>
<appInfo>
<meta.attribute kind="identifier" basedOn="org.eclipse.ui.editors/editor/@id"/>
</appInfo>
</annotation>
</attribute>
</complexType>
</element>

Expand Down Expand Up @@ -123,6 +134,7 @@ content merge viewer and implements &lt;samp&gt;org.eclipse.compare.IViewerCreat
</complexType>
</element>


<annotation>
<appInfo>
<meta.section type="examples"/>
Expand Down Expand Up @@ -154,7 +166,6 @@ for text files (extension &quot;txt&quot;):
</documentation>
</annotation>


<annotation>
<appInfo>
<meta.section type="implementation"/>
Expand Down

0 comments on commit 6de5471

Please sign in to comment.