Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion team/bundles/org.eclipse.compare/META-INF/MANIFEST.MF
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,8 @@ Export-Package: org.eclipse.compare,
org.eclipse.compare.internal.merge;x-internal:=true,
org.eclipse.compare.internal.patch;x-friends:="org.eclipse.team.ui",
org.eclipse.compare.patch,
org.eclipse.compare.structuremergeviewer
org.eclipse.compare.structuremergeviewer,
org.eclipse.compare.unifieddiff
Require-Bundle: org.eclipse.ui;bundle-version="[3.206.0,4.0.0)",
org.eclipse.core.resources;bundle-version="[3.4.0,4.0.0)",
org.eclipse.jface.text;bundle-version="[3.8.0,4.0.0)",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2063,9 +2063,15 @@ protected void handleDispose(DisposeEvent event) {
fBirdsEyeCanvas= null;
fSummaryHeader= null;

fAncestorContributor.unsetDocument(fAncestor);
fLeftContributor.unsetDocument(fLeft);
fRightContributor.unsetDocument(fRight);
if (fAncestorContributor != null) {
fAncestorContributor.unsetDocument(fAncestor);
}
if (fLeftContributor != null) {
fLeftContributor.unsetDocument(fLeft);
}
if (fRightContributor != null) {
fRightContributor.unsetDocument(fRight);
}

disconnect(fLeftContributor);
disconnect(fRightContributor);
Expand Down Expand Up @@ -5563,6 +5569,12 @@ public int getChangesCount() {
}
};
}
if (adapter == IDocumentMergerInput.class) {
if (fMerger == null) {
return null;
}
return (T) fMerger.getInput();
}
if (adapter == OutlineViewerCreator.class) {
if (fOutlineViewerCreator == null) {
fOutlineViewerCreator = new InternalOutlineViewerCreator();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -123,6 +123,7 @@ private String loadPreviewContentFromFile(String key) {
public static final String ADDED_LINES_REGEX= PREFIX + "AddedLinesRegex"; //$NON-NLS-1$
public static final String REMOVED_LINES_REGEX= PREFIX + "RemovedLinesRegex"; //$NON-NLS-1$
public static final String SWAPPED = PREFIX + "Swapped"; //$NON-NLS-1$
public static final String UNIFIED_DIFF = PREFIX + "UnitifedDiff"; //$NON-NLS-1$


private IPropertyChangeListener fPreferenceChangeListener;
Expand Down Expand Up @@ -154,6 +155,7 @@ private String loadPreviewContentFromFile(String key) {
new OverlayPreferenceStore.OverlayKey(OverlayPreferenceStore.STRING, ICompareUIConstants.PREF_NAVIGATION_END_ACTION),
new OverlayPreferenceStore.OverlayKey(OverlayPreferenceStore.STRING, ICompareUIConstants.PREF_NAVIGATION_END_ACTION_LOCAL),
new OverlayPreferenceStore.OverlayKey(OverlayPreferenceStore.BOOLEAN, SWAPPED),
new OverlayPreferenceStore.OverlayKey(OverlayPreferenceStore.BOOLEAN, UNIFIED_DIFF),
};
private final List<FieldEditor> editors = new ArrayList<>();
private CTabItem fTextCompareTab;
Expand All @@ -177,6 +179,7 @@ public static void initDefaults(IPreferenceStore store) {
store.setDefault(ICompareUIConstants.PREF_NAVIGATION_END_ACTION, ICompareUIConstants.PREF_VALUE_PROMPT);
store.setDefault(ICompareUIConstants.PREF_NAVIGATION_END_ACTION_LOCAL, ICompareUIConstants.PREF_VALUE_LOOP);
store.setDefault(SWAPPED, false);
store.setDefault(UNIFIED_DIFF, false);
}

public ComparePreferencePage() {
Expand Down Expand Up @@ -286,6 +289,7 @@ private Control createGeneralPage(Composite parent) {
addCheckBox(composite, "ComparePreferencePage.structureCompare.label", OPEN_STRUCTURE_COMPARE, 0); //$NON-NLS-1$
addCheckBox(composite, "ComparePreferencePage.structureOutline.label", USE_OUTLINE_VIEW, 0); //$NON-NLS-1$
addCheckBox(composite, "ComparePreferencePage.ignoreWhitespace.label", IGNORE_WHITESPACE, 0); //$NON-NLS-1$
addCheckBox(composite, "ComparePreferencePage.unifiedDiff.label", UNIFIED_DIFF, 0); //$NON-NLS-1$

// a spacer
new Label(composite, SWT.NONE);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,9 @@
import java.io.InputStream;
import java.lang.reflect.InvocationTargetException;
import java.net.URL;
import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.Comparator;
Expand All @@ -43,13 +45,18 @@
import org.eclipse.compare.CompareConfiguration;
import org.eclipse.compare.CompareEditorInput;
import org.eclipse.compare.IResourceProvider;
import org.eclipse.compare.ISharedDocumentAdapter;
import org.eclipse.compare.IStreamContentAccessor;
import org.eclipse.compare.IStreamMerger;
import org.eclipse.compare.ITypedElement;
import org.eclipse.compare.internal.core.CompareSettings;
import org.eclipse.compare.internal.merge.DocumentMerger.IDocumentMergerInput;
import org.eclipse.compare.structuremergeviewer.ICompareInput;
import org.eclipse.compare.structuremergeviewer.IStructureCreator;
import org.eclipse.compare.structuremergeviewer.SharedDocumentAdapterWrapper;
import org.eclipse.compare.structuremergeviewer.StructureDiffViewer;
import org.eclipse.compare.unifieddiff.UnifiedDiff;
import org.eclipse.compare.unifieddiff.UnifiedDiff.UnifiedDiffMode;
import org.eclipse.core.resources.IFile;
import org.eclipse.core.resources.IResource;
import org.eclipse.core.runtime.Adapters;
Expand All @@ -62,12 +69,14 @@
import org.eclipse.core.runtime.IPath;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.NullProgressMonitor;
import org.eclipse.core.runtime.OperationCanceledException;
import org.eclipse.core.runtime.Platform;
import org.eclipse.core.runtime.Status;
import org.eclipse.core.runtime.content.IContentDescription;
import org.eclipse.core.runtime.content.IContentType;
import org.eclipse.core.runtime.content.IContentTypeManager;
import org.eclipse.jface.action.Action;
import org.eclipse.jface.dialogs.MessageDialog;
import org.eclipse.jface.operation.IRunnableContext;
import org.eclipse.jface.preference.IPreferenceStore;
Expand All @@ -76,6 +85,7 @@
import org.eclipse.jface.viewers.Viewer;
import org.eclipse.osgi.service.debug.DebugOptions;
import org.eclipse.osgi.service.debug.DebugOptionsListener;
import org.eclipse.swt.SWT;
import org.eclipse.swt.graphics.Image;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Display;
Expand All @@ -91,8 +101,10 @@
import org.eclipse.ui.IWorkbenchWindow;
import org.eclipse.ui.PartInitException;
import org.eclipse.ui.PlatformUI;
import org.eclipse.ui.ide.IDE;
import org.eclipse.ui.model.IWorkbenchAdapter;
import org.eclipse.ui.plugin.AbstractUIPlugin;
import org.eclipse.ui.texteditor.ITextEditor;
import org.osgi.framework.BundleContext;
import org.osgi.framework.ServiceRegistration;

Expand Down Expand Up @@ -560,6 +572,10 @@ public void openCompareEditor(final CompareEditorInput input,
CompareConfiguration configuration = input.getCompareConfiguration();
if (configuration != null) {
IPreferenceStore ps= configuration.getPreferenceStore();
boolean unifiedDiffEnabled = ps.getBoolean(ComparePreferencePage.UNIFIED_DIFF);
if (unifiedDiffEnabled && openUnifiedDiffInEditor(input, page, editor, activate)) {
return;
}
if (ps != null) {
configuration.setProperty(
CompareConfiguration.USE_OUTLINE_VIEW,
Expand All @@ -575,9 +591,155 @@ public void openCompareEditor(final CompareEditorInput input,
}
}

private void openEditorInBackground(final CompareEditorInput input,
final IWorkbenchPage page, final IReusableEditor editor,
final boolean activate) {
private boolean openUnifiedDiffInEditor(final CompareEditorInput input, final IWorkbenchPage page,
IReusableEditor editor, boolean activate) {
var unifiedDiffInput = canShowInUnifiedDiff(input);
if (unifiedDiffInput!=null) {
try {
IWorkbenchPage wpage = page != null ? page : getActivePage();
IEditorPart rightEditor = wpage.openEditor(unifiedDiffInput.right,
getEditorId(unifiedDiffInput.right, unifiedDiffInput.rightElement));
if (rightEditor instanceof ITextEditor rightTextEditor) {
Action openTwoWayCompare = new Action("Open in 2-way Compare Editor", SWT.PUSH) {
@Override
public void run() {
if (input.canRunAsJob()) {
openEditorInBackground(input, page, editor, activate);
} else {
if (compareResultOK(input, null)) {
internalOpenEditor(input, page, editor, activate);
}
}
}
};
UnifiedDiff
.create(rightTextEditor, getSourceOf(unifiedDiffInput.leftAcessor()),
UnifiedDiffMode.OVERLAY_READ_ONLY_MODE)
.additionalActions(Arrays.asList(openTwoWayCompare))
.ignoreWhitespaceContributorFactory(
t -> unifiedDiffInput.documentMergerInput != null
? unifiedDiffInput.documentMergerInput.createIgnoreWhitespaceContributor(t)
: Optional.empty())
.tokenComparatorFactory(t -> unifiedDiffInput.documentMergerInput != null
? unifiedDiffInput.documentMergerInput.createTokenComparator(t)
: null)
.ignoreWhiteSpace(Utilities.getBoolean(input.getCompareConfiguration(),
CompareConfiguration.IGNORE_WHITESPACE, false))
.open();
}
return true;
} catch (PartInitException e) {
CompareUIPlugin.log(e);
}
}
return false;
}

private String getSourceOf(IStreamContentAccessor right) {
try {
if (right == null) {
return ""; //$NON-NLS-1$
}
String result = toString(right.getContents());
return result;
} catch (CoreException | IOException e) {
CompareUIPlugin.log(e);
}
return null;
}

private static String toString(InputStream inputStream) throws IOException {
if (inputStream == null) {
return ""; //$NON-NLS-1$
}
try (inputStream) {
return new String(inputStream.readAllBytes(), StandardCharsets.UTF_8);
}
}

private static String getEditorId(IEditorInput editorInput, ITypedElement element) {
String fileName = editorInput.getName();
IEditorRegistry registry = PlatformUI.getWorkbench().getEditorRegistry();
IContentType type = getContentType(element);
IEditorDescriptor descriptor = registry.getDefaultEditor(fileName, type);
IDE.overrideDefaultEditorAssociation(editorInput, type, descriptor);
String id;
if (descriptor == null || descriptor.isOpenExternal()) {
id = "org.eclipse.ui.DefaultTextEditor"; //$NON-NLS-1$
} else {
id = descriptor.getId();
}
return id;
}

private static record LeftEditorInputAndRightStreamContentAccessor(IEditorInput left, ITypedElement leftElement,
IStreamContentAccessor leftAcessor, IEditorInput right, ITypedElement rightElement,
IStreamContentAccessor rightAcessor, IDocumentMergerInput documentMergerInput) {
}

private LeftEditorInputAndRightStreamContentAccessor canShowInUnifiedDiff(CompareEditorInput input) {
IDocumentMergerInput documentMergerInput = null;
try {
input.run(new NullProgressMonitor());
Object res = input.getCompareResult();
if (!(res instanceof ICompareInput compareInput)) {
return null;
}
ITypedElement ancestor = compareInput.getAncestor();
if (ancestor != null) {
return null;
}
// TODO (tm) do not support if one side is editable?
ITypedElement left = compareInput.getLeft();
if (left == null) {
return null;
}
ISharedDocumentAdapter leftSda = SharedDocumentAdapterWrapper.getAdapter(left);
if (leftSda == null) {
return null;
}
IEditorInput leftEditorInput = leftSda.getDocumentKey(left);
if (leftEditorInput == null) {
return null;
}
if (!(left instanceof IStreamContentAccessor leftSa)) {
return null;
}
ITypedElement right = compareInput.getRight();
if (right == null) {
return null;
}
ISharedDocumentAdapter rightSda = SharedDocumentAdapterWrapper.getAdapter(right);
if (rightSda == null) {
return null;
}
IEditorInput rightEditorInput = rightSda.getDocumentKey(right);
if (rightEditorInput == null) {
return null;
}
if (!(right instanceof IStreamContentAccessor rightSa)) {
return null;
}
var invisibleParent = new Shell();
try {
invisibleParent.setVisible(false);
var viewer = input.findContentViewer(new NullViewer(getShell()), compareInput, invisibleParent);
if (viewer instanceof IAdaptable adaptable) {
documentMergerInput = adaptable.getAdapter(IDocumentMergerInput.class);
}
} finally {
invisibleParent.dispose();
}
return new LeftEditorInputAndRightStreamContentAccessor(leftEditorInput, left, leftSa, rightEditorInput,
right, rightSa, documentMergerInput);
} catch (InvocationTargetException | InterruptedException e) {
CompareUIPlugin.log(e);
}
return null;
}

private void openEditorInBackground(final CompareEditorInput input, final IWorkbenchPage page,
final IReusableEditor editor, final boolean activate) {
internalOpenEditor(input, page, editor, activate);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1403,4 +1403,7 @@ private Diff findPrev(char contributor, List<Diff> v, int start, int end, boolea
return null;
}

public IDocumentMergerInput getInput() {
return fInput;
}
}
Loading
Loading