avoid caret visual position changes on parameter hints adding (IDEA-115424)
authorDmitry Batrak <Dmitry.Batrak@jetbrains.com>
Mon, 24 Oct 2016 14:55:30 +0000 (17:55 +0300)
committerDmitry Batrak <Dmitry.Batrak@jetbrains.com>
Mon, 24 Oct 2016 14:56:23 +0000 (17:56 +0300)
platform/lang-impl/src/com/intellij/codeInsight/actions/ReformatCodeProcessor.java
platform/lang-impl/src/com/intellij/codeInsight/hints/ParameterHintsPassFactory.java
platform/platform-impl/src/com/intellij/openapi/editor/ex/util/CaretVisualPositionKeeper.java [new file with mode: 0644]

index 0e27a8bbe8504c81d728c8d8530e13f8fe96e641..4bf4864316a1a1eed71d2bdda20d3fce9aa72efc 100644 (file)
@@ -20,9 +20,8 @@ import com.intellij.codeInsight.CodeInsightBundle;
 import com.intellij.formatting.FormattingProgressTask;
 import com.intellij.openapi.diagnostic.Logger;
 import com.intellij.openapi.editor.Document;
-import com.intellij.openapi.editor.Editor;
-import com.intellij.openapi.editor.EditorFactory;
 import com.intellij.openapi.editor.SelectionModel;
+import com.intellij.openapi.editor.ex.util.CaretVisualPositionKeeper;
 import com.intellij.openapi.module.Module;
 import com.intellij.openapi.project.Project;
 import com.intellij.openapi.util.TextRange;
@@ -37,11 +36,8 @@ import com.intellij.util.diff.FilesTooBigForDiffException;
 import org.jetbrains.annotations.NotNull;
 import org.jetbrains.annotations.Nullable;
 
-import java.awt.*;
 import java.util.ArrayList;
 import java.util.Collection;
-import java.util.HashMap;
-import java.util.Map;
 import java.util.concurrent.FutureTask;
 
 public class ReformatCodeProcessor extends AbstractLayoutCodeProcessor {
@@ -172,32 +168,4 @@ public class ReformatCodeProcessor extends AbstractLayoutCodeProcessor {
     
     return !myRanges.isEmpty() ? myRanges : ContainerUtil.newArrayList(file.getTextRange());
   }
-
-  private static class CaretVisualPositionKeeper {
-    private final Map<Editor, Integer> myCaretRelativeVerticalPositions = new HashMap<>();
-    
-    private CaretVisualPositionKeeper(@Nullable Document document) {
-      if (document == null) return;
-  
-      Editor[] editors = EditorFactory.getInstance().getEditors(document);
-      for (Editor editor : editors) {
-        Rectangle visibleArea = editor.getScrollingModel().getVisibleArea();
-        Point pos = editor.visualPositionToXY(editor.getCaretModel().getVisualPosition());
-        int relativePosition = pos.y - visibleArea.y;
-        myCaretRelativeVerticalPositions.put(editor, relativePosition);
-      }
-    }
-    
-    private void restoreOriginalLocation() {
-      for (Map.Entry<Editor, Integer> e : myCaretRelativeVerticalPositions.entrySet()) {
-        Editor editor = e.getKey();
-        int relativePosition = e.getValue();
-        Point caretLocation = editor.visualPositionToXY(editor.getCaretModel().getVisualPosition());
-        int scrollOffset = caretLocation.y - relativePosition;
-        editor.getScrollingModel().disableAnimation();
-        editor.getScrollingModel().scrollVertically(scrollOffset);
-        editor.getScrollingModel().enableAnimation();
-      }
-    }
-  }
 }
\ No newline at end of file
index fcd21aaf9b58a98d71dfb8eb733c157e648e3205..fd49d5736ed5f8f1019d4497525ffdd9c375bf75 100644 (file)
@@ -29,6 +29,7 @@ import com.intellij.openapi.editor.Editor;
 import com.intellij.openapi.editor.Inlay;
 import com.intellij.openapi.editor.VisualPosition;
 import com.intellij.openapi.editor.ex.EditorSettingsExternalizable;
+import com.intellij.openapi.editor.ex.util.CaretVisualPositionKeeper;
 import com.intellij.openapi.progress.ProgressIndicator;
 import com.intellij.openapi.project.Project;
 import com.intellij.openapi.util.Key;
@@ -107,6 +108,7 @@ public class ParameterHintsPassFactory extends AbstractProjectComponent implemen
       ParameterHintsPresentationManager presentationManager = ParameterHintsPresentationManager.getInstance();
       Set<String> removedHints = new HashSet<>();
       TIntObjectHashMap<Caret> caretMap = new TIntObjectHashMap<>();
+      CaretVisualPositionKeeper keeper = new CaretVisualPositionKeeper(myEditor);
       for (Caret caret : myEditor.getCaretModel().getAllCarets()) {
         caretMap.put(caret.getOffset(), caret);
       }
@@ -131,6 +133,7 @@ public class ParameterHintsPassFactory extends AbstractProjectComponent implemen
         String text = e.getValue();
         presentationManager.addHint(myEditor, offset, text, !firstTime && !removedHints.contains(text));
       }
+      keeper.restoreOriginalLocation();
       myEditor.putUserData(REPEATED_PASS, Boolean.TRUE);
     }
 
diff --git a/platform/platform-impl/src/com/intellij/openapi/editor/ex/util/CaretVisualPositionKeeper.java b/platform/platform-impl/src/com/intellij/openapi/editor/ex/util/CaretVisualPositionKeeper.java
new file mode 100644 (file)
index 0000000..c919ed5
--- /dev/null
@@ -0,0 +1,62 @@
+/*
+ * Copyright 2000-2016 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.editor.ex.util;
+
+import com.intellij.openapi.editor.Document;
+import com.intellij.openapi.editor.Editor;
+import com.intellij.openapi.editor.EditorFactory;
+import org.jetbrains.annotations.Nullable;
+
+import java.awt.*;
+import java.util.HashMap;
+import java.util.Map;
+
+/**
+ * Allows to keep caret's position in editor window at the same vertical position for operations, that can potentially move caret.
+ * An instance of this class is to be created before the operation, method {@link #restoreOriginalLocation()} should be called after it.
+ */
+public class CaretVisualPositionKeeper {
+  private final Map<Editor, Integer> myCaretRelativeVerticalPositions = new HashMap<>();
+
+  public CaretVisualPositionKeeper(@Nullable Editor editor) {
+    this(editor == null ? Editor.EMPTY_ARRAY : new Editor[]{editor});
+  }
+
+  public CaretVisualPositionKeeper(@Nullable Document document) {
+    this(document == null ? Editor.EMPTY_ARRAY : EditorFactory.getInstance().getEditors(document));
+  }
+
+  private CaretVisualPositionKeeper(Editor[] editors) {
+    for (Editor editor : editors) {
+      Rectangle visibleArea = editor.getScrollingModel().getVisibleArea();
+      Point pos = editor.visualPositionToXY(editor.getCaretModel().getVisualPosition());
+      int relativePosition = pos.y - visibleArea.y;
+      myCaretRelativeVerticalPositions.put(editor, relativePosition);
+    }
+  }
+
+  public void restoreOriginalLocation() {
+    for (Map.Entry<Editor, Integer> e : myCaretRelativeVerticalPositions.entrySet()) {
+      Editor editor = e.getKey();
+      int relativePosition = e.getValue();
+      Point caretLocation = editor.visualPositionToXY(editor.getCaretModel().getVisualPosition());
+      int scrollOffset = caretLocation.y - relativePosition;
+      editor.getScrollingModel().disableAnimation();
+      editor.getScrollingModel().scrollVertically(scrollOffset);
+      editor.getScrollingModel().enableAnimation();
+    }
+  }
+}