Fix output interfering with input

Refactored some code
This commit is contained in:
Mike Cifelli 2017-03-22 15:26:00 -04:00
parent 228b4b1793
commit 79fb8b633b
5 changed files with 60 additions and 21 deletions

View File

@ -8,10 +8,8 @@ import stream.SafeInputStream;
class ControlSequenceHandler {
private static final char ESCAPE = '\u001B';
public static final boolean isEscape(char c) {
return c == ESCAPE;
return c == UNICODE_ESCAPE;
}
private SafeInputStream input;

View File

@ -8,21 +8,21 @@ import terminal.ControlSequence.NullControlSequence;
public class ControlSequenceLookup {
private static Map<Character, Map<String, ControlSequence>> controlSequenceMap = new HashMap<>();
private static Map<Character, Map<String, ControlSequence>> commands = new HashMap<>();
static {
Map<String, ControlSequence> selectGraphicRenditionMap = new HashMap<>();
Map<String, ControlSequence> sgrCodes = new HashMap<>();
for (SelectGraphicRendition sgr : SelectGraphicRendition.values())
selectGraphicRenditionMap.put(sgr.getCode(), sgr);
sgrCodes.put(sgr.getCode(), sgr);
controlSequenceMap.put(SGR_COMMAND, selectGraphicRenditionMap);
commands.put(SGR_COMMAND, sgrCodes);
}
public static ControlSequence lookupControlSequence(char command, String code) {
Map<String, ControlSequence> commandMap = controlSequenceMap.getOrDefault(command, new HashMap<>());
Map<String, ControlSequence> codes = commands.getOrDefault(command, new HashMap<>());
return commandMap.getOrDefault(code, new NullControlSequence());
return codes.getOrDefault(code, new NullControlSequence());
}
}

View File

@ -3,6 +3,7 @@ package terminal;
import static com.googlecode.lanterna.input.KeyType.*;
import static terminal.ControlSequenceHandler.isEscape;
import static util.Characters.EOF;
import static util.Characters.UNICODE_NULL;
import java.io.*;
import java.util.concurrent.*;
@ -15,7 +16,7 @@ import stream.*;
public class LispTerminal {
public static final char END_OF_SEGMENT = 'x';
public static final char END_OF_SEGMENT = UNICODE_NULL;
private IOSafeTerminal terminal;
private SafeOutputStream inputWriter;
@ -54,6 +55,10 @@ public class LispTerminal {
terminalSize = terminal.getTerminalSize();
terminal.clearScreen();
terminal.setCursorPosition(0, 0);
redisplayInput();
}
private synchronized void redisplayInput() {
setOriginToCurrentPosition();
putStringToTerminal(inputLine);
moveCursorToEndOfInput();
@ -358,14 +363,14 @@ public class LispTerminal {
printSegmentCharacters();
terminal.setCursorVisible(true);
outputSegment = "";
setOriginToCurrentPosition();
redisplayInput();
terminal.flush();
}
private synchronized void printSegmentCharacters() {
moveCursorToEndOfInput();
putOutputToTerminal();
moveCursorToNextRowIfNecessary();
terminal.flush();
}
private synchronized void putOutputToTerminal() {

View File

@ -24,6 +24,8 @@ public final class Characters {
public static final char RIGHT_SQUARE_BRACKET = ']';
public static final char SEMICOLON = ';';
public static final char SINGLE_QUOTE = '\'';
public static final char UNICODE_ESCAPE = '\u001B';
public static final char UNICODE_NULL = '\u0000';
public static final Set<Character> illegalIdentifierCharacters = new HashSet<>();

View File

@ -452,18 +452,52 @@ public class LispTerminalTest {
}
@Test
public void printedOutputDoesNotOverwriteInput() {
public void outputDoesNotOverwriteInput_AndRedisplaysInput() {
setColumns(3);
enterCharacters("01201201");
pressKeyTimes(ArrowLeft, 5);
enterCharacters("0123");
pressKeyTimes(ArrowLeft, 3);
produceOutput("out");
assertCursorPosition(0, 4);
assertCharacterPositions(new char[][] { { '0', '1', '2' }, { '0', '1', '2' }, { '0', '1', 'o' },
{ 'u', 't', ' ' } });
assertCursorPosition(2, 3);
assertCharacterPositions(new char[][] { { '0', '1', '2' }, { '3', 'o', 'u' }, { 't', '0', '1' },
{ '2', '3', ' ' }, { ' ', ' ', ' ' } });
}
@Test
public void printedOutputDoesNotOverwriteInput_AfterEnter() {
public void outputEndsOnSecondToLastColumn_MovesToNewRow() {
setColumns(3);
enterCharacters("01234");
pressKeyTimes(ArrowLeft, 3);
produceOutput("out");
assertCursorPosition(2, 4);
assertCharacterPositions(new char[][] { { '0', '1', '2' }, { '3', '4', 'o' }, { 'u', 't', ' ' },
{ '0', '1', '2' }, { '3', '4', ' ' } });
}
@Test
public void outputEndsOnLastColumn_MovesToNewRow() {
setColumns(3);
enterCharacters("012345");
pressKeyTimes(ArrowLeft, 3);
produceOutput("out");
assertCursorPosition(0, 5);
assertCharacterPositions(new char[][] { { '0', '1', '2' }, { '3', '4', '5' }, { 'o', 'u', 't' },
{ '0', '1', '2' }, { '3', '4', '5' }, { ' ', ' ', ' ' } });
}
@Test
public void outputRedisplaysInputAtEndOfBuffer() {
setColumns(3);
setRows(4);
enterCharacters("01234");
pressKeyTimes(ArrowLeft, 3);
produceOutput("out");
assertCursorPosition(2, 3);
assertCharacterPositions(new char[][] { { '3', '4', 'o' }, { 'u', 't', ' ' }, { '0', '1', '2' },
{ '3', '4', ' ' } });
}
@Test
public void outputDoesNotOverwriteInput_AfterEnter() {
setColumns(3);
enterCharacters("01201201");
pressKeyTimes(ArrowLeft, 5);
@ -471,7 +505,7 @@ public class LispTerminalTest {
produceOutput("out");
assertCursorPosition(0, 4);
assertCharacterPositions(new char[][] { { '0', '1', '2' }, { '0', '1', '2' }, { '0', '1', ' ' },
{ 'o', 'u', 't' } });
{ 'o', 'u', 't' }, { ' ', ' ', ' ' } });
}
@Test
@ -509,7 +543,7 @@ public class LispTerminalTest {
}
@Test
public void controlSequenceIsNotPrinted() {
public void controlSequencesAreNotPrinted() {
produceOutput("\u001B[32mcontrol\u001B[0mseq");
assertCharacterPositions(new char[][] { { 'c', 'o', 'n', 't', 'r', 'o', 'l', 's', 'e', 'q' } });
}