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 parser.LispParser;
|
||||||
import sexpression.SExpression;
|
import sexpression.SExpression;
|
||||||
|
|
||||||
public class LispInterpreter {
|
public abstract class LispInterpreter {
|
||||||
|
|
||||||
protected RuntimeEnvironment environment;
|
protected RuntimeEnvironment environment;
|
||||||
private LispParser parser;
|
private LispParser parser;
|
||||||
|
|
|
@ -166,7 +166,7 @@ public class LispInterpreterBuilderImpl implements LispInterpreterBuilder {
|
||||||
}
|
}
|
||||||
|
|
||||||
private LispInterpreter createInterpreter() {
|
private LispInterpreter createInterpreter() {
|
||||||
return isInteractive ? new InteractiveLispInterpreter() : new LispInterpreter();
|
return isInteractive ? new InteractiveLispInterpreter() : new FileLispInterpreter();
|
||||||
}
|
}
|
||||||
|
|
||||||
public static class InterpreterAlreadyBuiltException extends CriticalLispException {
|
public static class InterpreterAlreadyBuiltException extends CriticalLispException {
|
||||||
|
|
|
@ -11,6 +11,7 @@ public class LispTerminal implements Runnable {
|
||||||
private IOSafeTerminal terminal;
|
private IOSafeTerminal terminal;
|
||||||
private boolean isFinished;
|
private boolean isFinished;
|
||||||
private String currentLine;
|
private String currentLine;
|
||||||
|
private TerminalPosition origin;
|
||||||
|
|
||||||
public LispTerminal() {
|
public LispTerminal() {
|
||||||
try {
|
try {
|
||||||
|
@ -23,6 +24,7 @@ public class LispTerminal implements Runnable {
|
||||||
|
|
||||||
this.isFinished = false;
|
this.isFinished = false;
|
||||||
this.currentLine = "";
|
this.currentLine = "";
|
||||||
|
this.origin = terminal.getCursorPosition();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void run() {
|
public void run() {
|
||||||
|
@ -71,42 +73,80 @@ public class LispTerminal implements Runnable {
|
||||||
private void doEnter() {
|
private void doEnter() {
|
||||||
terminal.putCharacter('\n');
|
terminal.putCharacter('\n');
|
||||||
currentLine = "";
|
currentLine = "";
|
||||||
|
origin = terminal.getCursorPosition();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void moveCursorLeft() {
|
private void moveCursorLeft() {
|
||||||
TerminalPosition cursorPosition = terminal.getCursorPosition();
|
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() {
|
private void moveCursorRight() {
|
||||||
TerminalPosition cursorPosition = terminal.getCursorPosition();
|
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));
|
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() {
|
private void doBackspace() {
|
||||||
TerminalPosition cursorPosition = terminal.getCursorPosition();
|
TerminalPosition cursorPosition = terminal.getCursorPosition();
|
||||||
|
|
||||||
if (cursorPosition.getColumn() > 0) {
|
if (isPossibleToMoveLeft(cursorPosition)) {
|
||||||
String remaining = currentLine.substring(cursorPosition.getColumn(), currentLine.length());
|
String remaining = currentLine.substring(distanceFromOrigin(cursorPosition), currentLine.length());
|
||||||
currentLine = currentLine.substring(0, cursorPosition.getColumn() - 1) + remaining;
|
currentLine = currentLine.substring(0, distanceFromOrigin(cursorPosition) - 1) + remaining;
|
||||||
terminal.setCursorPosition(cursorPosition.withRelativeColumn(-1));
|
|
||||||
|
if (cursorPosition.getColumn() == 0)
|
||||||
|
terminal.setCursorPosition(terminal.getTerminalSize().getColumns(), cursorPosition.getRow() - 1);
|
||||||
|
else
|
||||||
|
terminal.setCursorPosition(cursorPosition.withRelativeColumn(-1));
|
||||||
|
|
||||||
for (char c : remaining.toCharArray())
|
for (char c : remaining.toCharArray())
|
||||||
terminal.putCharacter(c);
|
terminal.putCharacter(c);
|
||||||
|
|
||||||
terminal.putCharacter(' ');
|
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() {
|
private void doDelete() {
|
||||||
TerminalPosition cursorPosition = terminal.getCursorPosition();
|
TerminalPosition cursorPosition = terminal.getCursorPosition();
|
||||||
|
|
||||||
if (cursorPosition.getColumn() < currentLine.length()) {
|
if (isPossibleToMoveRight(cursorPosition)) {
|
||||||
String remaining = currentLine.substring(cursorPosition.getColumn() + 1, currentLine.length());
|
String remaining = currentLine.substring(distanceFromOrigin(cursorPosition) + 1, currentLine.length());
|
||||||
currentLine = currentLine.substring(0, cursorPosition.getColumn()) + remaining;
|
currentLine = currentLine.substring(0, distanceFromOrigin(cursorPosition)) + remaining;
|
||||||
|
|
||||||
for (char c : remaining.toCharArray())
|
for (char c : remaining.toCharArray())
|
||||||
terminal.putCharacter(c);
|
terminal.putCharacter(c);
|
||||||
|
@ -119,18 +159,20 @@ public class LispTerminal implements Runnable {
|
||||||
private void doCharacter(KeyStroke keyStroke) {
|
private void doCharacter(KeyStroke keyStroke) {
|
||||||
TerminalPosition cursorPosition = terminal.getCursorPosition();
|
TerminalPosition cursorPosition = terminal.getCursorPosition();
|
||||||
|
|
||||||
if (cursorPosition.getColumn() < currentLine.length()) {
|
if (isPossibleToMoveRight(cursorPosition)) {
|
||||||
String remaining = keyStroke.getCharacter()
|
String remaining = keyStroke.getCharacter()
|
||||||
+ currentLine.substring(cursorPosition.getColumn(), currentLine.length());
|
+ currentLine.substring(distanceFromOrigin(cursorPosition), currentLine.length());
|
||||||
currentLine = currentLine.substring(0, cursorPosition.getColumn()) + remaining;
|
currentLine = currentLine.substring(0, distanceFromOrigin(cursorPosition)) + remaining;
|
||||||
|
|
||||||
for (char c : remaining.toCharArray())
|
for (char c : remaining.toCharArray())
|
||||||
terminal.putCharacter(c);
|
terminal.putCharacter(c);
|
||||||
|
|
||||||
terminal.setCursorPosition(cursorPosition.withRelativeColumn(1));
|
advanceCursor(cursorPosition);
|
||||||
} else {
|
} else {
|
||||||
terminal.putCharacter(keyStroke.getCharacter());
|
terminal.putCharacter(keyStroke.getCharacter());
|
||||||
currentLine += keyStroke.getCharacter();
|
currentLine += keyStroke.getCharacter();
|
||||||
|
|
||||||
|
advanceCursor(cursorPosition);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue