diff --git a/platform/testFramework/src/com/intellij/testFramework/fixtures/CodeInsightTestFixture.java b/platform/testFramework/src/com/intellij/testFramework/fixtures/CodeInsightTestFixture.java index cddec39ffbf0..684118a49ebc 100644 --- a/platform/testFramework/src/com/intellij/testFramework/fixtures/CodeInsightTestFixture.java +++ b/platform/testFramework/src/com/intellij/testFramework/fixtures/CodeInsightTestFixture.java @@ -19,6 +19,7 @@ import com.intellij.modcommand.ActionContext; import com.intellij.model.psi.PsiSymbolReference; import com.intellij.openapi.Disposable; import com.intellij.openapi.actionSystem.AnAction; +import com.intellij.openapi.actionSystem.AnActionEvent; import com.intellij.openapi.actionSystem.Presentation; import com.intellij.openapi.editor.Document; import com.intellij.openapi.editor.Editor; @@ -618,7 +619,11 @@ public interface CodeInsightTestFixture extends IdeaProjectTestFixture { void type(@NotNull String s); - void performEditorAction(@NotNull String actionId); + default void performEditorAction(@NotNull String actionId) { + performEditorAction(actionId, null); + } + + void performEditorAction(@NotNull String actionId, @Nullable AnActionEvent actionEvent); /** * If the action is visible and enabled, perform it. diff --git a/platform/testFramework/src/com/intellij/testFramework/fixtures/EditorTestFixture.java b/platform/testFramework/src/com/intellij/testFramework/fixtures/EditorTestFixture.java index 3fe87b76cc66..749266368a19 100644 --- a/platform/testFramework/src/com/intellij/testFramework/fixtures/EditorTestFixture.java +++ b/platform/testFramework/src/com/intellij/testFramework/fixtures/EditorTestFixture.java @@ -126,11 +126,14 @@ public class EditorTestFixture { } public boolean performEditorAction(@NotNull String actionId) { - DataContext dataContext = getEditorDataContext(); + return performEditorAction(actionId, null); + } + public boolean performEditorAction(@NotNull String actionId, @Nullable AnActionEvent actionEvent) { ActionManagerEx managerEx = ActionManagerEx.getInstanceEx(); AnAction action = managerEx.getAction(actionId); - AnActionEvent event = new AnActionEvent(null, dataContext, ActionPlaces.UNKNOWN, new Presentation(), managerEx, 0); + AnActionEvent event = actionEvent != null ? actionEvent + : new AnActionEvent(null, getEditorDataContext(), ActionPlaces.UNKNOWN, new Presentation(), managerEx, 0); PerformWithDocumentsCommitted.commitDocumentsIfNeeded(action, event); ActionUtil.performDumbAwareUpdate(action, event, false); if (event.getPresentation().isEnabled()) { diff --git a/platform/testFramework/src/com/intellij/testFramework/fixtures/impl/CodeInsightTestFixtureImpl.java b/platform/testFramework/src/com/intellij/testFramework/fixtures/impl/CodeInsightTestFixtureImpl.java index 5f0a1d5f3010..c50f0dc37cd3 100644 --- a/platform/testFramework/src/com/intellij/testFramework/fixtures/impl/CodeInsightTestFixtureImpl.java +++ b/platform/testFramework/src/com/intellij/testFramework/fixtures/impl/CodeInsightTestFixtureImpl.java @@ -994,9 +994,9 @@ public class CodeInsightTestFixtureImpl extends BaseFixture implements CodeInsig } @Override - public void performEditorAction(@NotNull String actionId) { + public void performEditorAction(@NotNull String actionId, @Nullable AnActionEvent actionEvent) { assertInitialized(); - EdtTestUtil.runInEdtAndWait(() -> myEditorTestFixture.performEditorAction(actionId)); + EdtTestUtil.runInEdtAndWait(() -> myEditorTestFixture.performEditorAction(actionId, actionEvent)); } @NotNull diff --git a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/XDebuggerLineChangeHandler.kt b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/XDebuggerLineChangeHandler.kt index 13ef58b32898..6a0206e2b748 100644 --- a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/XDebuggerLineChangeHandler.kt +++ b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/XDebuggerLineChangeHandler.kt @@ -61,7 +61,7 @@ open class XDebuggerLineChangeIconProvider(val project: Project) { open suspend fun getIcon(position: XSourcePositionImpl, editor: Editor): Icon? { return readAction { blockingContextToIndicator { - val types = XBreakpointUtil.getAvailableLineBreakpointTypes(project, position, editor) + val types = XBreakpointUtil.getAvailableLineBreakpointTypes(project, position, false, editor) types.firstOrNull()?.enabledIcon } } diff --git a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/XDebuggerUtilImpl.java b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/XDebuggerUtilImpl.java index efa1872e9601..452dbcf4fa90 100644 --- a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/XDebuggerUtilImpl.java +++ b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/XDebuggerUtilImpl.java @@ -143,7 +143,7 @@ public class XDebuggerUtilImpl extends XDebuggerUtil { final int line, final boolean temporary) { XSourcePositionImpl position = XSourcePositionImpl.create(file, line); - return toggleAndReturnLineBreakpoint(project, Collections.singletonList(type), position, temporary, null, true); + return toggleAndReturnLineBreakpoint(project, Collections.singletonList(type), position, false, temporary, null, true); } /** @@ -278,16 +278,30 @@ public class XDebuggerUtilImpl extends XDebuggerUtil { return bestBreakpoint; } + /** + * @deprecated use {@link #toggleAndReturnLineBreakpoint(Project, List, XSourcePosition, boolean, boolean, Editor, boolean)} + */ + @Deprecated @NotNull public static Promise<@Nullable XLineBreakpoint> toggleAndReturnLineBreakpoint(@NotNull final Project project, - @NotNull List types, - @NotNull final XSourcePosition position, - final boolean temporary, - @Nullable final Editor editor, - boolean canRemove) { + @NotNull List types, + @NotNull final XSourcePosition position, + final boolean temporary, + @Nullable final Editor editor, + boolean canRemove) { + return toggleAndReturnLineBreakpoint(project, types, position, true, temporary, editor, canRemove); + } + + @NotNull + public static Promise<@Nullable XLineBreakpoint> toggleAndReturnLineBreakpoint(@NotNull final Project project, + @NotNull List types, + @NotNull final XSourcePosition position, + boolean selectVariantByPositionColumn, + final boolean temporary, + @Nullable final Editor editor, + boolean canRemove) { final VirtualFile file = position.getFile(); final int line = position.getLine(); - final int caretOffset = position.getOffset(); final XBreakpointManager breakpointManager = XDebuggerManager.getInstance(project).getBreakpointManager(); Promise> variantsAsync = getLineBreakpointVariants(project, types, position); @@ -295,7 +309,7 @@ public class XDebuggerUtilImpl extends XDebuggerUtil { return variantsAsync.then(variantsWithAll -> { var variants = variantsWithAll.stream().filter(v -> !v.isMultiVariant()).toList(); - var breakpointOrVariant = getBestMatchingBreakpoint(caretOffset, + var breakpointOrVariant = getBestMatchingBreakpoint(selectVariantByPositionColumn ? position.getOffset() : 0, Stream.concat( types.stream().flatMap(t -> breakpointManager.findBreakpointsAtLine(t, file, line).stream()), variants.stream()).iterator(), @@ -381,7 +395,7 @@ public class XDebuggerUtilImpl extends XDebuggerUtil { } } - final int defaultIndex = getIndexOfBestMatchingInlineVariant(caretOffset, variants); + final int defaultIndex = getIndexOfBestMatchingInlineVariant(position.getOffset(), variants); final MySelectionListener selectionListener = new MySelectionListener(); BaseListPopupStep step = diff --git a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/actions/handlers/AddLineBreakpointAction.java b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/actions/handlers/AddLineBreakpointAction.java index f9459f8caa18..59a4edfd4978 100644 --- a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/actions/handlers/AddLineBreakpointAction.java +++ b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/actions/handlers/AddLineBreakpointAction.java @@ -34,7 +34,7 @@ public class AddLineBreakpointAction extends DumbAwareAction { if (editor == null) return; XSourcePosition position = getLineBreakpointPosition(e); assert position != null; - XBreakpointUtil.toggleLineBreakpoint(project, position, editor, false, false, true) + XBreakpointUtil.toggleLineBreakpoint(project, position, false, editor, false, false, true) .onSuccess(bp -> { if (bp != null && isConditional()) { EditorGutterComponentEx gutter = (EditorGutterComponentEx)editor.getGutter(); diff --git a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/actions/handlers/XToggleLineBreakpointActionHandler.java b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/actions/handlers/XToggleLineBreakpointActionHandler.java index 1214ba93d13b..030b52cff3f0 100644 --- a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/actions/handlers/XToggleLineBreakpointActionHandler.java +++ b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/actions/handlers/XToggleLineBreakpointActionHandler.java @@ -73,6 +73,7 @@ public class XToggleLineBreakpointActionHandler extends DebuggerActionHandler { if (processedLines.add(position.getLine())) { XBreakpointUtil.toggleLineBreakpoint(project, position, + !isFromGutterClick, editor, isAltClick || myTemporary, !isFromGutterClick, diff --git a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/breakpoints/XBreakpointUtil.java b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/breakpoints/XBreakpointUtil.java index 0479ca4f5654..ea32b918bf93 100644 --- a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/breakpoints/XBreakpointUtil.java +++ b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/breakpoints/XBreakpointUtil.java @@ -145,6 +145,24 @@ public final class XBreakpointUtil { return null; } + /** + * Toggle line breakpoint with editor support: + * - unfolds folded block on the line + * - if folded, checks if line breakpoints could be toggled inside folded text + * + * @deprecated use {@link #toggleLineBreakpoint(Project, XSourcePosition, boolean, Editor, boolean, boolean, boolean)} + */ + @Deprecated + @NotNull + public static Promise<@Nullable XLineBreakpoint> toggleLineBreakpoint(@NotNull Project project, + @NotNull XSourcePosition position, + @Nullable Editor editor, + boolean temporary, + boolean moveCaret, + boolean canRemove) { + return toggleLineBreakpoint(project, position, true, editor, temporary, moveCaret, canRemove); + } + /** * Toggle line breakpoint with editor support: * - unfolds folded block on the line @@ -152,23 +170,24 @@ public final class XBreakpointUtil { */ @NotNull public static Promise<@Nullable XLineBreakpoint> toggleLineBreakpoint(@NotNull Project project, - @NotNull XSourcePosition position, - @Nullable Editor editor, - boolean temporary, - boolean moveCaret, - boolean canRemove) { - Pair, Integer> info = getAvailableLineBreakpointInfo(project, position, editor); + @NotNull XSourcePosition position, + boolean selectVariantByPositionColumn, + @Nullable Editor editor, + boolean temporary, + boolean moveCaret, + boolean canRemove) { + Pair, Integer> info = getAvailableLineBreakpointInfo(project, position, selectVariantByPositionColumn, editor); List typeWinner = info.first; int lineWinner = info.second; - int lineStart = position.getLine(); if (typeWinner.isEmpty()) { return rejectedPromise(new RuntimeException("Cannot find appropriate type")); } + int lineStart = position.getLine(); XSourcePosition winPosition = (lineStart == lineWinner) ? position : XSourcePositionImpl.create(position.getFile(), lineWinner); Promise res = - XDebuggerUtilImpl.toggleAndReturnLineBreakpoint(project, typeWinner, winPosition, temporary, editor, canRemove); + XDebuggerUtilImpl.toggleAndReturnLineBreakpoint(project, typeWinner, winPosition, selectVariantByPositionColumn, temporary, editor, canRemove); if (editor != null && lineStart != lineWinner) { int offset = editor.getDocument().getLineStartOffset(lineWinner); @@ -181,13 +200,21 @@ public final class XBreakpointUtil { } public static List getAvailableLineBreakpointTypes(@NotNull Project project, - @NotNull XSourcePosition position, + @NotNull XSourcePosition linePosition, @Nullable Editor editor) { - return getAvailableLineBreakpointInfo(project, position, editor).first; + return getAvailableLineBreakpointTypes(project, linePosition, false, editor); + } + + public static List getAvailableLineBreakpointTypes(@NotNull Project project, + @NotNull XSourcePosition position, + boolean selectTypeByPositionColumn, + @Nullable Editor editor) { + return getAvailableLineBreakpointInfo(project, position, selectTypeByPositionColumn, editor).first; } private static Pair, Integer> getAvailableLineBreakpointInfo(@NotNull Project project, @NotNull XSourcePosition position, + boolean selectTypeByPositionColumn, @Nullable Editor editor) { int lineStart = position.getLine(); VirtualFile file = position.getFile(); @@ -196,9 +223,10 @@ public final class XBreakpointUtil { return Pair.create(Collections.emptyList(), -1); } - // for folded text check each line and find out type with the biggest priority + // for folded text check each line and find out type with the biggest priority, + // do it unless we were asked to select type strictly by caret position int linesEnd = lineStart; - if (editor != null) { + if (editor != null && !selectTypeByPositionColumn) { FoldRegion region = FoldingUtil.findFoldRegionStartingAtLine(editor, lineStart); if (region != null && !region.isExpanded()) { linesEnd = region.getDocument().getLineNumber(region.getEndOffset()); diff --git a/plugins/ide-features-trainer/src/training/learn/lesson/general/run/CommonDebugLesson.kt b/plugins/ide-features-trainer/src/training/learn/lesson/general/run/CommonDebugLesson.kt index 88d56d636aea..68180cdac8ac 100644 --- a/plugins/ide-features-trainer/src/training/learn/lesson/general/run/CommonDebugLesson.kt +++ b/plugins/ide-features-trainer/src/training/learn/lesson/general/run/CommonDebugLesson.kt @@ -341,7 +341,7 @@ abstract class CommonDebugLesson(id: String) : KLesson(id, LessonsBundle.message val line = logicalPosition.line val createPosition = XDebuggerUtil.getInstance().createPosition(virtualFile, line) ?: error("Can't create source position: $line at $virtualFile") - XBreakpointUtil.toggleLineBreakpoint(project, createPosition, editor, false, false, true) + XBreakpointUtil.toggleLineBreakpoint(project, createPosition, false, editor, false, false, true) //breakpointManager.addLineBreakpoint() } } diff --git a/plugins/ide-features-trainer/src/training/onboarding/NewProjectOnboardingTipsImpl.kt b/plugins/ide-features-trainer/src/training/onboarding/NewProjectOnboardingTipsImpl.kt index b0f95fb3f7ab..6bfea8d54a79 100644 --- a/plugins/ide-features-trainer/src/training/onboarding/NewProjectOnboardingTipsImpl.kt +++ b/plugins/ide-features-trainer/src/training/onboarding/NewProjectOnboardingTipsImpl.kt @@ -82,7 +82,7 @@ private fun installTipsInFirstEditor(editor: Editor, project: Project, info: Onb if (offset != null) { val position = XDebuggerUtil.getInstance().createPositionByOffset(file, offset) ?: return - XBreakpointUtil.toggleLineBreakpoint(project, position, editor, false, false, true) + XBreakpointUtil.toggleLineBreakpoint(project, position, true, editor, false, false, true) } val pathToRunningFile = file.path