mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
IDEA-80056 Column selection mode improvement
implementation of select/unselect next occurrence actions
This commit is contained in:
@@ -0,0 +1,38 @@
|
||||
/*
|
||||
* Copyright 2000-2014 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.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package com.intellij.openapi.actionSystem;
|
||||
|
||||
import com.intellij.openapi.application.ApplicationManager;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
/**
|
||||
* This component provides the notion of last action. Its purpose is to be able to determine whether some action was performed right after
|
||||
* another specific action.
|
||||
* <p>
|
||||
* It's supposed to be used from EDT only.
|
||||
*/
|
||||
public abstract class LastActionTracker {
|
||||
public static LastActionTracker getInstance() {
|
||||
return ApplicationManager.getApplication().getComponent(LastActionTracker.class);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the id of the previously invoked action or <code>null</code>, if no history exists yet, or last user activity was of
|
||||
* non-action type, like mouse clicking in editor or text typing.
|
||||
*/
|
||||
@Nullable
|
||||
public abstract String getLastActionId();
|
||||
}
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2000-2013 JetBrains s.r.o.
|
||||
* Copyright 2000-2014 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.
|
||||
@@ -65,7 +65,7 @@ public class SelectWordUtil {
|
||||
return SELECTIONERS;
|
||||
}
|
||||
|
||||
private static final CharCondition JAVA_IDENTIFIER_PART_CONDITION = new CharCondition() {
|
||||
public static final CharCondition JAVA_IDENTIFIER_PART_CONDITION = new CharCondition() {
|
||||
@Override
|
||||
public boolean value(char ch) {
|
||||
return Character.isJavaIdentifierPart(ch);
|
||||
|
||||
+156
@@ -0,0 +1,156 @@
|
||||
/*
|
||||
* Copyright 2000-2014 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.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package com.intellij.openapi.editor.actions;
|
||||
|
||||
import com.intellij.codeInsight.editorActions.SelectWordUtil;
|
||||
import com.intellij.codeInsight.hint.HintManager;
|
||||
import com.intellij.codeInsight.hint.HintManagerImpl;
|
||||
import com.intellij.codeInsight.hint.HintUtil;
|
||||
import com.intellij.find.FindBundle;
|
||||
import com.intellij.find.FindManager;
|
||||
import com.intellij.find.FindModel;
|
||||
import com.intellij.find.FindResult;
|
||||
import com.intellij.openapi.actionSystem.LastActionTracker;
|
||||
import com.intellij.openapi.actionSystem.DataContext;
|
||||
import com.intellij.openapi.actionSystem.IdeActions;
|
||||
import com.intellij.openapi.editor.Caret;
|
||||
import com.intellij.openapi.editor.Editor;
|
||||
import com.intellij.openapi.editor.ScrollType;
|
||||
import com.intellij.openapi.editor.actionSystem.EditorAction;
|
||||
import com.intellij.openapi.editor.actionSystem.EditorActionHandler;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.openapi.util.Key;
|
||||
import com.intellij.openapi.util.TextRange;
|
||||
import com.intellij.ui.LightweightHint;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
public class SelectNextOccurrenceAction extends EditorAction {
|
||||
private static final Key<Boolean> NOT_FOUND = Key.create("select.next.occurence.not.found");
|
||||
private static final Key<Boolean> WHOLE_WORDS = Key.create("select.next.occurence.whole.words");
|
||||
|
||||
protected SelectNextOccurrenceAction() {
|
||||
super(new Handler());
|
||||
}
|
||||
|
||||
private static class Handler extends EditorActionHandler {
|
||||
@Override
|
||||
public boolean isEnabled(Editor editor, DataContext dataContext) {
|
||||
return super.isEnabled(editor, dataContext) && editor.getProject() != null && editor.getCaretModel().supportsMultipleCarets();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void execute(Editor editor, @Nullable Caret c, DataContext dataContext) {
|
||||
Caret caret = c == null ? editor.getCaretModel().getPrimaryCaret() : c;
|
||||
TextRange wordSelectionRange = SelectWordUtil.getWordSelectionRange(editor.getDocument().getCharsSequence(),
|
||||
caret.getOffset(),
|
||||
SelectWordUtil.JAVA_IDENTIFIER_PART_CONDITION);
|
||||
boolean notFoundPreviously = getAndResetNotFoundStatus(editor);
|
||||
Boolean wholeWordSearch = isWholeWordSearch(editor);
|
||||
if (caret.hasSelection()) {
|
||||
Project project = editor.getProject();
|
||||
String selectedText = caret.getSelectedText();
|
||||
if (project == null || selectedText == null) {
|
||||
return;
|
||||
}
|
||||
FindManager findManager = FindManager.getInstance(project);
|
||||
|
||||
if (wholeWordSearch == null) {
|
||||
wholeWordSearch = wordSelectionRange != null
|
||||
&& wordSelectionRange.getStartOffset() == caret.getSelectionStart()
|
||||
&& wordSelectionRange.getEndOffset() == caret.getSelectionEnd();
|
||||
setWholeWordSearch(editor, wholeWordSearch);
|
||||
}
|
||||
FindModel model = new FindModel();
|
||||
model.setStringToFind(caret.getSelectedText());
|
||||
model.setCaseSensitive(true);
|
||||
model.setWholeWordsOnly(wholeWordSearch);
|
||||
|
||||
int searchStartOffset = notFoundPreviously ? 0 : caret.getSelectionEnd();
|
||||
FindResult findResult = findManager.findString(editor.getDocument().getCharsSequence(), searchStartOffset, model);
|
||||
if (findResult.isStringFound()) {
|
||||
int newCaretOffset = caret.getOffset() - caret.getSelectionStart() + findResult.getStartOffset();
|
||||
EditorActionUtil.makePositionVisible(editor, newCaretOffset);
|
||||
Caret newCaret = editor.getCaretModel().addCaret(editor.offsetToVisualPosition(newCaretOffset));
|
||||
if (newCaret == null) {
|
||||
// this means that the found occurence is already selected
|
||||
if (notFoundPreviously) {
|
||||
setNotFoundStatus(editor); // to make sure we won't show hint anymore if there are no more occurrences
|
||||
}
|
||||
}
|
||||
else {
|
||||
setSelection(editor, newCaret, findResult);
|
||||
}
|
||||
}
|
||||
else {
|
||||
setNotFoundStatus(editor);
|
||||
showHint(editor);
|
||||
}
|
||||
}
|
||||
else {
|
||||
if (wordSelectionRange == null) {
|
||||
return;
|
||||
}
|
||||
setSelection(editor, caret, wordSelectionRange);
|
||||
setWholeWordSearch(editor, true);
|
||||
}
|
||||
editor.getScrollingModel().scrollToCaret(ScrollType.RELATIVE);
|
||||
}
|
||||
|
||||
private static void setSelection(Editor editor, Caret caret, TextRange selectionRange) {
|
||||
EditorActionUtil.makePositionVisible(editor, selectionRange.getStartOffset());
|
||||
EditorActionUtil.makePositionVisible(editor, selectionRange.getEndOffset());
|
||||
caret.setSelection(selectionRange.getStartOffset(), selectionRange.getEndOffset());
|
||||
}
|
||||
|
||||
|
||||
private static void showHint(final Editor editor) {
|
||||
String message = FindBundle.message("select.next.occurence.not.found.message");
|
||||
final LightweightHint hint = new LightweightHint(HintUtil.createInformationLabel(message));
|
||||
HintManagerImpl.getInstanceImpl().showEditorHint(hint,
|
||||
editor,
|
||||
HintManager.UNDER,
|
||||
HintManager.HIDE_BY_TEXT_CHANGE | HintManager.HIDE_BY_SCROLLING,
|
||||
0,
|
||||
false);
|
||||
}
|
||||
|
||||
private static boolean getAndResetNotFoundStatus(Editor editor) {
|
||||
boolean status = editor.getUserData(NOT_FOUND) != null;
|
||||
editor.putUserData(NOT_FOUND, null);
|
||||
return status && isRepeatedActionInvocation();
|
||||
}
|
||||
|
||||
private static void setNotFoundStatus(Editor editor) {
|
||||
editor.putUserData(NOT_FOUND, Boolean.TRUE);
|
||||
}
|
||||
|
||||
private static Boolean isWholeWordSearch(Editor editor) {
|
||||
if (!isRepeatedActionInvocation()) {
|
||||
editor.putUserData(WHOLE_WORDS, null);
|
||||
}
|
||||
return editor.getUserData(WHOLE_WORDS);
|
||||
}
|
||||
|
||||
private static void setWholeWordSearch(Editor editor, boolean isWholeWordSearch) {
|
||||
editor.putUserData(WHOLE_WORDS, isWholeWordSearch);
|
||||
}
|
||||
|
||||
private static boolean isRepeatedActionInvocation() {
|
||||
String lastActionId = LastActionTracker.getInstance().getLastActionId();
|
||||
return IdeActions.ACTION_SELECT_NEXT_OCCURENCE.equals(lastActionId) || IdeActions.ACTION_UNSELECT_LAST_OCCURENCE.equals(lastActionId);
|
||||
}
|
||||
}
|
||||
}
|
||||
+48
@@ -0,0 +1,48 @@
|
||||
/*
|
||||
* Copyright 2000-2014 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.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package com.intellij.openapi.editor.actions;
|
||||
|
||||
import com.intellij.openapi.actionSystem.DataContext;
|
||||
import com.intellij.openapi.editor.Caret;
|
||||
import com.intellij.openapi.editor.Editor;
|
||||
import com.intellij.openapi.editor.ScrollType;
|
||||
import com.intellij.openapi.editor.actionSystem.EditorAction;
|
||||
import com.intellij.openapi.editor.actionSystem.EditorActionHandler;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
public class UnselectLastOccurrenceAction extends EditorAction {
|
||||
protected UnselectLastOccurrenceAction() {
|
||||
super(new Handler());
|
||||
}
|
||||
|
||||
private static class Handler extends EditorActionHandler {
|
||||
@Override
|
||||
public boolean isEnabled(Editor editor, DataContext dataContext) {
|
||||
return super.isEnabled(editor, dataContext) && editor.getCaretModel().supportsMultipleCarets();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void execute(Editor editor, @Nullable Caret caret, DataContext dataContext) {
|
||||
if (editor.getCaretModel().getAllCarets().size() > 1) {
|
||||
editor.getCaretModel().removeCaret(editor.getCaretModel().getPrimaryCaret());
|
||||
}
|
||||
else {
|
||||
editor.getSelectionModel().removeSelection();
|
||||
}
|
||||
editor.getScrollingModel().scrollToCaret(ScrollType.RELATIVE);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2000-2013 JetBrains s.r.o.
|
||||
* Copyright 2000-2014 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.
|
||||
@@ -114,6 +114,8 @@ public interface IdeActions {
|
||||
@NonNls String ACTION_FIND = "Find";
|
||||
@NonNls String ACTION_FIND_NEXT = "FindNext";
|
||||
@NonNls String ACTION_FIND_PREVIOUS = "FindPrevious";
|
||||
@NonNls String ACTION_SELECT_NEXT_OCCURENCE = "SelectNextOccurrence";
|
||||
@NonNls String ACTION_UNSELECT_LAST_OCCURENCE = "UnselectLastOccurrence";
|
||||
@NonNls String ACTION_COMPILE = "Compile";
|
||||
@NonNls String ACTION_COMPILE_PROJECT = "CompileProject";
|
||||
@NonNls String ACTION_MAKE_MODULE = "MakeModule";
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2000-2012 JetBrains s.r.o.
|
||||
* Copyright 2000-2014 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.
|
||||
@@ -587,6 +587,7 @@ public class HintManagerImpl extends HintManager implements Disposable {
|
||||
@NotNull LogicalPosition pos2,
|
||||
@PositionFlags short constraint,
|
||||
boolean showByBalloon) {
|
||||
if (ApplicationManager.getApplication().isUnitTestMode()) return new Point();
|
||||
Point p = _getHintPosition(hint, editor, pos1, pos2, constraint, showByBalloon);
|
||||
JLayeredPane layeredPane = editor.getComponent().getRootPane().getLayeredPane();
|
||||
Dimension hintSize = hint.getComponent().getPreferredSize();
|
||||
|
||||
+116
@@ -0,0 +1,116 @@
|
||||
/*
|
||||
* Copyright 2000-2014 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.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package com.intellij.openapi.actionSystem.impl;
|
||||
|
||||
import com.intellij.openapi.actionSystem.*;
|
||||
import com.intellij.openapi.actionSystem.ex.AnActionListener;
|
||||
import com.intellij.openapi.components.ApplicationComponent;
|
||||
import com.intellij.openapi.editor.Editor;
|
||||
import com.intellij.openapi.editor.EditorFactory;
|
||||
import com.intellij.openapi.editor.event.EditorEventMulticaster;
|
||||
import com.intellij.openapi.editor.event.EditorMouseEvent;
|
||||
import com.intellij.openapi.editor.event.EditorMouseListener;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
public class LastActionTrackerImpl extends LastActionTracker implements ApplicationComponent, AnActionListener, EditorMouseListener {
|
||||
private final ActionManager myActionManager;
|
||||
private final EditorEventMulticaster myEditorEventMulticaster;
|
||||
|
||||
private String myLastActionId;
|
||||
private Editor myLastEditor;
|
||||
|
||||
LastActionTrackerImpl(ActionManager actionManager, EditorFactory editorFactory) {
|
||||
myActionManager = actionManager;
|
||||
myEditorEventMulticaster = editorFactory.getEventMulticaster();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void initComponent() {
|
||||
myActionManager.addAnActionListener(this);
|
||||
myEditorEventMulticaster.addEditorMouseListener(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void disposeComponent() {
|
||||
myEditorEventMulticaster.removeEditorMouseListener(this);
|
||||
myActionManager.removeAnActionListener(this);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public String getComponentName() {
|
||||
return "LastActionTracker";
|
||||
}
|
||||
|
||||
@Override
|
||||
@Nullable
|
||||
public String getLastActionId() {
|
||||
return myLastActionId;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void beforeActionPerformed(AnAction action, DataContext dataContext, AnActionEvent event) {
|
||||
if (CommonDataKeys.EDITOR.getData(dataContext) != myLastEditor) {
|
||||
resetLastAction();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void afterActionPerformed(AnAction action, DataContext dataContext, AnActionEvent event) {
|
||||
myLastActionId = getActionId(action);
|
||||
myLastEditor = CommonDataKeys.EDITOR.getData(dataContext);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void beforeEditorTyping(char c, DataContext dataContext) {
|
||||
resetLastAction();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void mousePressed(EditorMouseEvent e) {
|
||||
resetLastAction();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void mouseClicked(EditorMouseEvent e) {
|
||||
resetLastAction();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void mouseReleased(EditorMouseEvent e) {
|
||||
resetLastAction();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void mouseEntered(EditorMouseEvent e) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void mouseExited(EditorMouseEvent e) {
|
||||
|
||||
}
|
||||
|
||||
private String getActionId(AnAction action) {
|
||||
return action instanceof ActionStub ? ((ActionStub)action).getId() : myActionManager.getId(action);
|
||||
}
|
||||
|
||||
private void resetLastAction() {
|
||||
myLastActionId = null;
|
||||
myLastEditor = null;
|
||||
}
|
||||
}
|
||||
@@ -784,4 +784,21 @@ public class EditorActionUtil {
|
||||
public static void moveCaretToLineStartIgnoringSoftWraps(@NotNull Editor editor) {
|
||||
editor.getCaretModel().moveToLogicalPosition(EditorUtil.calcCaretLineRange(editor).first);
|
||||
}
|
||||
|
||||
/**
|
||||
* This method will make required expansions of collapsed region to make given offset 'visible'.
|
||||
*/
|
||||
public static void makePositionVisible(@NotNull final Editor editor, final int offset) {
|
||||
FoldingModel foldingModel = editor.getFoldingModel();
|
||||
FoldRegion collapsedRegionAtOffset;
|
||||
while ((collapsedRegionAtOffset = foldingModel.getCollapsedRegionAtOffset(offset)) != null) {
|
||||
final FoldRegion region = collapsedRegionAtOffset;
|
||||
foldingModel.runBatchFoldingOperation(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
region.setExpanded(true);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -107,6 +107,8 @@ action.EditorMoveUpAndScrollWithSelection.text=Move Up and Scroll with Selection
|
||||
action.EditorMoveDownAndScrollWithSelection.text=Move Down and Scroll with Selection
|
||||
action.EditorCloneCaretBelow.text=Clone Caret Below
|
||||
action.EditorCloneCaretAbove.text=Clone Caret Above
|
||||
action.SelectNextOccurence.text=Select Next Occurence
|
||||
action.UnselectLastOccurence.text=Unselect Last Occurence
|
||||
action.EditorToggleStickySelection.text=Toggle Sticky Selection
|
||||
action.EditorSwapSelectionBoundaries.text=Swap selection boundaries
|
||||
action.EditorLineStart.text=Move Caret to Line Start
|
||||
|
||||
@@ -7,6 +7,7 @@ find.search.again.from.top.hotkey.message={0}, press {1} to search from the top
|
||||
find.search.again.from.top.action.message={0}, perform \"Find Next\" again to search from the top
|
||||
find.search.again.from.bottom.hotkey.message={0}, press {1} to search from the bottom
|
||||
find.search.again.from.bottom.action.message={0}, perform \"Find Previous\" again to search from the bottom
|
||||
select.next.occurence.not.found.message=Not found, try again to search from top
|
||||
|
||||
find.no.usages.at.cursor.error=Cannot search for usages. \nPosition to an element to find usages for, and try again.
|
||||
find.what.group=Find
|
||||
|
||||
@@ -21,6 +21,10 @@
|
||||
<interface-class>com.intellij.openapi.actionSystem.ActionManager</interface-class>
|
||||
<implementation-class>com.intellij.openapi.actionSystem.impl.ActionManagerImpl</implementation-class>
|
||||
</component>
|
||||
<component>
|
||||
<interface-class>com.intellij.openapi.actionSystem.LastActionTracker</interface-class>
|
||||
<implementation-class>com.intellij.openapi.actionSystem.impl.LastActionTrackerImpl</implementation-class>
|
||||
</component>
|
||||
<component>
|
||||
<interface-class>com.intellij.openapi.keymap.KeymapManager</interface-class>
|
||||
<implementation-class>com.intellij.openapi.keymap.impl.KeymapManagerImpl</implementation-class>
|
||||
|
||||
@@ -112,6 +112,12 @@
|
||||
<action id="FindWordAtCaret">
|
||||
<keyboard-shortcut first-keystroke="control F3"/>
|
||||
</action>
|
||||
<action id="SelectNextOccurrence">
|
||||
<keyboard-shortcut first-keystroke="alt N"/>
|
||||
</action>
|
||||
<action id="UnselectLastOccurrence">
|
||||
<keyboard-shortcut first-keystroke="alt shift N"/>
|
||||
</action>
|
||||
<action id="GotoDeclaration">
|
||||
<keyboard-shortcut first-keystroke="control B"/>
|
||||
<mouse-shortcut keystroke="ctrl button1"/>
|
||||
|
||||
@@ -225,6 +225,8 @@
|
||||
<action id="FindNext" class="com.intellij.ide.actions.SearchAgainAction"/>
|
||||
<action id="FindPrevious" class="com.intellij.ide.actions.SearchBackAction"/>
|
||||
<action id="FindWordAtCaret" class="com.intellij.openapi.editor.actions.FindWordAtCaretAction"/>
|
||||
<action id="SelectNextOccurrence" class="com.intellij.openapi.editor.actions.SelectNextOccurrenceAction"/>
|
||||
<action id="UnselectLastOccurrence" class="com.intellij.openapi.editor.actions.UnselectLastOccurrenceAction"/>
|
||||
<separator/>
|
||||
<action id="FindInPath" class="com.intellij.find.actions.FindInPathAction"/>
|
||||
<action id="ReplaceInPath" class="com.intellij.find.actions.ReplaceInPathAction"/>
|
||||
|
||||
+194
@@ -0,0 +1,194 @@
|
||||
/*
|
||||
* Copyright 2000-2014 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.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package com.intellij.openapi.editor.actions;
|
||||
|
||||
import com.intellij.codeInsight.hint.EditorHintListener;
|
||||
import com.intellij.openapi.application.ApplicationManager;
|
||||
import com.intellij.openapi.editor.Document;
|
||||
import com.intellij.openapi.editor.FoldRegion;
|
||||
import com.intellij.openapi.editor.FoldingModel;
|
||||
import com.intellij.openapi.fileTypes.FileTypes;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.testFramework.EditorTestUtil;
|
||||
import com.intellij.testFramework.fixtures.LightPlatformCodeInsightFixtureTestCase;
|
||||
import com.intellij.ui.LightweightHint;
|
||||
|
||||
public class SelectUnselectOccurrenceActionsTest extends LightPlatformCodeInsightFixtureTestCase {
|
||||
private int hintCount;
|
||||
|
||||
@Override
|
||||
public void setUp() throws Exception {
|
||||
super.setUp();
|
||||
EditorTestUtil.enableMultipleCarets();
|
||||
EditorHintListener listener = new EditorHintListener() {
|
||||
@Override
|
||||
public void hintShown(Project project, LightweightHint hint, int flags) {
|
||||
hintCount++;
|
||||
}
|
||||
};
|
||||
ApplicationManager.getApplication().getMessageBus().connect(myTestRootDisposable).subscribe(EditorHintListener.TOPIC, listener);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void tearDown() throws Exception {
|
||||
EditorTestUtil.disableMultipleCarets();
|
||||
super.tearDown();
|
||||
}
|
||||
|
||||
public void testNoInitialSelection() throws Exception {
|
||||
init("some t<caret>ext\n" +
|
||||
"some texts\n" +
|
||||
"another text here"
|
||||
);
|
||||
executeAction();
|
||||
checkResult("some <selection>t<caret>ext</selection>\n" +
|
||||
"some texts\n" +
|
||||
"another text here");
|
||||
assertEquals(0, hintCount);
|
||||
}
|
||||
|
||||
public void testInitialWholeWordSelection() throws Exception {
|
||||
init("some <selection>t<caret>ext</selection>\n" +
|
||||
"some texts\n" +
|
||||
"another text here");
|
||||
executeAction();
|
||||
checkResult("some <selection>t<caret>ext</selection>\n" +
|
||||
"some texts\n" +
|
||||
"another <selection>t<caret>ext</selection> here");
|
||||
assertEquals(0, hintCount);
|
||||
}
|
||||
|
||||
public void testShowingHint() throws Exception {
|
||||
init("some <selection>t<caret>ext</selection>\n" +
|
||||
"some texts\n" +
|
||||
"another <selection>t<caret>ext</selection> here");
|
||||
executeAction();
|
||||
assertEquals(1, hintCount);
|
||||
checkResult("some <selection>t<caret>ext</selection>\n" +
|
||||
"some texts\n" +
|
||||
"another <selection>t<caret>ext</selection> here");
|
||||
executeAction();
|
||||
assertEquals(1, hintCount);
|
||||
checkResult("some <selection>t<caret>ext</selection>\n" +
|
||||
"some texts\n" +
|
||||
"another <selection>t<caret>ext</selection> here");
|
||||
}
|
||||
|
||||
public void testRevert() throws Exception {
|
||||
init("some <selection>t<caret>ext</selection>\n" +
|
||||
"some texts\n" +
|
||||
"another <selection>t<caret>ext</selection> here");
|
||||
executeReverseAction();
|
||||
checkResult("some <selection>t<caret>ext</selection>\n" +
|
||||
"some texts\n" +
|
||||
"another text here");
|
||||
assertEquals(0, hintCount);
|
||||
}
|
||||
|
||||
public void testRevertSingleSelection() throws Exception {
|
||||
init("some <selection>t<caret>ext</selection>\n" +
|
||||
"some texts\n" +
|
||||
"another text here");
|
||||
executeReverseAction();
|
||||
checkResult("some t<caret>ext\n" +
|
||||
"some texts\n" +
|
||||
"another text here");
|
||||
assertEquals(0, hintCount);
|
||||
}
|
||||
|
||||
public void testSelectAfterHint() throws Exception {
|
||||
init("some text\n" +
|
||||
"some texts\n" +
|
||||
"another <selection>t<caret>ext</selection> here");
|
||||
executeAction();
|
||||
checkResult("some text\n" +
|
||||
"some texts\n" +
|
||||
"another <selection>t<caret>ext</selection> here");
|
||||
assertEquals(1, hintCount);
|
||||
executeAction();
|
||||
checkResult("some <selection>t<caret>ext</selection>\n" +
|
||||
"some texts\n" +
|
||||
"another <selection>t<caret>ext</selection> here");
|
||||
assertEquals(1, hintCount);
|
||||
}
|
||||
|
||||
public void testInitialNonWholeWordSelection() throws Exception {
|
||||
init("some <selection>t<caret>ex</selection>t\n" +
|
||||
"some texts\n" +
|
||||
"another text here");
|
||||
executeAction();
|
||||
checkResult("some <selection>t<caret>ex</selection>t\n" +
|
||||
"some <selection>t<caret>ex</selection>ts\n" +
|
||||
"another text here");
|
||||
executeAction();
|
||||
checkResult("some <selection>t<caret>ex</selection>t\n" +
|
||||
"some <selection>t<caret>ex</selection>ts\n" +
|
||||
"another <selection>t<caret>ex</selection>t here");
|
||||
assertEquals(0, hintCount);
|
||||
}
|
||||
|
||||
public void testWholeWordinessIsRememberedAtStart() throws Exception {
|
||||
init("some <selection>text<caret></selection>s\n" +
|
||||
"another text\n" +
|
||||
"some other texts");
|
||||
executeAction();
|
||||
checkResult("some <selection>text<caret></selection>s\n" +
|
||||
"another <selection>text<caret></selection>\n" +
|
||||
"some other texts");
|
||||
executeAction();
|
||||
checkResult("some <selection>text<caret></selection>s\n" +
|
||||
"another <selection>text<caret></selection>\n" +
|
||||
"some other <selection>text<caret></selection>s");
|
||||
assertEquals(0, hintCount);
|
||||
}
|
||||
|
||||
public void testOccurrenceInCollapsedRegion() throws Exception {
|
||||
init("normal <selection><caret>line</selection>\n" +
|
||||
"collapsed line");
|
||||
final FoldingModel foldingModel = myFixture.getEditor().getFoldingModel();
|
||||
final Document document = myFixture.getEditor().getDocument();
|
||||
foldingModel.runBatchFoldingOperation(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
FoldRegion foldRegion = foldingModel.addFoldRegion(document.getLineStartOffset(1), document.getLineEndOffset(1), "...");
|
||||
assertNotNull(foldRegion);
|
||||
foldRegion.setExpanded(false);
|
||||
}
|
||||
});
|
||||
executeAction();
|
||||
checkResult("normal <selection><caret>line</selection>\n" +
|
||||
"collapsed <selection><caret>line</selection>");
|
||||
FoldRegion[] foldRegions = foldingModel.getAllFoldRegions();
|
||||
assertEquals(1, foldRegions.length);
|
||||
assertTrue(foldRegions[0].isExpanded());
|
||||
}
|
||||
|
||||
private void init(String text) {
|
||||
myFixture.configureByText(FileTypes.PLAIN_TEXT, text);
|
||||
}
|
||||
|
||||
private void checkResult(String text) {
|
||||
myFixture.checkResult(text);
|
||||
}
|
||||
|
||||
private void executeAction() {
|
||||
myFixture.performEditorAction("SelectNextOccurrence");
|
||||
}
|
||||
|
||||
private void executeReverseAction() {
|
||||
myFixture.performEditorAction("UnselectLastOccurrence");
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user