From 6937ba67f24b4cfb5ea3e03ff9a9a453d456c3b8 Mon Sep 17 00:00:00 2001 From: "Gregory.Shrago" Date: Wed, 4 Mar 2015 21:06:26 +0300 Subject: [PATCH] History: natural console history ordering and DBE-1149 fix --- .../console/ConsoleHistoryController.java | 47 ++++---- .../console/ConsoleHistoryModel.java | 106 ++++++++---------- 2 files changed, 73 insertions(+), 80 deletions(-) diff --git a/platform/lang-impl/src/com/intellij/execution/console/ConsoleHistoryController.java b/platform/lang-impl/src/com/intellij/execution/console/ConsoleHistoryController.java index 155158367d7e..5a18d9f36adb 100644 --- a/platform/lang-impl/src/com/intellij/execution/console/ConsoleHistoryController.java +++ b/platform/lang-impl/src/com/intellij/execution/console/ConsoleHistoryController.java @@ -38,6 +38,7 @@ import com.intellij.openapi.keymap.KeymapUtil; import com.intellij.openapi.project.Project; import com.intellij.openapi.project.ex.ProjectEx; import com.intellij.openapi.ui.Messages; +import com.intellij.openapi.util.Comparing; import com.intellij.openapi.util.Disposer; import com.intellij.openapi.util.Key; import com.intellij.openapi.util.TextRange; @@ -133,7 +134,7 @@ public class ConsoleHistoryController { } public boolean hasHistory() { - return getModel().getHistory().isEmpty(); + return !getModel().getEntries().isEmpty(); } private static String fixNullPersistenceId(@Nullable String persistenceId, @NotNull LanguageConsoleView console) { @@ -236,7 +237,9 @@ public class ConsoleHistoryController { @Override public void run() { if (storeUserText) { - myHelper.setContent(document.getText()); + String text = document.getText(); + if (Comparing.equal(command, text) && myHelper.getContent() != null) return; + myHelper.setContent(text); } String text = StringUtil.notNullize(command); int offset; @@ -290,22 +293,23 @@ public class ConsoleHistoryController { @Override public void actionPerformed(final AnActionEvent e) { - final String command; + String command; if (myNext) { command = getModel().getHistoryNext(); if (!myMultiline && command == null) return; } else { - if (!myMultiline && getModel().getHistoryCursor() < 0) return; command = ObjectUtils.chooseNotNull(getModel().getHistoryPrev(), myMultiline ? "" : StringUtil.notNullize(myHelper.getContent())); } - setConsoleText(command, myNext && getModel().getHistoryCursor() == 0, true); + setConsoleText(command, myNext && !getModel().hasHistory(false), true); } @Override public void update(final AnActionEvent e) { super.update(e); - e.getPresentation().setEnabled(myMultiline || !isUpDownKey(e) || canMoveInEditor(myNext)); + boolean enabled = myMultiline || !isUpDownKey(e) || canMoveInEditor(myNext); + //enabled &= getModel().hasHistory(myNext); + e.getPresentation().setEnabled(enabled); } private boolean isUpDownKey(AnActionEvent e) { @@ -340,12 +344,13 @@ public class ConsoleHistoryController { private class MyBrowseAction extends AnAction { @Override - public void update(final AnActionEvent e) { - e.getPresentation().setEnabled(getModel().getHistorySize() > 0); + public void update(AnActionEvent e) { + boolean enabled = hasHistory(); + e.getPresentation().setEnabled(enabled); } @Override - public void actionPerformed(final AnActionEvent e) { + public void actionPerformed(AnActionEvent e) { String s1 = KeymapUtil.getFirstKeyboardShortcutText(myHistoryNext); String s2 = KeymapUtil.getFirstKeyboardShortcutText(myHistoryPrev); String title = myConsole.getTitle() + " History" + @@ -364,7 +369,9 @@ public class ConsoleHistoryController { @Override protected List getContents() { - return getModel().getHistory(); + List entries = getModel().getEntries(); + Collections.reverse(entries); + return entries; } @Override @@ -394,7 +401,7 @@ public class ConsoleHistoryController { }; chooser.setContentIcon(null); chooser.setSplitterOrientation(false); - chooser.setSelectedIndex(Math.max(getModel().getHistoryCursor(), 0)); + chooser.setSelectedIndex(Math.max(0, getModel().getHistorySize() - getModel().getCurrentIndex() - 1)); if (chooser.showAndGet() && myConsole.getCurrentEditor().getComponent().isShowing()) { setConsoleText(chooser.getSelectedText(), false, true); } @@ -455,11 +462,8 @@ public class ConsoleHistoryController { } return false; } - List entries = Arrays.asList(VfsUtilCore.loadText(file).split(myRootType.getEntrySeparator())); - for (ListIterator iterator = entries.listIterator(entries.size()); iterator.hasPrevious(); ) { - String entry = iterator.previous(); - getModel().addToHistory(entry); - } + String[] split = VfsUtilCore.loadText(file).split(myRootType.getEntrySeparator()); + getModel().resetEntries(Arrays.asList(split)); return true; } catch (Exception ignored) { @@ -537,7 +541,7 @@ public class ConsoleHistoryController { private void saveHistory() { try { - if (getModel().getHistory().isEmpty()) return; + if (getModel().getEntries().isEmpty()) return; if (myRootType.isHidden()) { saveHistoryOld(); return; @@ -545,7 +549,7 @@ public class ConsoleHistoryController { AccessToken token = ApplicationManager.getApplication().acquireWriteActionLock(getClass()); try { VirtualFile file = HistoryRootType.getInstance().findFile(null, getHistoryName(myRootType, myId), ScratchFileService.Option.create_if_missing); - VfsUtil.saveText(file, StringUtil.join(getModel().getHistory(), myRootType.getEntrySeparator())); + VfsUtil.saveText(file, StringUtil.join(getModel().getEntries(), myRootType.getEntrySeparator())); } finally { token.finish(); @@ -573,10 +577,7 @@ public class ConsoleHistoryController { } in.moveUp(); } - for (ListIterator iterator = entries.listIterator(entries.size()); iterator.hasPrevious(); ) { - String entry = iterator.previous(); - getModel().addToHistory(entry); - } + getModel().resetEntries(entries); return consoleContent; } @@ -586,7 +587,7 @@ public class ConsoleHistoryController { out.attribute(null, "version", "1"); out.attribute(null, "id", myId); try { - for (String s : getModel().getHistory()) { + for (String s : getModel().getEntries()) { textTag(out, "history-entry", s); } String current = myContent; diff --git a/platform/lang-impl/src/com/intellij/execution/console/ConsoleHistoryModel.java b/platform/lang-impl/src/com/intellij/execution/console/ConsoleHistoryModel.java index 415d0acd47e0..9cc7e6079654 100644 --- a/platform/lang-impl/src/com/intellij/execution/console/ConsoleHistoryModel.java +++ b/platform/lang-impl/src/com/intellij/execution/console/ConsoleHistoryModel.java @@ -18,6 +18,7 @@ package com.intellij.execution.console; import com.intellij.ide.ui.UISettings; import com.intellij.openapi.util.SimpleModificationTracker; import com.intellij.openapi.util.text.StringUtil; +import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import java.util.ArrayList; @@ -30,95 +31,86 @@ import java.util.List; class ConsoleHistoryModel extends SimpleModificationTracker { /** @noinspection FieldCanBeLocal*/ private final ConsoleHistoryModel myMasterModel; // hard ref - private int myHistoryCursor = -1; - private final LinkedList myHistory; + private int myIndex; + private final LinkedList myEntries; ConsoleHistoryModel(ConsoleHistoryModel masterModel) { myMasterModel = masterModel; - myHistory = myMasterModel == null ? new LinkedList() : myMasterModel.myHistory; + myEntries = myMasterModel == null ? new LinkedList() : myMasterModel.myEntries; + resetIndex(); } ConsoleHistoryModel copy() { return new ConsoleHistoryModel(this); } - public void addToHistory(@Nullable String statement) { + public synchronized void resetEntries(@NotNull List entries) { + myEntries.clear(); + myEntries.addAll(entries.subList(0, Math.min(entries.size(), getMaxHistorySize()))); + incModificationCount(); + } + + public synchronized void addToHistory(@Nullable String statement) { if (StringUtil.isEmptyOrSpaces(statement)) return; int maxHistorySize = getMaxHistorySize(); - synchronized (myHistory) { - incModificationCount(); - myHistoryCursor = -1; - - myHistory.remove(statement); - int size = myHistory.size(); - if (size >= maxHistorySize && size > 0) { - myHistory.removeLast(); - } - myHistory.addFirst(statement); + myEntries.remove(statement); + int size = myEntries.size(); + if (size >= maxHistorySize && size > 0) { + myEntries.removeFirst(); } + myEntries.addLast(statement); + incModificationCount(); + } + + @Override + public void incModificationCount() { + resetIndex(); + super.incModificationCount(); + } + + protected synchronized void resetIndex() { + myIndex = myEntries.size(); } public int getMaxHistorySize() { return UISettings.getInstance().CONSOLE_COMMAND_HISTORY_LIMIT; } - public void removeFromHistory(final String statement) { - synchronized (myHistory) { - incModificationCount(); - myHistoryCursor = -1; - - myHistory.remove(statement); - } + public synchronized void removeFromHistory(String statement) { + myEntries.remove(statement); + incModificationCount(); } - public List getHistory() { - synchronized (myHistory) { - return new ArrayList(myHistory); - } + public synchronized List getEntries() { + return new ArrayList(myEntries); } - public int getHistorySize() { - synchronized (myHistory) { - return myHistory.size(); - } + public synchronized int getHistorySize() { + return myEntries.size(); } @Nullable - public String getHistoryNext() { - synchronized (myHistory) { - if (myHistoryCursor < myHistory.size() - 1) { - return myHistory.get(++myHistoryCursor); - } - else { - if (myHistoryCursor == myHistory.size() - 1) myHistoryCursor++; - return null; - } - } + public synchronized String getHistoryNext() { + if (myIndex >= 0) --myIndex; + return getCurrentEntry(); } @Nullable - public String getHistoryPrev() { - synchronized (myHistory) { - if (myHistoryCursor > 0) { - return myHistory.get(--myHistoryCursor); - } - else { - if (myHistoryCursor == 0) myHistoryCursor--; - return null; - } - } + public synchronized String getHistoryPrev() { + if (myIndex <= myEntries.size() - 1) ++myIndex; + return getCurrentEntry(); } - public boolean hasHistory(final boolean next) { - synchronized (myHistory) { - return next ? myHistoryCursor <= myHistory.size() - 1 : myHistoryCursor >= 0; - } + public synchronized boolean hasHistory(final boolean next) { + return next ? myIndex > 0 : myIndex < myEntries.size() - 1; } - public int getHistoryCursor() { - synchronized (myHistory) { - return myHistoryCursor; - } + synchronized String getCurrentEntry() { + return myIndex >= 0 && myIndex < myEntries.size() ? myEntries.get(myIndex) : null; + } + + synchronized int getCurrentIndex() { + return myIndex; } }