Add line wrapping support to the terminal
This commit is contained in:
parent
ac349c94cb
commit
462673ba64
|
@ -0,0 +1,5 @@
|
|||
package interpreter;
|
||||
|
||||
public class FileLispInterpreter extends LispInterpreter {
|
||||
|
||||
}
|
|
@ -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;
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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,42 +73,80 @@ public class LispTerminal implements Runnable {
|
|||
private void doEnter() {
|
||||
terminal.putCharacter('\n');
|
||||
currentLine = "";
|
||||
origin = terminal.getCursorPosition();
|
||||
}
|
||||
|
||||
private void moveCursorLeft() {
|
||||
TerminalPosition cursorPosition = terminal.getCursorPosition();
|
||||
terminal.setCursorPosition(cursorPosition.withRelativeColumn(-1));
|
||||
|
||||
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;
|
||||
terminal.setCursorPosition(cursorPosition.withRelativeColumn(-1));
|
||||
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(' ');
|
||||
terminal.setCursorPosition(cursorPosition.withRelativeColumn(-1));
|
||||
|
||||
if (cursorPosition.getColumn() == 0)
|
||||
terminal.setCursorPosition(terminal.getTerminalSize().getColumns(), cursorPosition.getRow() - 1);
|
||||
else
|
||||
terminal.setCursorPosition(cursorPosition.withRelativeColumn(-1));
|
||||
}
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue