Duplicate correct line with multiple carets at the start of lines (IJPL-53908)

GitOrigin-RevId: 8fa331c9d78792b58fcbbd277c8baa0a262c0cab
This commit is contained in:
Bas Leijdekkers
2025-05-05 14:12:03 +00:00
committed by intellij-monorepo-bot
parent 36278cb443
commit cfe2372de3
9 changed files with 53 additions and 14 deletions
@@ -33,7 +33,7 @@ public final class MoveElementLeftRightActionHandler extends EditorWriteActionHa
}
@Override
protected boolean reverseCaretOrder() {
public boolean reverseCaretOrder() {
return !myIsLeft;
}
@@ -27,7 +27,7 @@ public abstract class BaseMoveHandler extends EditorWriteActionHandler.ForEachCa
}
@Override
protected boolean reverseCaretOrder() {
public boolean reverseCaretOrder() {
return isDown;
}
@@ -1,4 +1,4 @@
// Copyright 2000-2024 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
// Copyright 2000-2025 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
package com.intellij.openapi.editor.actions;
import com.intellij.openapi.actionSystem.DataContext;
@@ -31,6 +31,14 @@ public final class NamedElementDuplicateHandler extends EditorWriteActionHandler
return myOriginal.isEnabled(editor, caret, dataContext);
}
@Override
public boolean reverseCaretOrder() {
if (myOriginal instanceof EditorWriteActionHandler handler) {
return handler.reverseCaretOrder();
}
return false;
}
@Override
public void executeWriteAction(@NotNull Editor editor, @NotNull Caret caret, DataContext dataContext) {
Project project = editor.getProject();
@@ -63,8 +71,8 @@ public final class NamedElementDuplicateHandler extends EditorWriteActionHandler
if (range == null || psi instanceof PsiFile || !toDuplicate.contains(psi.getTextRange())) {
break;
}
if (psi instanceof PsiNameIdentifierOwner) {
named = ((PsiNameIdentifierOwner)psi).getNameIdentifier();
if (psi instanceof PsiNameIdentifierOwner owner) {
named = owner.getNameIdentifier();
}
psi = psi.getParent();
}
@@ -2046,7 +2046,7 @@ a:com.intellij.openapi.editor.actionSystem.EditorActionHandler
- isEnabled(com.intellij.openapi.editor.Editor,com.intellij.openapi.actionSystem.DataContext):Z
- f:isEnabled(com.intellij.openapi.editor.Editor,com.intellij.openapi.editor.Caret,com.intellij.openapi.actionSystem.DataContext):Z
- p:isEnabledForCaret(com.intellij.openapi.editor.Editor,com.intellij.openapi.editor.Caret,com.intellij.openapi.actionSystem.DataContext):Z
- p:reverseCaretOrder():Z
- reverseCaretOrder():Z
- runForAllCarets():Z
a:com.intellij.openapi.editor.actionSystem.EditorActionHandler$ForEachCaret
- com.intellij.openapi.editor.actionSystem.EditorActionHandler
@@ -42,7 +42,7 @@ final class DynamicEditorActionHandler extends EditorActionHandler {
}
@Override
protected boolean reverseCaretOrder() {
public boolean reverseCaretOrder() {
return getHandler().reverseCaretOrder();
}
@@ -179,7 +179,7 @@ public abstract class EditorActionHandler {
return myRunForEachCaret;
}
protected boolean reverseCaretOrder() {
public boolean reverseCaretOrder() {
return false;
}
@@ -1,5 +1,4 @@
// Copyright 2000-2023 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
// Copyright 2000-2025 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
package com.intellij.openapi.editor.actions;
import com.intellij.openapi.actionSystem.DataContext;
@@ -26,6 +25,11 @@ public final class DuplicateAction extends EditorAction {
public boolean isEnabledForCaret(@NotNull Editor editor, @NotNull Caret caret, DataContext dataContext) {
return !editor.isOneLineMode() || editor.getSelectionModel().hasSelection();
}
@Override
public boolean reverseCaretOrder() {
return true;
}
}
public static void duplicateLineOrSelectedBlockAtCaret(Editor editor) {
@@ -1,4 +1,4 @@
// Copyright 2000-2023 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
// Copyright 2000-2025 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
package com.intellij.openapi.editor.actions;
import com.intellij.openapi.actionSystem.DataContext;
@@ -36,5 +36,10 @@ public final class DuplicateLinesAction extends EditorAction {
DuplicateAction.duplicateLinesRange(editor, caretPos, caretPos);
}
}
@Override
public boolean reverseCaretOrder() {
return true;
}
}
}
@@ -1,6 +1,4 @@
/*
* Copyright 2000-2017 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
*/
// Copyright 2000-2025 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
package com.intellij.openapi.editor.actions;
import com.intellij.openapi.actionSystem.ActionManager;
@@ -283,6 +281,30 @@ public class EditorActionTest extends AbstractEditorTest {
executeAction(IdeActions.ACTION_EDITOR_DUPLICATE_LINES);
checkResultByText("ab\ncd\n<selection>ab\ncd</selection>");
}
public void testDuplicateLinesMultiCaretLineStart() {
String before = """
<caret>one
<caret>two
<caret>three
""";
String after = """
one
<caret>one
two
<caret>two
three
<caret>three
""";
initText(before);
executeAction(IdeActions.ACTION_EDITOR_DUPLICATE_LINES);
checkResultByText(after);
initText(before);
ctrlD();
checkResultByText(after);
}
public void testDuplicateLineWithGuardedBlock() {
initText("a\n#");