From 744d6aecfbf8e46a98c6bab4eb2655d7467556f3 Mon Sep 17 00:00:00 2001 From: Dmitry Batrak Date: Fri, 1 May 2020 15:00:43 +0300 Subject: [PATCH] IDEA-238541 Honor CamelHumps selection when selecting on double click is not respected on mouse drag GitOrigin-RevId: 5ca4d1a189590388c657d533ffcde2a3c942493c --- .../openapi/editor/impl/CaretImpl.java | 6 +- .../openapi/editor/impl/CaretModelImpl.java | 8 +- .../openapi/editor/impl/EditorImpl.java | 94 +++++++------------ .../openapi/editor/impl/EditorImplTest.java | 16 ++++ .../fixtures/EditorMouseFixture.java | 22 +++-- 5 files changed, 68 insertions(+), 78 deletions(-) diff --git a/platform/platform-impl/src/com/intellij/openapi/editor/impl/CaretImpl.java b/platform/platform-impl/src/com/intellij/openapi/editor/impl/CaretImpl.java index 0d2e0cdb9664..0958f225f470 100644 --- a/platform/platform-impl/src/com/intellij/openapi/editor/impl/CaretImpl.java +++ b/platform/platform-impl/src/com/intellij/openapi/editor/impl/CaretImpl.java @@ -750,14 +750,13 @@ public class CaretImpl extends UserDataHolderBase implements Caret, Dumpable { updateVisualPosition(); } - int getWordAtCaretStart() { + int getWordAtCaretStart(boolean camel) { Document document = myEditor.getDocument(); int offset = getOffset(); if (offset == 0) return 0; int lineNumber = getLogicalPosition().line; int newOffset = offset - 1; int minOffset = lineNumber > 0 ? document.getLineEndOffset(lineNumber - 1) : 0; - boolean camel = myEditor.getSettings().isCamelWords(); for (; newOffset > minOffset; newOffset--) { if (EditorActionUtil.isWordOrLexemeStart(myEditor, newOffset, camel)) break; } @@ -765,7 +764,7 @@ public class CaretImpl extends UserDataHolderBase implements Caret, Dumpable { return newOffset; } - int getWordAtCaretEnd() { + int getWordAtCaretEnd(boolean camel) { Document document = myEditor.getDocument(); int offset = getOffset(); @@ -779,7 +778,6 @@ public class CaretImpl extends UserDataHolderBase implements Caret, Dumpable { if (lineNumber + 1 >= document.getLineCount()) return offset; maxOffset = document.getLineEndOffset(lineNumber + 1); } - boolean camel = myEditor.getSettings().isCamelWords(); for (; newOffset < maxOffset; newOffset++) { if (EditorActionUtil.isWordOrLexemeEnd(myEditor, newOffset, camel)) break; } diff --git a/platform/platform-impl/src/com/intellij/openapi/editor/impl/CaretModelImpl.java b/platform/platform-impl/src/com/intellij/openapi/editor/impl/CaretModelImpl.java index 478f9c0041fc..035820f6f7c3 100644 --- a/platform/platform-impl/src/com/intellij/openapi/editor/impl/CaretModelImpl.java +++ b/platform/platform-impl/src/com/intellij/openapi/editor/impl/CaretModelImpl.java @@ -116,12 +116,12 @@ public class CaretModelImpl implements CaretModel, PrioritizedDocumentListener, } } - int getWordAtCaretStart() { - return getCurrentCaret().getWordAtCaretStart(); + int getWordAtCaretStart(boolean camel) { + return getCurrentCaret().getWordAtCaretStart(camel); } - int getWordAtCaretEnd() { - return getCurrentCaret().getWordAtCaretEnd(); + int getWordAtCaretEnd(boolean camel) { + return getCurrentCaret().getWordAtCaretEnd(camel); } @Override diff --git a/platform/platform-impl/src/com/intellij/openapi/editor/impl/EditorImpl.java b/platform/platform-impl/src/com/intellij/openapi/editor/impl/EditorImpl.java index cb83056026d7..1cadbd032bba 100644 --- a/platform/platform-impl/src/com/intellij/openapi/editor/impl/EditorImpl.java +++ b/platform/platform-impl/src/com/intellij/openapi/editor/impl/EditorImpl.java @@ -2546,32 +2546,7 @@ public final class EditorImpl extends UserDataHolderBase implements EditorEx, Hi } else { if (getMouseSelectionState() != MOUSE_SELECTION_STATE_NONE) { - int newSelection = newCaretOffset; - if (caretShift < 0) { - if (getMouseSelectionState() == MOUSE_SELECTION_STATE_WORD_SELECTED) { - newSelection = myCaretModel.getWordAtCaretStart(); - } - else { - if (getMouseSelectionState() == MOUSE_SELECTION_STATE_LINE_SELECTED) { - newSelection = visualPositionToOffset(new VisualPosition(getCaretModel().getVisualPosition().line, 0)); - } - } - if (newSelection < 0) newSelection = newCaretOffset; - selectionModel.setSelection(mySavedSelectionEnd, newSelection); - } - else { - if (getMouseSelectionState() == MOUSE_SELECTION_STATE_WORD_SELECTED) { - newSelection = myCaretModel.getWordAtCaretEnd(); - } - else { - if (getMouseSelectionState() == MOUSE_SELECTION_STATE_LINE_SELECTED) { - newSelection = visualPositionToOffset(new VisualPosition(getCaretModel().getVisualPosition().line + 1, 0)); - } - } - if (newSelection < 0) newSelection = newCaretOffset; - selectionModel.setSelection(mySavedSelectionStart, newSelection); - } - getCaretModel().moveToOffset(newSelection); + setupSpecialSelectionOnMouseDrag(newCaretOffset, caretShift); cancelAutoResetForMouseSelectionState(); return; } @@ -2632,6 +2607,38 @@ public final class EditorImpl extends UserDataHolderBase implements EditorEx, Hi } } + private void setupSpecialSelectionOnMouseDrag(int newCaretOffset, int caretShift) { + int newSelectionStart; + int newSelectionEnd = newCaretOffset; + if (caretShift < 0) { + if (getMouseSelectionState() == MOUSE_SELECTION_STATE_WORD_SELECTED) { + newSelectionEnd = myCaretModel.getWordAtCaretStart(mySettings.isCamelWords() && mySettings.isMouseClickSelectionHonorsCamelWords()); + } + else if (getMouseSelectionState() == MOUSE_SELECTION_STATE_LINE_SELECTED) { + newSelectionEnd = visualPositionToOffset(new VisualPosition(getCaretModel().getVisualPosition().line, 0)); + } + newSelectionStart = validateOffset(mySavedSelectionEnd); + } + else { + if (getMouseSelectionState() == MOUSE_SELECTION_STATE_WORD_SELECTED) { + newSelectionEnd = myCaretModel.getWordAtCaretEnd(mySettings.isCamelWords() && mySettings.isMouseClickSelectionHonorsCamelWords()); + } + else if (getMouseSelectionState() == MOUSE_SELECTION_STATE_LINE_SELECTED) { + newSelectionEnd = visualPositionToOffset(new VisualPosition(getCaretModel().getVisualPosition().line + 1, 0)); + } + newSelectionStart = validateOffset(mySavedSelectionStart); + } + if (newSelectionEnd < 0) newSelectionEnd = newCaretOffset; + mySelectionModel.setSelection(newSelectionStart, newSelectionEnd); + myCaretModel.moveToOffset(newSelectionEnd); + } + + private int validateOffset(int offset) { + if (offset < 0) return 0; + if (offset > myDocument.getTextLength()) return myDocument.getTextLength(); + return offset; + } + private void clearDnDContext() { if (myDraggedRange != null) { myDraggedRange.dispose(); @@ -3012,34 +3019,7 @@ public final class EditorImpl extends UserDataHolderBase implements EditorEx, Hi int caretShift = newCaretOffset - mySavedSelectionStart; if (getMouseSelectionState() != MOUSE_SELECTION_STATE_NONE) { - if (caretShift < 0) { - int newSelection = newCaretOffset; - if (getMouseSelectionState() == MOUSE_SELECTION_STATE_WORD_SELECTED) { - newSelection = myCaretModel.getWordAtCaretStart(); - } - else { - if (getMouseSelectionState() == MOUSE_SELECTION_STATE_LINE_SELECTED) { - newSelection = visualPositionToOffset(new VisualPosition(getCaretModel().getVisualPosition().line, 0)); - } - } - if (newSelection < 0) newSelection = newCaretOffset; - mySelectionModel.setSelection(validateOffset(mySavedSelectionEnd), newSelection); - getCaretModel().moveToOffset(newSelection); - } - else { - int newSelection = newCaretOffset; - if (getMouseSelectionState() == MOUSE_SELECTION_STATE_WORD_SELECTED) { - newSelection = myCaretModel.getWordAtCaretEnd(); - } - else { - if (getMouseSelectionState() == MOUSE_SELECTION_STATE_LINE_SELECTED) { - newSelection = visualPositionToOffset(new VisualPosition(getCaretModel().getVisualPosition().line + 1, 0)); - } - } - if (newSelection < 0) newSelection = newCaretOffset; - mySelectionModel.setSelection(validateOffset(mySavedSelectionStart), newSelection); - getCaretModel().moveToOffset(newSelection); - } + setupSpecialSelectionOnMouseDrag(newCaretOffset, caretShift); return; } @@ -3066,12 +3046,6 @@ public final class EditorImpl extends UserDataHolderBase implements EditorEx, Hi myTimer = null; } } - - private int validateOffset(int offset) { - if (offset < 0) return 0; - if (offset > myDocument.getTextLength()) return myDocument.getTextLength(); - return offset; - } } private static void updateOpaque(JScrollBar bar) { diff --git a/platform/platform-tests/testSrc/com/intellij/openapi/editor/impl/EditorImplTest.java b/platform/platform-tests/testSrc/com/intellij/openapi/editor/impl/EditorImplTest.java index 58a6403a2236..77b148b1eead 100644 --- a/platform/platform-tests/testSrc/com/intellij/openapi/editor/impl/EditorImplTest.java +++ b/platform/platform-tests/testSrc/com/intellij/openapi/editor/impl/EditorImplTest.java @@ -8,6 +8,7 @@ import com.intellij.openapi.editor.colors.FontPreferences; import com.intellij.openapi.editor.event.DocumentListener; import com.intellij.openapi.editor.ex.DocumentEx; import com.intellij.openapi.editor.ex.EditorEx; +import com.intellij.openapi.editor.ex.EditorSettingsExternalizable; import com.intellij.openapi.editor.ex.FoldingModelEx; import com.intellij.openapi.editor.ex.util.EditorUtil; import com.intellij.openapi.editor.markup.HighlighterTargetArea; @@ -644,4 +645,19 @@ public class EditorImplTest extends AbstractEditorTest { mouse().pressAtXY(0, 0).dragToXY(0, getEditor().getLineHeight()).release(); checkResultByText("abc"); } + + public void testMouseDraggingWithCamelHumpsDisabledForMouse() { + boolean savedOption = EditorSettingsExternalizable.getInstance().isCamelWords(); + try { + EditorSettingsExternalizable.getInstance().setCamelWords(true); + initText("AbcDefGhi"); + EditorTestUtil.setEditorVisibleSize(getEditor(), 100, 100); + getEditor().getSettings().setMouseClickSelectionHonorsCamelWords(false); + mouse().doubleClickNoReleaseAt(0, 4).dragTo(0, 5).release(); + checkResultByText("AbcDefGhi"); + } + finally { + EditorSettingsExternalizable.getInstance().setCamelWords(savedOption); + } + } } diff --git a/platform/testFramework/src/com/intellij/testFramework/fixtures/EditorMouseFixture.java b/platform/testFramework/src/com/intellij/testFramework/fixtures/EditorMouseFixture.java index 3769be791bb9..828ca5f5916d 100644 --- a/platform/testFramework/src/com/intellij/testFramework/fixtures/EditorMouseFixture.java +++ b/platform/testFramework/src/com/intellij/testFramework/fixtures/EditorMouseFixture.java @@ -20,6 +20,7 @@ public class EditorMouseFixture { private int myModifiers; private int myButton = MouseEvent.BUTTON1; private int myLastId; + private int myLastClickCount; private Component myLastComponent; public EditorMouseFixture(EditorImpl editor) { @@ -51,25 +52,22 @@ public class EditorMouseFixture { myModifiers | getModifiersForButtonPress(myButton), myX = p.x, myY = p.y, - clickCount, + myLastClickCount = clickCount, false, // Windows behaviour myButton)); return this; } public EditorMouseFixture release() { - return release(1); - } - - private EditorMouseFixture release(int clickCount) { int oldLastId = myLastId; + int clickCount = myLastId == MouseEvent.MOUSE_PRESSED ? myLastClickCount : 0; myLastComponent.dispatchEvent(new MouseEvent(myLastComponent, myLastId = MouseEvent.MOUSE_RELEASED, System.currentTimeMillis(), myModifiers | getModifiersForButtonRelease(myButton), myX, myY, - clickCount, + myLastClickCount = clickCount, myButton == MouseEvent.BUTTON3, // Windows behaviour myButton)); if (oldLastId == MouseEvent.MOUSE_PRESSED) { @@ -96,11 +94,15 @@ public class EditorMouseFixture { } public EditorMouseFixture doubleClickAt(int visualLine, int visualColumn) { - return clickAt(visualLine, visualColumn).pressAt(2, getPoint(visualLine, visualColumn)).release(2); + return doubleClickNoReleaseAt(visualLine, visualColumn).release(); + } + + public EditorMouseFixture doubleClickNoReleaseAt(int visualLine, int visualColumn) { + return clickAt(visualLine, visualColumn).pressAt(2, getPoint(visualLine, visualColumn)); } public EditorMouseFixture tripleClickAt(int visualLine, int visualColumn) { - return doubleClickAt(visualLine, visualColumn).pressAt(3, getPoint(visualLine, visualColumn)).release(3); + return doubleClickAt(visualLine, visualColumn).pressAt(3, getPoint(visualLine, visualColumn)).release(); } public EditorMouseFixture moveTo(int visualLine, int visualColumn) { @@ -126,7 +128,7 @@ public class EditorMouseFixture { myModifiers, myX = x, myY = y, - 0, + myLastClickCount = 0, false, 0)); return this; @@ -146,7 +148,7 @@ public class EditorMouseFixture { myModifiers | getModifiersForButtonPress(myButton), myX = x, myY = y, - 1, + myLastClickCount = 1, false, 0)); return this;