Add line wrapping support to the terminal
This commit is contained in:
		
							parent
							
								
									ac349c94cb
								
							
						
					
					
						commit
						462673ba64
					
				
							
								
								
									
										5
									
								
								src/interpreter/FileLispInterpreter.java
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										5
									
								
								src/interpreter/FileLispInterpreter.java
									
									
									
									
									
										Normal file
									
								
							| @ -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,32 +73,70 @@ 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(); | ||||||
|  | 
 | ||||||
|  |         if (isPossibleToMoveLeft(cursorPosition)) | ||||||
|  |             if (cursorPosition.getColumn() == 0) | ||||||
|  |                 terminal.setCursorPosition(terminal.getTerminalSize().getColumns(), cursorPosition.getRow() - 1); | ||||||
|  |             else | ||||||
|                 terminal.setCursorPosition(cursorPosition.withRelativeColumn(-1)); |                 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; | ||||||
|  | 
 | ||||||
|  |             if (cursorPosition.getColumn() == 0) | ||||||
|  |                 terminal.setCursorPosition(terminal.getTerminalSize().getColumns(), cursorPosition.getRow() - 1); | ||||||
|  |             else | ||||||
|                 terminal.setCursorPosition(cursorPosition.withRelativeColumn(-1)); |                 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(' '); | ||||||
|  | 
 | ||||||
|  |             if (cursorPosition.getColumn() == 0) | ||||||
|  |                 terminal.setCursorPosition(terminal.getTerminalSize().getColumns(), cursorPosition.getRow() - 1); | ||||||
|  |             else | ||||||
|                 terminal.setCursorPosition(cursorPosition.withRelativeColumn(-1)); |                 terminal.setCursorPosition(cursorPosition.withRelativeColumn(-1)); | ||||||
|         } |         } | ||||||
|     } |     } | ||||||
| @ -104,9 +144,9 @@ public class LispTerminal implements Runnable { | |||||||
|     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
	
	Block a user