From f6f7db0bcf364354965acaaa3c70bf5a54a8acbf Mon Sep 17 00:00:00 2001 From: Aleksey Pivovarov Date: Fri, 22 Apr 2016 13:28:23 +0300 Subject: [PATCH] patch: apply somehow - avoid unnecessary scrolling --- .../diff/tools/util/SyncScrollSupport.java | 15 ++++++++----- .../changes/patch/tool/ApplyPatchChange.java | 22 +++++++++++-------- 2 files changed, 22 insertions(+), 15 deletions(-) diff --git a/platform/diff-impl/src/com/intellij/diff/tools/util/SyncScrollSupport.java b/platform/diff-impl/src/com/intellij/diff/tools/util/SyncScrollSupport.java index 8a27215bcc2c..1bd2bcbd8b33 100644 --- a/platform/diff-impl/src/com/intellij/diff/tools/util/SyncScrollSupport.java +++ b/platform/diff-impl/src/com/intellij/diff/tools/util/SyncScrollSupport.java @@ -242,7 +242,7 @@ public class SyncScrollSupport { assert startLines.length == count; assert endLines.length == count; - final int[] offsets = getTargetOffsets(editors.toArray(new Editor[count]), startLines, endLines); + final int[] offsets = getTargetOffsets(editors.toArray(new Editor[count]), startLines, endLines, -1); final int[] startOffsets = new int[count]; for (int i = 0; i < count; i++) { @@ -412,14 +412,16 @@ public class SyncScrollSupport { @NotNull public static int[] getTargetOffsets(@NotNull Editor editor1, @NotNull Editor editor2, - int startLine1, int endLine1, int startLine2, int endLine2) { + int startLine1, int endLine1, int startLine2, int endLine2, + int preferredTopShift) { return getTargetOffsets(new Editor[]{editor1, editor2}, new int[]{startLine1, startLine2}, - new int[]{endLine1, endLine2}); + new int[]{endLine1, endLine2}, + preferredTopShift); } @NotNull - private static int[] getTargetOffsets(@NotNull Editor[] editors, int[] startLines, int[] endLines) { + private static int[] getTargetOffsets(@NotNull Editor[] editors, int[] startLines, int[] endLines, int preferredTopShift) { int count = editors.length; assert startLines.length == count; assert endLines.length == count; @@ -444,11 +446,12 @@ public class SyncScrollSupport { // 'shift' here - distance between editor's top and first line of range - // make whole range visible. If possible, locate it at 'center' (1/3 of height) + // make whole range visible. If possible, locate it at 'center' (1/3 of height) (or at 'preferredTopShift' if it was specified) // If can't show whole range - show as much as we can boolean canShow = 2 * gapLines[i] + rangeHeights[i] <= editorHeights[i]; - topShifts[i] = canShow ? Math.min(editorHeights[i] - gapLines[i] - rangeHeights[i], editorHeights[i] / 3) : gapLines[i]; + int shift = preferredTopShift != -1 ? preferredTopShift : editorHeights[i] / 3; + topShifts[i] = canShow ? Math.min(editorHeights[i] - gapLines[i] - rangeHeights[i], shift) : gapLines[i]; } int topShift = min(topShifts); diff --git a/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/patch/tool/ApplyPatchChange.java b/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/patch/tool/ApplyPatchChange.java index 6c54b55a37fc..b676f2b14271 100644 --- a/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/patch/tool/ApplyPatchChange.java +++ b/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/patch/tool/ApplyPatchChange.java @@ -19,12 +19,10 @@ import com.intellij.diff.comparison.ByWord; import com.intellij.diff.comparison.ComparisonPolicy; import com.intellij.diff.fragments.DiffFragment; import com.intellij.diff.tools.util.SyncScrollSupport; -import com.intellij.diff.util.DiffDrawUtil; -import com.intellij.diff.util.DiffUtil; -import com.intellij.diff.util.LineRange; -import com.intellij.diff.util.TextDiffType; +import com.intellij.diff.util.*; import com.intellij.openapi.editor.Document; import com.intellij.openapi.editor.Editor; +import com.intellij.openapi.editor.LogicalPosition; import com.intellij.openapi.editor.ex.DocumentEx; import com.intellij.openapi.editor.ex.EditorEx; import com.intellij.openapi.editor.ex.MarkupModelEx; @@ -102,21 +100,27 @@ class ApplyPatchChange { RangeHighlighter highlighter = markupModel.addRangeHighlighter(textRange.getStartOffset(), textRange.getEndOffset(), HighlighterLayer.LAST, null, HighlighterTargetArea.LINES_IN_RANGE); - PairConsumer clickHandler = myAppliedTo != null ? (ed, e) -> handleStatusClick(editor) : null; + PairConsumer clickHandler = myAppliedTo != null ? (e, event) -> handleStatusClick(editor, event) : null; highlighter.setLineMarkerRenderer(LineStatusMarkerRenderer.createRenderer(line1, line2, color, clickHandler)); myHighlighters.add(highlighter); } - private void handleStatusClick(@NotNull EditorEx editor) { - // TODO: avoid scrolling clicked editor, if possible - // TODO: blink ranges, to make them more noticeable ? + private void handleStatusClick(@NotNull EditorEx editor, @NotNull MouseEvent event) { assert myAppliedTo != null; EditorEx resultEditor = myViewer.getResultEditor(); EditorEx patchEditor = myViewer.getPatchEditor(); + + Side clickSide = Side.fromLeft(editor == resultEditor); + int clickLine = clickSide.select(myAppliedTo.start, myPatchInsertionRange.start); + EditorEx clickEditor = clickSide.select(resultEditor, patchEditor); + int targetY = clickEditor.logicalPositionToXY(new LogicalPosition(clickLine, 0)).y; + int topShift = targetY - clickEditor.getScrollingModel().getVerticalScrollOffset(); + int[] offsets = SyncScrollSupport.getTargetOffsets(resultEditor, patchEditor, myAppliedTo.start, myAppliedTo.end, - myPatchInsertionRange.start, myPatchInsertionRange.end); + myPatchInsertionRange.start, myPatchInsertionRange.end, + topShift); DiffUtil.scrollToPoint(resultEditor, new Point(0, offsets[0]), false); DiffUtil.scrollToPoint(patchEditor, new Point(0, offsets[1]), false); }