Add line wrapping support to the terminal

This commit is contained in:
Mike Cifelli 2017-03-17 19:40:56 -04:00
parent ac349c94cb
commit 462673ba64
4 changed files with 63 additions and 16 deletions

View File

@ -0,0 +1,5 @@
package interpreter;
public class FileLispInterpreter extends LispInterpreter {
}

View File

@ -7,7 +7,7 @@ import error.LispException;
import parser.LispParser;
import sexpression.SExpression;
public class LispInterpreter {
public abstract class LispInterpreter {
protected RuntimeEnvironment environment;
private LispParser parser;

View File

@ -166,7 +166,7 @@ public class LispInterpreterBuilderImpl implements LispInterpreterBuilder {
}
private LispInterpreter createInterpreter() {
return isInteractive ? new InteractiveLispInterpreter() : new LispInterpreter();
return isInteractive ? new InteractiveLispInterpreter() : new FileLispInterpreter();
}
public static class InterpreterAlreadyBuiltException extends CriticalLispException {

View File

@ -11,6 +11,7 @@ public class LispTerminal implements Runnable {
private IOSafeTerminal terminal;
private boolean isFinished;
private String currentLine;
private TerminalPosition origin;
public LispTerminal() {
try {
@ -23,6 +24,7 @@ public class LispTerminal implements Runnable {
this.isFinished = false;
this.currentLine = "";
this.origin = terminal.getCursorPosition();
}
public void run() {
@ -71,32 +73,70 @@ public class LispTerminal implements Runnable {
private void doEnter() {
terminal.putCharacter('\n');
currentLine = "";
origin = terminal.getCursorPosition();
}
private void moveCursorLeft() {
TerminalPosition cursorPosition = terminal.getCursorPosition();
if (isPossibleToMoveLeft(cursorPosition))
if (cursorPosition.getColumn() == 0)
terminal.setCursorPosition(terminal.getTerminalSize().getColumns(), cursorPosition.getRow() - 1);
else
terminal.setCursorPosition(cursorPosition.withRelativeColumn(-1));
}
private boolean isPossibleToMoveLeft(TerminalPosition cursorPosition) {
return distanceFromOrigin(cursorPosition) > 0;
}
private int distanceFromOrigin(TerminalPosition cursorPosition) {
return cursorPosition.getColumn()
+ (terminal.getTerminalSize().getColumns() * (cursorPosition.getRow() - origin.getRow()));
}
private void moveCursorRight() {
TerminalPosition cursorPosition = terminal.getCursorPosition();
if (cursorPosition.getColumn() < currentLine.length())
if (isPossibleToMoveRight(cursorPosition))
advanceCursor(cursorPosition);
}
private void advanceCursor(TerminalPosition cursorPosition) {
if (isCursorAtEndOfRow(cursorPosition))
terminal.setCursorPosition(0, cursorPosition.getRow() + 1);
else
terminal.setCursorPosition(cursorPosition.withRelativeColumn(1));
}
private boolean isCursorAtEndOfRow(TerminalPosition cursorPosition) {
return cursorPosition.getColumn() == terminal.getTerminalSize().getColumns() - 1;
}
private boolean isPossibleToMoveRight(TerminalPosition cursorPosition) {
return distanceFromOrigin(cursorPosition) < currentLine.length();
}
private void doBackspace() {
TerminalPosition cursorPosition = terminal.getCursorPosition();
if (cursorPosition.getColumn() > 0) {
String remaining = currentLine.substring(cursorPosition.getColumn(), currentLine.length());
currentLine = currentLine.substring(0, cursorPosition.getColumn() - 1) + remaining;
if (isPossibleToMoveLeft(cursorPosition)) {
String remaining = currentLine.substring(distanceFromOrigin(cursorPosition), currentLine.length());
currentLine = currentLine.substring(0, distanceFromOrigin(cursorPosition) - 1) + remaining;
if (cursorPosition.getColumn() == 0)
terminal.setCursorPosition(terminal.getTerminalSize().getColumns(), cursorPosition.getRow() - 1);
else
terminal.setCursorPosition(cursorPosition.withRelativeColumn(-1));
for (char c : remaining.toCharArray())
terminal.putCharacter(c);
terminal.putCharacter(' ');
if (cursorPosition.getColumn() == 0)
terminal.setCursorPosition(terminal.getTerminalSize().getColumns(), cursorPosition.getRow() - 1);
else
terminal.setCursorPosition(cursorPosition.withRelativeColumn(-1));
}
}
@ -104,9 +144,9 @@ public class LispTerminal implements Runnable {
private void doDelete() {
TerminalPosition cursorPosition = terminal.getCursorPosition();
if (cursorPosition.getColumn() < currentLine.length()) {
String remaining = currentLine.substring(cursorPosition.getColumn() + 1, currentLine.length());
currentLine = currentLine.substring(0, cursorPosition.getColumn()) + remaining;
if (isPossibleToMoveRight(cursorPosition)) {
String remaining = currentLine.substring(distanceFromOrigin(cursorPosition) + 1, currentLine.length());
currentLine = currentLine.substring(0, distanceFromOrigin(cursorPosition)) + remaining;
for (char c : remaining.toCharArray())
terminal.putCharacter(c);
@ -119,18 +159,20 @@ public class LispTerminal implements Runnable {
private void doCharacter(KeyStroke keyStroke) {
TerminalPosition cursorPosition = terminal.getCursorPosition();
if (cursorPosition.getColumn() < currentLine.length()) {
if (isPossibleToMoveRight(cursorPosition)) {
String remaining = keyStroke.getCharacter()
+ currentLine.substring(cursorPosition.getColumn(), currentLine.length());
currentLine = currentLine.substring(0, cursorPosition.getColumn()) + remaining;
+ currentLine.substring(distanceFromOrigin(cursorPosition), currentLine.length());
currentLine = currentLine.substring(0, distanceFromOrigin(cursorPosition)) + remaining;
for (char c : remaining.toCharArray())
terminal.putCharacter(c);
terminal.setCursorPosition(cursorPosition.withRelativeColumn(1));
advanceCursor(cursorPosition);
} else {
terminal.putCharacter(keyStroke.getCharacter());
currentLine += keyStroke.getCharacter();
advanceCursor(cursorPosition);
}
}