diff: Add option to reduce diff granularity and to turn diff highlighting off.

This commit is contained in:
Aleksey Pivovarov
2014-02-03 16:35:03 +04:00
parent d30c09e75e
commit a1ce98ffb5
9 changed files with 184 additions and 13 deletions
@@ -0,0 +1,103 @@
/*
* Copyright 2000-2014 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.intellij.openapi.diff.actions;
import com.intellij.CommonBundle;
import com.intellij.openapi.actionSystem.AnAction;
import com.intellij.openapi.actionSystem.AnActionEvent;
import com.intellij.openapi.actionSystem.DefaultActionGroup;
import com.intellij.openapi.actionSystem.Presentation;
import com.intellij.openapi.actionSystem.ex.ComboBoxAction;
import com.intellij.openapi.diff.DiffBundle;
import com.intellij.openapi.diff.ex.DiffPanelEx;
import com.intellij.openapi.diff.impl.DiffPanelImpl;
import com.intellij.openapi.diff.impl.processing.HighlightMode;
import com.intellij.openapi.project.DumbAware;
import com.intellij.util.containers.HashMap;
import org.jetbrains.annotations.NotNull;
import javax.swing.*;
import java.awt.*;
import java.util.Map;
public class HighlightModeAction extends ComboBoxAction implements DumbAware {
private final Map<HighlightMode, AnAction> myActions = new HashMap<HighlightMode, AnAction>();
private static final HighlightMode[] ourActionOrder =
new HighlightMode[]{HighlightMode.BY_WORD, HighlightMode.BY_LINE, HighlightMode.NO_HIGHLIGHTING};
public HighlightModeAction() {
myActions.put(HighlightMode.BY_WORD,
new SetHighlightModeAction(DiffBundle.message("diff.acton.highlight.mode.action.by.word"), HighlightMode.BY_WORD));
myActions.put(HighlightMode.BY_LINE,
new SetHighlightModeAction(DiffBundle.message("diff.acton.highlight.mode.action.by.line"), HighlightMode.BY_LINE));
myActions.put(HighlightMode.NO_HIGHLIGHTING,
new SetHighlightModeAction(DiffBundle.message("diff.acton.highlight.mode.action.no.highlighting"),
HighlightMode.NO_HIGHLIGHTING));
}
@Override
public JComponent createCustomComponent(final Presentation presentation) {
JPanel panel = new JPanel(new BorderLayout());
final JLabel label = new JLabel(CommonBundle.message("diff.acton.highlight.mode.action.name"));
label.setBorder(BorderFactory.createEmptyBorder(0, 4, 0, 4));
panel.add(label, BorderLayout.WEST);
panel.add(super.createCustomComponent(presentation), BorderLayout.CENTER);
return panel;
}
@NotNull
protected DefaultActionGroup createPopupActionGroup(JComponent button) {
DefaultActionGroup actionGroup = new DefaultActionGroup();
for (HighlightMode comparisonPolicy : ourActionOrder) {
actionGroup.add(myActions.get(comparisonPolicy));
}
return actionGroup;
}
public void update(AnActionEvent e) {
super.update(e);
Presentation presentation = e.getPresentation();
DiffPanelEx diffPanel = DiffPanelImpl.fromDataContext(e.getDataContext());
if (diffPanel != null && diffPanel.getComponent().isDisplayable()) {
AnAction action = myActions.get(diffPanel.getHighlightMode());
Presentation templatePresentation = action.getTemplatePresentation();
presentation.setIcon(templatePresentation.getIcon());
presentation.setText(templatePresentation.getText());
presentation.setEnabled(true);
}
else {
presentation.setIcon(null);
presentation.setText(DiffBundle.message("diff.acton.highlight.mode.not.available.action.name"));
presentation.setEnabled(false);
}
}
private static class SetHighlightModeAction extends AnAction implements DumbAware {
private final HighlightMode myHighlightMode;
public SetHighlightModeAction(String text, HighlightMode mode) {
super(text);
myHighlightMode = mode;
}
public void actionPerformed(AnActionEvent e) {
final DiffPanelImpl diffPanel = DiffPanelImpl.fromDataContext(e.getDataContext());
if (diffPanel != null) {
diffPanel.setHighlightMode(myHighlightMode);
}
}
}
}
@@ -27,6 +27,7 @@ package com.intellij.openapi.diff.ex;
import com.intellij.openapi.Disposable;
import com.intellij.openapi.diff.DiffPanel;
import com.intellij.openapi.diff.impl.ComparisonPolicy;
import com.intellij.openapi.diff.impl.processing.HighlightMode;
import com.intellij.openapi.editor.Editor;
import org.jetbrains.annotations.Nullable;
@@ -45,4 +46,8 @@ public interface DiffPanelEx extends DiffPanel, Disposable {
void setAutoScrollEnabled(boolean enabled);
boolean isAutoScrollEnabled();
void setHighlightMode(HighlightMode highlightMode);
HighlightMode getHighlightMode();
}
@@ -34,6 +34,7 @@ import com.intellij.openapi.diff.impl.fragments.Fragment;
import com.intellij.openapi.diff.impl.fragments.FragmentList;
import com.intellij.openapi.diff.impl.highlighting.DiffPanelState;
import com.intellij.openapi.diff.impl.highlighting.FragmentSide;
import com.intellij.openapi.diff.impl.processing.HighlightMode;
import com.intellij.openapi.diff.impl.processing.HorizontalDiffSplitter;
import com.intellij.openapi.diff.impl.settings.DiffMergeEditorSetting;
import com.intellij.openapi.diff.impl.settings.DiffMergeSettings;
@@ -483,6 +484,15 @@ public class DiffPanelImpl implements DiffPanelEx, ContentChangeListener, TwoSid
setComparisonPolicy(comparisonPolicy, true);
}
public void setHighlightMode(HighlightMode highlightMode) {
myData.setHighlightMode(highlightMode);
rediff();
}
public HighlightMode getHighlightMode() {
return myData.getHighlightMode();
}
public Rediffers getDiffUpdater() {
return myDiffUpdater;
}
@@ -24,6 +24,7 @@ import com.intellij.openapi.diff.impl.fragments.FragmentList;
import com.intellij.openapi.diff.impl.fragments.FragmentListImpl;
import com.intellij.openapi.diff.impl.fragments.LineFragment;
import com.intellij.openapi.diff.impl.processing.DiffPolicy;
import com.intellij.openapi.diff.impl.processing.HighlightMode;
import com.intellij.openapi.diff.impl.processing.TextCompareProcessor;
import com.intellij.openapi.diff.impl.splitter.LineBlocks;
import com.intellij.openapi.project.Project;
@@ -37,6 +38,7 @@ import java.util.Iterator;
public abstract class SimpleDiffPanelState implements Disposable {
protected ComparisonPolicy myComparisonPolicy = ComparisonPolicy.DEFAULT;
protected DiffPolicy myDiffPolicy;
protected HighlightMode myHighlightMode;
protected final EditorPlaceHolder myAppender1;
protected final EditorPlaceHolder myAppender2;
protected FragmentList myFragmentList = FragmentList.EMPTY;
@@ -47,6 +49,7 @@ public abstract class SimpleDiffPanelState implements Disposable {
myAppender2 = createEditorWrapper(project, changeListener, FragmentSide.SIDE2);
myProject = project;
myDiffPolicy = DiffPolicy.LINES_WO_FORMATTING;
myHighlightMode = HighlightMode.BY_WORD;
Disposer.register(parentDisposable, this);
}
@@ -72,6 +75,14 @@ public abstract class SimpleDiffPanelState implements Disposable {
return myComparisonPolicy;
}
public HighlightMode getHighlightMode() {
return myHighlightMode;
}
public void setHighlightMode(HighlightMode highlightMode) {
myHighlightMode = highlightMode;
}
public void dispose() {
}
@@ -105,7 +116,12 @@ public abstract class SimpleDiffPanelState implements Disposable {
return LineBlocks.EMPTY;
}
return addMarkup(new TextCompareProcessor(myComparisonPolicy, myDiffPolicy).process(myAppender1.getText(), myAppender2.getText()));
if (myHighlightMode == HighlightMode.NO_HIGHLIGHTING) {
return LineBlocks.fromLineFragments(new ArrayList<LineFragment>());
}
return addMarkup(new TextCompareProcessor(myComparisonPolicy, myDiffPolicy, myHighlightMode == HighlightMode.BY_WORD)
.process(myAppender1.getText(), myAppender2.getText()));
}
public Project getProject() { return myProject; }
@@ -32,28 +32,38 @@ public class TextCompareProcessor {
private static final Logger LOG = Logger.getInstance("#com.intellij.openapi.diff.impl.processing.Processor");
private final DiffPolicy myDiffPolicy;
@NotNull private final ComparisonPolicy myComparisonPolicy;
private final boolean mySearchForSubFragments;
public TextCompareProcessor(@NotNull ComparisonPolicy comparisonPolicy, final DiffPolicy diffPolicy) {
public TextCompareProcessor(@NotNull ComparisonPolicy comparisonPolicy,
final DiffPolicy diffPolicy,
boolean searchForSubFragments) {
myComparisonPolicy = comparisonPolicy;
myDiffPolicy = diffPolicy;
mySearchForSubFragments = searchForSubFragments;
}
public TextCompareProcessor(ComparisonPolicy comparisonPolicy) {
public TextCompareProcessor(@NotNull ComparisonPolicy comparisonPolicy, final DiffPolicy diffPolicy) {
this(comparisonPolicy, diffPolicy, true);
}
public TextCompareProcessor(@NotNull ComparisonPolicy comparisonPolicy) {
this(comparisonPolicy, DiffPolicy.LINES_WO_FORMATTING);
}
public ArrayList<LineFragment> process(String text1, String text2) throws FilesTooBigForDiffException {
DiffFragment[] woFormattingBlocks = myDiffPolicy.buildFragments(text1, text2);
DiffFragment[] step1lineFragments = new DiffCorrection.TrueLineBlocks(myComparisonPolicy).
correctAndNormalize(woFormattingBlocks);
DiffFragment[] step1lineFragments = new DiffCorrection.TrueLineBlocks(myComparisonPolicy).correctAndNormalize(woFormattingBlocks);
ArrayList<LineFragment> lineBlocks = new DiffFragmentsProcessor().process(step1lineFragments);
for (LineFragment lineBlock : lineBlocks) {
if (lineBlock.isOneSide() || lineBlock.isEqual()) continue;
String subText1 = lineBlock.getText(text1, FragmentSide.SIDE1);
String subText2 = lineBlock.getText(text2, FragmentSide.SIDE2);
ArrayList<LineFragment> subFragments = findSubFragments(subText1, subText2);
lineBlock.setChildren(new ArrayList<Fragment>(subFragments));
lineBlock.adjustTypeFromChildrenTypes();
if (mySearchForSubFragments) {
for (LineFragment lineBlock : lineBlocks) {
if (lineBlock.isOneSide() || lineBlock.isEqual()) continue;
String subText1 = lineBlock.getText(text1, FragmentSide.SIDE1);
String subText2 = lineBlock.getText(text2, FragmentSide.SIDE2);
ArrayList<LineFragment> subFragments = findSubFragments(subText1, subText2);
lineBlock.setChildren(new ArrayList<Fragment>(subFragments));
lineBlock.adjustTypeFromChildrenTypes();
}
}
return lineBlocks;
}
@@ -175,4 +175,5 @@ This may lead to incorrect behaviour. Proxy should be set in Settings | HTTP Pro
This JVM property is old and its usage is not recommended by Oracle.\n\
\n(Note: It could have been assigned by some code dynamically.)
label.proxy.exceptions.text=Example\: *.domain.com, 192.168.*
checkbox.automatic.proxy.configuration.url=Automatic proxy configuration URL\:
checkbox.automatic.proxy.configuration.url=Automatic proxy configuration URL\:
diff.acton.highlight.mode.action.name=Highlighting Mode
@@ -83,3 +83,7 @@ diff.content.selected.value=Selected Value
diff.clipboard.vs.value.dialog.title=Clipboard vs Selected Value
diff.can.not.show.unknown=Can not show diff for unknown file type
diff.acton.highlight.mode.action.by.word=By Word
diff.acton.highlight.mode.action.by.line=By Line
diff.acton.highlight.mode.action.no.highlighting=No Highlighting
diff.acton.highlight.mode.not.available.action.name=<Not available>
@@ -550,6 +550,8 @@
<reference ref="NextDiff"/>
<separator/>
<action id="Diff.IgnoreWhitespace" class="com.intellij.openapi.diff.actions.IgnoreWhiteSpacesAction" text=""/>
<separator/>
<action id="Diff.HighlightMode" class="com.intellij.openapi.diff.actions.HighlightModeAction" text=""/>
</group>
<group id="ChangeScheme">
@@ -0,0 +1,20 @@
/*
* Copyright 2000-2014 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.intellij.openapi.diff.impl.processing;
public enum HighlightMode {
BY_WORD, BY_LINE, NO_HIGHLIGHTING
}