diff --git a/platform/platform-api/src/com/intellij/openapi/actionSystem/IdeActions.java b/platform/platform-api/src/com/intellij/openapi/actionSystem/IdeActions.java index 66486d8da4be..9d7a307615dc 100644 --- a/platform/platform-api/src/com/intellij/openapi/actionSystem/IdeActions.java +++ b/platform/platform-api/src/com/intellij/openapi/actionSystem/IdeActions.java @@ -46,6 +46,8 @@ public interface IdeActions { @NonNls String ACTION_EDITOR_MOVE_CARET_PAGE_DOWN = "EditorPageDown"; @NonNls String ACTION_EDITOR_NEXT_WORD = "EditorNextWord"; @NonNls String ACTION_EDITOR_PREVIOUS_WORD = "EditorPreviousWord"; + @NonNls String ACTION_EDITOR_NEXT_WORD_WITH_SELECTION = "EditorNextWordWithSelection"; + @NonNls String ACTION_EDITOR_PREVIOUS_WORD_WITH_SELECTION = "EditorPreviousWordWithSelection"; @NonNls String ACTION_EDITOR_TAB = "EditorTab"; @NonNls String ACTION_EDITOR_ESCAPE = "EditorEscape"; @NonNls String ACTION_EDITOR_JOIN_LINES = "EditorJoinLines"; diff --git a/platform/platform-impl/src/com/intellij/openapi/editor/actions/EditorActionUtil.java b/platform/platform-impl/src/com/intellij/openapi/editor/actions/EditorActionUtil.java index 74a2bf9ca75b..717f32340da7 100644 --- a/platform/platform-impl/src/com/intellij/openapi/editor/actions/EditorActionUtil.java +++ b/platform/platform-impl/src/com/intellij/openapi/editor/actions/EditorActionUtil.java @@ -603,23 +603,35 @@ public class EditorActionUtil { : caretModel.getLogicalPosition(); int offset = caretModel.getOffset(); - CharSequence text = document.getCharsSequence(); if (offset == document.getTextLength()) { return; } - int newOffset = offset + 1; - int lineNumber = caretModel.getLogicalPosition().line; - if (lineNumber >= document.getLineCount()) return; - int maxOffset = document.getLineEndOffset(lineNumber); - if (newOffset > maxOffset) { - if (lineNumber + 1 >= document.getLineCount()) { - return; - } - maxOffset = document.getLineEndOffset(lineNumber + 1); + + int newOffset; + + FoldRegion currentFoldRegion = editor.getFoldingModel().getCollapsedRegionAtOffset(offset); + if (currentFoldRegion != null) { + newOffset = currentFoldRegion.getEndOffset(); } - for (; newOffset < maxOffset; newOffset++) { - if (isWordOrLexemeStart(editor, newOffset, camel)) { - break; + else { + newOffset = offset + 1; + int lineNumber = caretModel.getLogicalPosition().line; + if (lineNumber >= document.getLineCount()) return; + int maxOffset = document.getLineEndOffset(lineNumber); + if (newOffset > maxOffset) { + if (lineNumber + 1 >= document.getLineCount()) { + return; + } + maxOffset = document.getLineEndOffset(lineNumber + 1); + } + for (; newOffset < maxOffset; newOffset++) { + if (isWordOrLexemeStart(editor, newOffset, camel)) { + break; + } + } + FoldRegion foldRegion = editor.getFoldingModel().getCollapsedRegionAtOffset(newOffset); + if (foldRegion != null) { + newOffset = foldRegion.getStartOffset(); } } caretModel.moveToOffset(newOffset); @@ -687,13 +699,25 @@ public class EditorActionUtil { int offset = editor.getCaretModel().getOffset(); if (offset == 0) return; - int lineNumber = editor.getCaretModel().getLogicalPosition().line; - CharSequence text = document.getCharsSequence(); - int newOffset = offset - 1; - int minOffset = lineNumber > 0 ? document.getLineEndOffset(lineNumber - 1) : 0; - for (; newOffset > minOffset; newOffset--) { - if (isWordOrLexemeStart(editor, newOffset, camel)) break; + int newOffset; + + FoldRegion currentFoldRegion = editor.getFoldingModel().getCollapsedRegionAtOffset(offset - 1); + if (currentFoldRegion != null) { + newOffset = currentFoldRegion.getStartOffset(); } + else { + int lineNumber = editor.getCaretModel().getLogicalPosition().line; + newOffset = offset - 1; + int minOffset = lineNumber > 0 ? document.getLineEndOffset(lineNumber - 1) : 0; + for (; newOffset > minOffset; newOffset--) { + if (isWordOrLexemeStart(editor, newOffset, camel)) break; + } + FoldRegion foldRegion = editor.getFoldingModel().getCollapsedRegionAtOffset(newOffset); + if (foldRegion != null && newOffset > foldRegion.getStartOffset()) { + newOffset = foldRegion.getEndOffset(); + } + } + editor.getCaretModel().moveToOffset(newOffset); EditorModificationUtil.scrollToCaret(editor); diff --git a/platform/platform-tests/testSrc/com/intellij/openapi/editor/actions/NextPrevWordTest.java b/platform/platform-tests/testSrc/com/intellij/openapi/editor/actions/NextPrevWordTest.java index a8bdd4e9875f..c9cea52f0cc0 100644 --- a/platform/platform-tests/testSrc/com/intellij/openapi/editor/actions/NextPrevWordTest.java +++ b/platform/platform-tests/testSrc/com/intellij/openapi/editor/actions/NextPrevWordTest.java @@ -16,6 +16,8 @@ package com.intellij.openapi.editor.actions; import com.intellij.openapi.actionSystem.IdeActions; +import com.intellij.openapi.editor.FoldRegion; +import com.intellij.testFramework.EditorTestUtil; import com.intellij.testFramework.fixtures.LightPlatformCodeInsightFixtureTestCase; /** @@ -52,4 +54,44 @@ public class NextPrevWordTest extends LightPlatformCodeInsightFixtureTestCase { myFixture.performEditorAction(IdeActions.ACTION_EDITOR_PREVIOUS_WORD); myFixture.checkResult("class Foo { String s = \"a\\xb\"; }"); } + + public void testPrevNextWordWithFolding() { + myFixture.configureByText("a.txt", "brown fox"); + EditorTestUtil.addFoldRegion(myFixture.getEditor(), 4, 7, "...", true); + myFixture.performEditorAction(IdeActions.ACTION_EDITOR_NEXT_WORD); + myFixture.checkResult("brown fox"); + myFixture.performEditorAction(IdeActions.ACTION_EDITOR_NEXT_WORD); + myFixture.checkResult("brown fox"); + myFixture.performEditorAction(IdeActions.ACTION_EDITOR_NEXT_WORD); + myFixture.checkResult("brown fox"); + myFixture.performEditorAction(IdeActions.ACTION_EDITOR_PREVIOUS_WORD); + myFixture.checkResult("brown fox"); + myFixture.performEditorAction(IdeActions.ACTION_EDITOR_PREVIOUS_WORD); + myFixture.checkResult("brown fox"); + myFixture.performEditorAction(IdeActions.ACTION_EDITOR_PREVIOUS_WORD); + myFixture.checkResult("brown fox"); + FoldRegion[] foldRegions = myFixture.getEditor().getFoldingModel().getAllFoldRegions(); + assertEquals(1, foldRegions.length); + assertFalse(foldRegions[0].isExpanded()); + } + + public void testPrevNextWordWithSelectionAndFolding() { + myFixture.configureByText("a.txt", "brown fox"); + EditorTestUtil.addFoldRegion(myFixture.getEditor(), 4, 7, "...", true); + myFixture.performEditorAction(IdeActions.ACTION_EDITOR_NEXT_WORD_WITH_SELECTION); + myFixture.checkResult("brown fox"); + myFixture.performEditorAction(IdeActions.ACTION_EDITOR_NEXT_WORD_WITH_SELECTION); + myFixture.checkResult("brown fox"); + myFixture.performEditorAction(IdeActions.ACTION_EDITOR_NEXT_WORD_WITH_SELECTION); + myFixture.checkResult("brown fox"); + myFixture.performEditorAction(IdeActions.ACTION_EDITOR_PREVIOUS_WORD_WITH_SELECTION); + myFixture.checkResult("brown fox"); + myFixture.performEditorAction(IdeActions.ACTION_EDITOR_PREVIOUS_WORD_WITH_SELECTION); + myFixture.checkResult("brown fox"); + myFixture.performEditorAction(IdeActions.ACTION_EDITOR_PREVIOUS_WORD_WITH_SELECTION); + myFixture.checkResult("brown fox"); + FoldRegion[] foldRegions = myFixture.getEditor().getFoldingModel().getAllFoldRegions(); + assertEquals(1, foldRegions.length); + assertFalse(foldRegions[0].isExpanded()); + } }