IDEA-146710 issue with multiple carets in column mode
authorDmitry Batrak <Dmitry.Batrak@jetbrains.com>
Fri, 30 Oct 2015 18:30:52 +0000 (21:30 +0300)
committerDmitry Batrak <Dmitry.Batrak@jetbrains.com>
Fri, 30 Oct 2015 18:32:30 +0000 (21:32 +0300)
platform/platform-impl/src/com/intellij/openapi/editor/actions/CloneCaretActionHandler.java
platform/platform-impl/src/com/intellij/openapi/editor/actions/MoveCaretDownWithSelectionAction.java
platform/platform-impl/src/com/intellij/openapi/editor/actions/MoveCaretUpWithSelectionAction.java
platform/platform-tests/testSrc/com/intellij/openapi/editor/EditorMultiCaretColumnModeTest.java
platform/testFramework/src/com/intellij/testFramework/EditorTestUtil.java

index 23f74dc88dc30193f828c407bd2fe3029a911c0b..f506ae20dd1143ea7399fa0e8f3628e8bf065314 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright 2000-2014 JetBrains s.r.o.
+ * Copyright 2000-2015 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.
@@ -26,6 +26,7 @@ import com.intellij.openapi.editor.actionSystem.EditorActionHandler;
 import com.intellij.openapi.keymap.impl.ModifierKeyDoubleClickHandler;
 import com.intellij.openapi.util.Key;
 import com.intellij.util.containers.HashSet;
+import org.jetbrains.annotations.NotNull;
 import org.jetbrains.annotations.Nullable;
 
 import java.util.ArrayList;
@@ -41,6 +42,8 @@ public class CloneCaretActionHandler extends EditorActionHandler {
     IdeActions.ACTION_EDITOR_CLONE_CARET_BELOW,
     IdeActions.ACTION_EDITOR_MOVE_CARET_LEFT_WITH_SELECTION,
     IdeActions.ACTION_EDITOR_MOVE_CARET_RIGHT_WITH_SELECTION,
+    IdeActions.ACTION_EDITOR_MOVE_CARET_UP_WITH_SELECTION,
+    IdeActions.ACTION_EDITOR_MOVE_CARET_DOWN_WITH_SELECTION,
     IdeActions.ACTION_EDITOR_MOVE_LINE_START_WITH_SELECTION,
     IdeActions.ACTION_EDITOR_MOVE_LINE_END_WITH_SELECTION
   ));
@@ -52,7 +55,7 @@ public class CloneCaretActionHandler extends EditorActionHandler {
   }
 
   @Override
-  public boolean isEnabled(Editor editor, DataContext dataContext) {
+  public boolean isEnabledForCaret(@NotNull Editor editor, @NotNull Caret caret, DataContext dataContext) {
     return editor.getCaretModel().supportsMultipleCarets();
   }
 
index 1025a4036ea8049743ac4233746980824f8ad808..c86baba68cef8b58ea5864ebfcddf84fdfff851c 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright 2000-2014 JetBrains s.r.o.
+ * Copyright 2000-2015 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.
@@ -45,7 +45,7 @@ public class MoveCaretDownWithSelectionAction extends EditorAction {
         return;
       }
       if (editor.isColumnMode()) {
-        EditorActionUtil.cloneOrRemoveCaret(editor, caret == null ? editor.getCaretModel().getPrimaryCaret() : caret, false);
+        new CloneCaretActionHandler(false).execute(editor, caret, dataContext);
       }
       else {
         CaretAction caretAction = new CaretAction() {
index e9afbcc566b6597bf17414a4681244b73a1cfc39..bb38d49161bd630b565756447ca41c07f9ceb914 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright 2000-2014 JetBrains s.r.o.
+ * Copyright 2000-2015 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.
@@ -43,7 +43,7 @@ public class MoveCaretUpWithSelectionAction extends EditorAction {
         return;
       }
       if (editor.isColumnMode()) {
-        EditorActionUtil.cloneOrRemoveCaret(editor, caret == null ? editor.getCaretModel().getPrimaryCaret() : caret, true);
+        new CloneCaretActionHandler(true).execute(editor, caret, dataContext);
       }
       else {
         CaretAction caretAction = new CaretAction() {
index c1a7671e51efe6a7e67b17e77b247368f95d108c..a1c81695fddffe85727debaffc9e2e6f54dcc2b1 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright 2000-2014 JetBrains s.r.o.
+ * Copyright 2000-2015 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.
@@ -15,6 +15,7 @@
  */
 package com.intellij.openapi.editor;
 
+import com.intellij.openapi.actionSystem.IdeActions;
 import com.intellij.openapi.editor.ex.EditorEx;
 import com.intellij.openapi.editor.impl.AbstractEditorTest;
 
@@ -26,32 +27,32 @@ public class EditorMultiCaretColumnModeTest extends AbstractEditorTest {
          "li<caret>ne2\n" +
          "line3");
 
-    executeAction("EditorDownWithSelection");
+    executeAction(IdeActions.ACTION_EDITOR_MOVE_CARET_DOWN_WITH_SELECTION);
     checkResultByText("line1\n" +
                       "li<caret>ne2\n" +
                       "li<caret>ne3");
 
-    executeAction("EditorDownWithSelection"); // hitting document bottom
+    executeAction(IdeActions.ACTION_EDITOR_MOVE_CARET_DOWN_WITH_SELECTION); // hitting document bottom
     checkResultByText("line1\n" +
                       "li<caret>ne2\n" +
                       "li<caret>ne3");
 
-    executeAction("EditorUpWithSelection");
+    executeAction(IdeActions.ACTION_EDITOR_MOVE_CARET_UP_WITH_SELECTION);
     checkResultByText("line1\n" +
                       "li<caret>ne2\n" +
                       "line3");
 
-    executeAction("EditorUpWithSelection"); // hitting document top
+    executeAction(IdeActions.ACTION_EDITOR_MOVE_CARET_UP_WITH_SELECTION); // hitting document top
     checkResultByText("li<caret>ne1\n" +
                       "li<caret>ne2\n" +
                       "line3");
 
-    executeAction("EditorUpWithSelection");
+    executeAction(IdeActions.ACTION_EDITOR_MOVE_CARET_UP_WITH_SELECTION);
     checkResultByText("li<caret>ne1\n" +
                       "li<caret>ne2\n" +
                       "line3");
 
-    executeAction("EditorDownWithSelection");
+    executeAction(IdeActions.ACTION_EDITOR_MOVE_CARET_DOWN_WITH_SELECTION);
     checkResultByText("line1\n" +
                       "li<caret>ne2\n" +
                       "line3");
@@ -76,7 +77,7 @@ public class EditorMultiCaretColumnModeTest extends AbstractEditorTest {
                       "line6\n" +
                       "line7");
 
-    executeAction("EditorUpWithSelection");
+    executeAction(IdeActions.ACTION_EDITOR_MOVE_CARET_UP_WITH_SELECTION);
     checkResultByText("line<caret>1\n" +
                       "line<caret>2\n" +
                       "line<caret>3\n" +
@@ -118,52 +119,52 @@ public class EditorMultiCaretColumnModeTest extends AbstractEditorTest {
          "li<caret>ne2\n" +
          "line3");
 
-    executeAction("EditorRightWithSelection");
+    executeAction(IdeActions.ACTION_EDITOR_MOVE_CARET_RIGHT_WITH_SELECTION);
     checkResultByText("line1\n" +
                       "li<selection>n<caret></selection>e2\n" +
                       "line3");
 
-    executeAction("EditorDownWithSelection");
+    executeAction(IdeActions.ACTION_EDITOR_MOVE_CARET_DOWN_WITH_SELECTION);
     checkResultByText("line1\n" +
                       "li<selection>n<caret></selection>e2\n" +
                       "li<selection>n<caret></selection>e3");
 
-    executeAction("EditorLeftWithSelection");
+    executeAction(IdeActions.ACTION_EDITOR_MOVE_CARET_LEFT_WITH_SELECTION);
     checkResultByText("line1\n" +
                       "li<caret>ne2\n" +
                       "li<caret>ne3");
 
-    executeAction("EditorLeftWithSelection");
+    executeAction(IdeActions.ACTION_EDITOR_MOVE_CARET_LEFT_WITH_SELECTION);
     checkResultByText("line1\n" +
                       "l<selection><caret>i</selection>ne2\n" +
                       "l<selection><caret>i</selection>ne3");
 
-    executeAction("EditorUpWithSelection");
+    executeAction(IdeActions.ACTION_EDITOR_MOVE_CARET_UP_WITH_SELECTION);
     checkResultByText("line1\n" +
                       "l<selection><caret>i</selection>ne2\n" +
                       "line3");
 
-    executeAction("EditorUpWithSelection");
+    executeAction(IdeActions.ACTION_EDITOR_MOVE_CARET_UP_WITH_SELECTION);
     checkResultByText("l<selection><caret>i</selection>ne1\n" +
                       "l<selection><caret>i</selection>ne2\n" +
                       "line3");
 
-    executeAction("EditorRightWithSelection");
+    executeAction(IdeActions.ACTION_EDITOR_MOVE_CARET_RIGHT_WITH_SELECTION);
     checkResultByText("li<caret>ne1\n" +
                       "li<caret>ne2\n" +
                       "line3");
 
-    executeAction("EditorRightWithSelection");
+    executeAction(IdeActions.ACTION_EDITOR_MOVE_CARET_RIGHT_WITH_SELECTION);
     checkResultByText("li<selection>n<caret></selection>e1\n" +
                       "li<selection>n<caret></selection>e2\n" +
                       "line3");
 
-    executeAction("EditorDownWithSelection");
+    executeAction(IdeActions.ACTION_EDITOR_MOVE_CARET_DOWN_WITH_SELECTION);
     checkResultByText("line1\n" +
                       "li<selection>n<caret></selection>e2\n" +
                       "line3");
 
-    executeAction("EditorLeftWithSelection");
+    executeAction(IdeActions.ACTION_EDITOR_MOVE_CARET_LEFT_WITH_SELECTION);
     checkResultByText("line1\n" +
                       "li<caret>ne2\n" +
                       "line3");
@@ -172,7 +173,7 @@ public class EditorMultiCaretColumnModeTest extends AbstractEditorTest {
   public void testSelectNextPrevWord() throws Exception {
     init("aaa aaa<caret>\n" +
          "bbbb bbbb");
-    executeAction("EditorDownWithSelection");
+    executeAction(IdeActions.ACTION_EDITOR_MOVE_CARET_DOWN_WITH_SELECTION);
     executeAction("EditorPreviousWordWithSelection");
     checkResultByText("aaa <selection><caret>aaa</selection>\n" +
                       "bbbb <selection><caret>bb</selection>bb");
@@ -204,7 +205,7 @@ public class EditorMultiCaretColumnModeTest extends AbstractEditorTest {
     mouse().clickAt(0, 4).dragTo(0, 3).release();
     verifyCaretsAndSelections(0, 3, 3, 4);
 
-    executeAction("EditorRightWithSelection");
+    executeAction(IdeActions.ACTION_EDITOR_MOVE_CARET_RIGHT_WITH_SELECTION);
     verifyCaretsAndSelections(0, 4, 4, 4);
   }
 
@@ -213,40 +214,40 @@ public class EditorMultiCaretColumnModeTest extends AbstractEditorTest {
     mouse().clickAt(1, 1);
     verifyCaretsAndSelections(1, 1, 1, 1);
 
-    executeAction("EditorRightWithSelection");
+    executeAction(IdeActions.ACTION_EDITOR_MOVE_CARET_RIGHT_WITH_SELECTION);
     verifyCaretsAndSelections(1, 2, 1, 2);
 
-    executeAction("EditorDownWithSelection");
+    executeAction(IdeActions.ACTION_EDITOR_MOVE_CARET_DOWN_WITH_SELECTION);
     verifyCaretsAndSelections(1, 2, 1, 2,
                               2, 2, 1, 2);
 
-    executeAction("EditorLeftWithSelection");
+    executeAction(IdeActions.ACTION_EDITOR_MOVE_CARET_LEFT_WITH_SELECTION);
     verifyCaretsAndSelections(1, 1, 1, 1,
                               2, 1, 1, 1);
 
-    executeAction("EditorLeftWithSelection");
+    executeAction(IdeActions.ACTION_EDITOR_MOVE_CARET_LEFT_WITH_SELECTION);
     verifyCaretsAndSelections(1, 0, 0, 1,
                               2, 0, 0, 1);
 
-    executeAction("EditorUpWithSelection");
+    executeAction(IdeActions.ACTION_EDITOR_MOVE_CARET_UP_WITH_SELECTION);
     verifyCaretsAndSelections(1, 0, 0, 1);
 
-    executeAction("EditorUpWithSelection");
+    executeAction(IdeActions.ACTION_EDITOR_MOVE_CARET_UP_WITH_SELECTION);
     verifyCaretsAndSelections(0, 0, 0, 1,
                               1, 0, 0, 1);
 
-    executeAction("EditorRightWithSelection");
+    executeAction(IdeActions.ACTION_EDITOR_MOVE_CARET_RIGHT_WITH_SELECTION);
     verifyCaretsAndSelections(0, 1, 1, 1,
                               1, 1, 1, 1);
 
-    executeAction("EditorRightWithSelection");
+    executeAction(IdeActions.ACTION_EDITOR_MOVE_CARET_RIGHT_WITH_SELECTION);
     verifyCaretsAndSelections(0, 2, 1, 2,
                               1, 2, 1, 2);
 
-    executeAction("EditorDownWithSelection");
+    executeAction(IdeActions.ACTION_EDITOR_MOVE_CARET_DOWN_WITH_SELECTION);
     verifyCaretsAndSelections(1, 2, 1, 2);
 
-    executeAction("EditorLeftWithSelection");
+    executeAction(IdeActions.ACTION_EDITOR_MOVE_CARET_LEFT_WITH_SELECTION);
     verifyCaretsAndSelections(1, 1, 1, 1);
   }
 
@@ -348,6 +349,80 @@ public class EditorMultiCaretColumnModeTest extends AbstractEditorTest {
     verifyCaretsAndSelections(1, 4, 2, 4,
                               2, 4, 2, 4);
   }
+  
+  public void testSeparatedCarets() throws Exception {
+    init("\n" +
+         "\n" +
+         "<caret>\n" +
+         "\n" +
+         "<caret>\n" +
+         "\n" +
+         "");
+    executeAction(IdeActions.ACTION_EDITOR_MOVE_CARET_DOWN_WITH_SELECTION);
+    checkResultByText("\n" +
+                      "\n" +
+                      "<caret>\n" +
+                      "<caret>\n" +
+                      "<caret>\n" +
+                      "<caret>\n" +
+                      "");
+    executeAction(IdeActions.ACTION_EDITOR_MOVE_CARET_DOWN_WITH_SELECTION);
+    checkResultByText("\n" +
+                      "\n" +
+                      "<caret>\n" +
+                      "<caret>\n" +
+                      "<caret>\n" +
+                      "<caret>\n" +
+                      "<caret>");
+    executeAction(IdeActions.ACTION_EDITOR_MOVE_CARET_UP_WITH_SELECTION);
+    checkResultByText("\n" +
+                      "\n" +
+                      "<caret>\n" +
+                      "<caret>\n" +
+                      "<caret>\n" +
+                      "<caret>\n" +
+                      "");
+    executeAction(IdeActions.ACTION_EDITOR_MOVE_CARET_UP_WITH_SELECTION);
+    checkResultByText("\n" +
+                      "\n" +
+                      "<caret>\n" +
+                      "\n" +
+                      "<caret>\n" +
+                      "\n" +
+                      "");
+    executeAction(IdeActions.ACTION_EDITOR_MOVE_CARET_UP_WITH_SELECTION);
+    checkResultByText("\n" +
+                      "<caret>\n" +
+                      "<caret>\n" +
+                      "<caret>\n" +
+                      "<caret>\n" +
+                      "\n" +
+                      "");
+    executeAction(IdeActions.ACTION_EDITOR_MOVE_CARET_UP_WITH_SELECTION);
+    checkResultByText("<caret>\n" +
+                      "<caret>\n" +
+                      "<caret>\n" +
+                      "<caret>\n" +
+                      "<caret>\n" +
+                      "\n" +
+                      "");
+    executeAction(IdeActions.ACTION_EDITOR_MOVE_CARET_DOWN_WITH_SELECTION);
+    checkResultByText("\n" +
+                      "<caret>\n" +
+                      "<caret>\n" +
+                      "<caret>\n" +
+                      "<caret>\n" +
+                      "\n" +
+                      "");
+    executeAction(IdeActions.ACTION_EDITOR_MOVE_CARET_DOWN_WITH_SELECTION);
+    checkResultByText("\n" +
+                      "\n" +
+                      "<caret>\n" +
+                      "\n" +
+                      "<caret>\n" +
+                      "\n" +
+                      "");
+  }
 
   private void init(String text) throws IOException {
     configureFromFileText(getTestName(false) + ".txt", text);
index 0c726148b7d306af8707d5a795f203af107f98ea..584fc27c42b767bff86ca648c78395f57d911a15 100644 (file)
@@ -18,6 +18,7 @@ package com.intellij.testFramework;
 import com.intellij.ide.DataManager;
 import com.intellij.injected.editor.EditorWindow;
 import com.intellij.openapi.actionSystem.*;
+import com.intellij.openapi.actionSystem.ex.ActionManagerEx;
 import com.intellij.openapi.actionSystem.impl.SimpleDataContext;
 import com.intellij.openapi.application.Result;
 import com.intellij.openapi.command.WriteCommandAction;
@@ -90,7 +91,8 @@ public class EditorTestUtil {
   }
 
   public static void executeAction(@NotNull Editor editor, @NotNull String actionId, boolean assertActionIsEnabled) {
-    AnAction action = ActionManager.getInstance().getAction(actionId);
+    ActionManagerEx actionManager = ActionManagerEx.getInstanceEx();
+    AnAction action = actionManager.getAction(actionId);
     assertNotNull(action);
     AnActionEvent event = AnActionEvent.createFromAnAction(action, null, "", createEditorContext(editor));
     action.beforeActionPerformedUpdate(event);
@@ -98,15 +100,16 @@ public class EditorTestUtil {
       assertFalse("Action " + actionId + " is disabled", assertActionIsEnabled);
       return;
     }
+    actionManager.fireBeforeActionPerformed(action, event.getDataContext(), event);
     action.actionPerformed(event);
+    actionManager.fireAfterActionPerformed(action, event.getDataContext(), event);
   }
 
   @NotNull
   private static DataContext createEditorContext(@NotNull Editor editor) {
-    Object e = editor;
     Object hostEditor = editor instanceof EditorWindow ? ((EditorWindow)editor).getDelegate() : editor;
     Map<String, Object> map = ContainerUtil.newHashMap(Pair.create(CommonDataKeys.HOST_EDITOR.getName(), hostEditor),
-                                                       Pair.createNonNull(CommonDataKeys.EDITOR.getName(), e));
+                                                       Pair.createNonNull(CommonDataKeys.EDITOR.getName(), editor));
     DataContext parent = DataManager.getInstance().getDataContext(editor.getContentComponent());
     return SimpleDataContext.getSimpleContext(map, parent);
   }