diff --git a/platform/lang-impl/src/com/intellij/ide/actions/GotoActionBase.java b/platform/lang-impl/src/com/intellij/ide/actions/GotoActionBase.java index 0f0027c43180..75b12f4a7e60 100644 --- a/platform/lang-impl/src/com/intellij/ide/actions/GotoActionBase.java +++ b/platform/lang-impl/src/com/intellij/ide/actions/GotoActionBase.java @@ -27,6 +27,7 @@ import com.intellij.openapi.editor.Document; import com.intellij.openapi.editor.Editor; import com.intellij.openapi.fileEditor.FileEditorManager; import com.intellij.openapi.fileEditor.ex.FileEditorManagerEx; +import com.intellij.openapi.project.DumbAwareAction; import com.intellij.openapi.project.Project; import com.intellij.openapi.util.Pair; import com.intellij.openapi.util.text.StringUtil; @@ -34,13 +35,16 @@ import com.intellij.openapi.wm.IdeFocusManager; import com.intellij.psi.PsiDocumentManager; import com.intellij.psi.PsiElement; import com.intellij.psi.PsiFile; +import com.intellij.ui.DocumentAdapter; import com.intellij.ui.speedSearch.SpeedSearchSupply; import com.intellij.util.containers.ContainerUtil; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import javax.swing.*; +import javax.swing.event.DocumentEvent; import java.awt.*; +import java.util.List; import java.util.Map; /** @@ -51,14 +55,17 @@ public abstract class GotoActionBase extends AnAction { protected static Class myInAction = null; private static final Map> ourLastStrings = ContainerUtil.newHashMap(); - + private static final Map> ourHistory = ContainerUtil.newHashMap(); + private int myHistoryIndex = 0; @Override public void actionPerformed(AnActionEvent e) { - LOG.assertTrue (!getClass ().equals (myInAction)); + LOG.assertTrue(!getClass().equals(myInAction)); try { myInAction = getClass(); - gotoActionPerformed (e); + List strings = ourHistory.get(myInAction); + myHistoryIndex = Math.min(1, ContainerUtil.isEmpty(strings) ? 0 : strings.size() - 1); + gotoActionPerformed(e); } catch (Throwable t) { LOG.error(t); @@ -201,12 +208,13 @@ public abstract class GotoActionBase extends AnAction { final ChooseByNameFilter filter = callback.createFilter(popup); popup.invoke(new ChooseByNamePopupComponent.Callback() { - @Override public void onClose() { - ourLastStrings.put(myInAction, Pair.create(popup.getEnteredText(), popup.getSelectedIndex())); //noinspection ConstantConditions if (startedAction != null && startedAction.equals(myInAction)) { + String text = popup.getEnteredText(); + ourLastStrings.put(myInAction, Pair.create(text, popup.getSelectedIndex())); + updateHistory(text); myInAction = null; } if (filter != null) { @@ -214,11 +222,66 @@ public abstract class GotoActionBase extends AnAction { } } + private void updateHistory(@Nullable String text) { + if (!StringUtil.isEmptyOrSpaces(text)) { + List history = ourHistory.get(myInAction); + if (history == null) history = ContainerUtil.newArrayList(); + if (!text.equals(ContainerUtil.getFirstItem(history))) { + history.add(0, text); + } + ourHistory.put(myInAction, history); + } + } + @Override public void elementChosen(Object element) { callback.elementChosen(popup, element); } }, ModalityState.current(), allowMultipleSelection); - } + final JTextField editor = popup.getTextField(); + + final DocumentAdapter historyResetListener = new DocumentAdapter() { + @Override + protected void textChanged(DocumentEvent e) { + myHistoryIndex = 0; + } + }; + + abstract class HistoryAction extends DumbAwareAction { + @Override + public void update(AnActionEvent e) { + e.getPresentation().setEnabled(!ContainerUtil.isEmpty(ourHistory.get(myInAction))); + } + + void setText(@NotNull List strings) { + javax.swing.text.Document document = editor.getDocument(); + document.removeDocumentListener(historyResetListener); + editor.setText(strings.get(myHistoryIndex)); + document.addDocumentListener(historyResetListener); + editor.selectAll(); + } + } + + editor.getDocument().addDocumentListener(historyResetListener); + + new HistoryAction() { + @Override + public void actionPerformed(AnActionEvent e) { + List strings = ourHistory.get(myInAction); + setText(strings); + myHistoryIndex = myHistoryIndex >= strings.size() - 1 ? 0 : myHistoryIndex + 1; + } + + }.registerCustomShortcutSet(CustomShortcutSet.fromString("ctrl UP"), editor); + + new HistoryAction() { + @Override + public void actionPerformed(AnActionEvent e) { + List strings = ourHistory.get(myInAction); + setText(strings); + myHistoryIndex = myHistoryIndex <= 0 ? strings.size() - 1 : myHistoryIndex - 1; + } + }.registerCustomShortcutSet(CustomShortcutSet.fromString("ctrl DOWN"), editor); + } } diff --git a/platform/lang-impl/src/com/intellij/ide/util/gotoByName/ChooseByNameBase.java b/platform/lang-impl/src/com/intellij/ide/util/gotoByName/ChooseByNameBase.java index 4ff25f80c0b1..18e025a889fa 100644 --- a/platform/lang-impl/src/com/intellij/ide/util/gotoByName/ChooseByNameBase.java +++ b/platform/lang-impl/src/com/intellij/ide/util/gotoByName/ChooseByNameBase.java @@ -1325,6 +1325,7 @@ public abstract class ChooseByNameBase { } int position = myTextField.getCaretPosition(); int code = keyStroke.getKeyCode(); + int modifiers = keyStroke.getModifiers(); try { super.processKeyEvent(e); } @@ -1334,7 +1335,7 @@ public abstract class ChooseByNameBase { } } finally { - if (code == KeyEvent.VK_UP || code == KeyEvent.VK_DOWN) { + if ((code == KeyEvent.VK_UP || code == KeyEvent.VK_DOWN) && modifiers == 0) { myTextField.setCaretPosition(position); } } @@ -1797,4 +1798,8 @@ public abstract class ChooseByNameBase { public abstract Object[][] getElements(); } + + public JTextField getTextField() { + return myTextField; + } }