IDEA-167094 Can't remove first char in user input

This commit is contained in:
Alexey Kudravtsev
2017-02-13 14:36:48 +03:00
parent ec798c3e54
commit 80357763e6
3 changed files with 71 additions and 12 deletions
@@ -597,7 +597,7 @@ public class ConsoleViewImpl extends JPanel implements ConsoleView, ObservableCo
StringBuilder textToSend = new StringBuilder();
// compute text input from the console contents:
// all range markers beginning from the caret offset backwards, marked as user input and not marked as already sent
for (RangeMarker marker = findTokenMarker(myEditor.getCaretModel().getOffset());
for (RangeMarker marker = findTokenMarker(myEditor.getCaretModel().getOffset()-1);
marker != null;
marker = ((RangeMarkerImpl)marker).findRangeMarkerBefore()) {
ConsoleViewContentType tokenType = getTokenType(marker);
@@ -1127,11 +1127,12 @@ public class ConsoleViewImpl extends JPanel implements ConsoleView, ObservableCo
}
}
// finds range marker the [offset..offset+1) belongs to
private RangeMarker findTokenMarker(int offset) {
RangeMarker[] marker = new RangeMarker[1];
MarkupModelEx model = (MarkupModelEx)DocumentMarkupModel.forDocument(myEditor.getDocument(), getProject(), true);
model.processRangeHighlightersOverlappingWith(offset, offset, m->{
if (getTokenType(m) == null) return true;
if (getTokenType(m) == null || m.getStartOffset() > offset || offset + 1 > m.getEndOffset()) return true;
marker[0] = m;
return false;
});
@@ -1166,8 +1167,8 @@ public class ConsoleViewImpl extends JPanel implements ConsoleView, ObservableCo
flushDeferredText();
SelectionModel selectionModel = editor.getSelectionModel();
int start = selectionModel.hasSelection() ? selectionModel.getSelectionStart() : editor.getCaretModel().getOffset();
RangeMarker marker = findTokenMarker(start);
int lastOffset = selectionModel.hasSelection() ? selectionModel.getSelectionStart() : editor.getCaretModel().getOffset() - 1;
RangeMarker marker = findTokenMarker(lastOffset);
if (getTokenType(marker) != ConsoleViewContentType.USER_INPUT) {
print(text, ConsoleViewContentType.USER_INPUT);
moveScrollRemoveSelection(editor, editor.getDocument().getTextLength());
@@ -1179,7 +1180,8 @@ public class ConsoleViewImpl extends JPanel implements ConsoleView, ObservableCo
replaceUserText(selectionModel.getSelectionStart(), selectionModel.getSelectionEnd(), textToUse);
}
else {
insertUserText(start, textToUse);
int typeOffset = selectionModel.hasSelection() ? selectionModel.getSelectionStart() : editor.getCaretModel().getOffset();
insertUserText(typeOffset, textToUse);
}
}
@@ -22,8 +22,10 @@ import com.intellij.execution.process.ProcessHandler;
import com.intellij.execution.ui.ConsoleViewContentType;
import com.intellij.ide.DataManager;
import com.intellij.ide.ui.UISettings;
import com.intellij.openapi.actionSystem.DataContext;
import com.intellij.openapi.actionSystem.*;
import com.intellij.openapi.actionSystem.ex.ActionUtil;
import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.command.CommandProcessor;
import com.intellij.openapi.editor.Editor;
import com.intellij.openapi.editor.actionSystem.EditorActionManager;
import com.intellij.openapi.editor.actionSystem.TypedAction;
@@ -31,17 +33,18 @@ import com.intellij.openapi.editor.ex.EditorEx;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.util.Disposer;
import com.intellij.psi.search.GlobalSearchScope;
import com.intellij.testFramework.LightPlatformCodeInsightTestCase;
import com.intellij.testFramework.LightPlatformTestCase;
import com.intellij.testFramework.PlatformTestUtil;
import com.intellij.testFramework.TestDataProvider;
import com.intellij.testFramework.*;
import com.intellij.util.Alarm;
import com.intellij.util.Consumer;
import com.intellij.util.TimeoutUtil;
import com.intellij.util.ui.UIUtil;
import gnu.trove.THashSet;
import org.jetbrains.annotations.NotNull;
import java.io.ByteArrayOutputStream;
import java.util.Arrays;
import java.util.List;
import java.util.Set;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.Future;
@@ -207,7 +210,7 @@ public class ConsoleViewImplTest extends LightPlatformTestCase {
GlobalSearchScope.allScope(project),
false,
false);
console.getComponent();
console.getComponent(); // initConsoleEditor()
ProcessHandler processHandler = new NopProcessHandler();
processHandler.startNotify();
console.attachToProcess(processHandler);
@@ -228,6 +231,21 @@ public class ConsoleViewImplTest extends LightPlatformTestCase {
}).cpuBound().assertTiming());
}
/*
public void testPerformanceOfMergeableTokens() throws Exception {
withCycleConsole(1000, console ->
PlatformTestUtil.startPerformanceTest("console print", 1500, () -> {
console.clear();
for (int i=0; i<10_000_000; i++) {
console.print("xxx\n", ConsoleViewContentType.NORMAL_OUTPUT);
UIUtil.dispatchAllInvocationEvents();
}
LightPlatformCodeInsightTestCase.type('\n', console.getEditor(), getProject());
console.waitAllRequests();
}).cpuBound().assertTiming());
}
*/
private static void withCycleConsole(int capacityKB, Consumer<ConsoleViewImpl> runnable) {
boolean oldUse = UISettings.getInstance().OVERRIDE_CONSOLE_CYCLE_BUFFER_SIZE;
int oldSize = UISettings.getInstance().CONSOLE_CYCLE_BUFFER_SIZE_KB;
@@ -318,4 +336,38 @@ public class ConsoleViewImplTest extends LightPlatformTestCase {
action.actionPerformed(editor, c, dataContext);
}
public void testBackspaceDoesDeleteTheLastTypedChar() throws Exception {
final ConsoleViewImpl console = myConsole;
final Editor editor = console.getEditor();
console.print("xxxx", ConsoleViewContentType.NORMAL_OUTPUT);
console.print("a", ConsoleViewContentType.USER_INPUT);
console.print("b", ConsoleViewContentType.USER_INPUT);
console.print("c", ConsoleViewContentType.USER_INPUT);
console.print("d", ConsoleViewContentType.USER_INPUT);
console.flushDeferredText();
assertEquals("xxxxabcd", editor.getDocument().getText());
backspace(console);
assertEquals("xxxxabc", editor.getDocument().getText());
backspace(console);
assertEquals("xxxxab", editor.getDocument().getText());
backspace(console);
assertEquals("xxxxa", editor.getDocument().getText());
backspace(console);
assertEquals("xxxx", editor.getDocument().getText());
}
private static void backspace(ConsoleViewImpl consoleView) {
Editor editor = consoleView.getEditor();
Set<Shortcut> backShortcuts = new THashSet<>(Arrays.asList(ActionManager.getInstance().getAction(IdeActions.ACTION_EDITOR_BACKSPACE).getShortcutSet().getShortcuts()));
List<AnAction> actions = ActionUtil.getActions(consoleView.getEditor().getContentComponent());
AnAction handler = actions.stream()
.filter(a -> new THashSet<>(Arrays.asList(a.getShortcutSet().getShortcuts())).equals(backShortcuts))
.findFirst()
.get();
CommandProcessor.getInstance().executeCommand(getProject(),
() -> EditorTestUtil.executeAction(editor, true, handler),
"", null, editor.getDocument());
}
}
@@ -98,12 +98,17 @@ public class EditorTestUtil {
ActionManagerEx actionManager = ActionManagerEx.getInstanceEx();
AnAction action = actionManager.getAction(actionId);
assertNotNull(action);
executeAction(editor, assertActionIsEnabled, action);
}
public static void executeAction(@NotNull Editor editor, boolean assertActionIsEnabled, @NotNull AnAction action) {
AnActionEvent event = AnActionEvent.createFromAnAction(action, null, "", createEditorContext(editor));
action.beforeActionPerformedUpdate(event);
if (!event.getPresentation().isEnabled()) {
assertFalse("Action " + actionId + " is disabled", assertActionIsEnabled);
assertFalse("Action " + action + " is disabled", assertActionIsEnabled);
return;
}
ActionManagerEx actionManager = ActionManagerEx.getInstanceEx();
actionManager.fireBeforeActionPerformed(action, event.getDataContext(), event);
action.actionPerformed(event);
actionManager.fireAfterActionPerformed(action, event.getDataContext(), event);