From 462673ba64f6489ac17adf7088811c1613cb2e1f Mon Sep 17 00:00:00 2001 From: Mike Cifelli Date: Fri, 17 Mar 2017 19:40:56 -0400 Subject: [PATCH] Add line wrapping support to the terminal --- src/interpreter/FileLispInterpreter.java | 5 ++ src/interpreter/LispInterpreter.java | 2 +- .../LispInterpreterBuilderImpl.java | 2 +- src/terminal/LispTerminal.java | 70 +++++++++++++++---- 4 files changed, 63 insertions(+), 16 deletions(-) create mode 100644 src/interpreter/FileLispInterpreter.java diff --git a/src/interpreter/FileLispInterpreter.java b/src/interpreter/FileLispInterpreter.java new file mode 100644 index 0000000..4356ad9 --- /dev/null +++ b/src/interpreter/FileLispInterpreter.java @@ -0,0 +1,5 @@ +package interpreter; + +public class FileLispInterpreter extends LispInterpreter { + +} diff --git a/src/interpreter/LispInterpreter.java b/src/interpreter/LispInterpreter.java index 183d609..40231eb 100644 --- a/src/interpreter/LispInterpreter.java +++ b/src/interpreter/LispInterpreter.java @@ -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; diff --git a/src/interpreter/LispInterpreterBuilderImpl.java b/src/interpreter/LispInterpreterBuilderImpl.java index e4f7381..29fb195 100644 --- a/src/interpreter/LispInterpreterBuilderImpl.java +++ b/src/interpreter/LispInterpreterBuilderImpl.java @@ -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 { diff --git a/src/terminal/LispTerminal.java b/src/terminal/LispTerminal.java index 7471b14..97709c8 100644 --- a/src/terminal/LispTerminal.java +++ b/src/terminal/LispTerminal.java @@ -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); } }