use of com.googlecode.lanterna.terminal.ansi.UnixTerminal in project claro-lang by JasonSteving99.
the class ReplTerminal method runTerminal.
public void runTerminal() {
DefaultTerminalFactory defaultTerminalFactory = new DefaultTerminalFactory();
UnixTerminal terminal = null;
try {
terminal = new UnixTerminal(System.in, System.out, StandardCharsets.UTF_8, CtrlCBehaviour.CTRL_C_KILLS_APPLICATION);
terminal.clearScreen();
terminal.setCursorVisible(true);
final TextGraphics textGraphics = terminal.newTextGraphics();
// Change to a background/foreground color combo that pops more.
textGraphics.setForegroundColor(TextColor.ANSI.WHITE);
textGraphics.setBackgroundColor(TextColor.ANSI.BLACK);
textGraphics.putString(2, 0, String.format("ClaroLang %s - Press ESC/Ctr-C to exit", claroVersion), SGR.BOLD);
// Change back to the default background/foreground colors.
textGraphics.setForegroundColor(TextColor.ANSI.DEFAULT);
textGraphics.setBackgroundColor(TextColor.ANSI.DEFAULT);
final String PROMPT = ">>> ";
textGraphics.putString(0, 1, PROMPT, SGR.BOLD);
// Need to flush for changes to become visible.
terminal.flush();
// Setup the control vars that'll track the current user position and state as they use the terminal.
StringBuilder currInstruction = new StringBuilder();
Stack<String> prevInstructions = new Stack<>();
int instructionIndex = 0;
int currLine = 1;
int currPromptCol = 0;
KeyStroke keyStroke = terminal.readInput();
while (keyStroke.getKeyType() != KeyType.Escape) {
switch(keyStroke.getKeyType()) {
case Character:
Character currKeyStrokeCharacter = keyStroke.getCharacter();
currInstruction.insert(currPromptCol, keyStroke.getCharacter().charValue());
currPromptCol++;
break;
case ArrowUp:
if (instructionIndex == 0) {
terminal.bell();
} else {
textGraphics.putString(0, currLine, PROMPT + getSpacesStringOfLength(currInstruction.length()));
currInstruction.delete(0, currInstruction.length());
currInstruction.append(prevInstructions.elementAt(--instructionIndex));
currPromptCol = currInstruction.length();
}
break;
case ArrowDown:
if (instructionIndex == prevInstructions.size() - 1) {
// Moving down after the last instruction, should just clear everything.
textGraphics.putString(0, currLine, PROMPT + getSpacesStringOfLength(currInstruction.length()));
currInstruction.delete(0, currInstruction.length());
instructionIndex++;
currPromptCol = 0;
} else if (instructionIndex >= prevInstructions.size()) {
terminal.bell();
} else {
textGraphics.putString(0, currLine, PROMPT + getSpacesStringOfLength(currInstruction.length()));
currInstruction.delete(0, currInstruction.length());
currInstruction.append(prevInstructions.elementAt(++instructionIndex));
currPromptCol = currInstruction.length();
}
break;
case ArrowRight:
if (currPromptCol < currInstruction.length()) {
currPromptCol++;
} else {
terminal.bell();
}
break;
case ArrowLeft:
if (currPromptCol > 0) {
currPromptCol--;
} else {
terminal.bell();
}
break;
case Backspace:
if (currPromptCol > 0) {
// Overwrite the buffer so that after modifying the currInstruction, the terminal will show the correctly
// edited instruction.
textGraphics.putString(0, currLine, getSpacesStringOfLength(PROMPT.length() + currInstruction.length()));
currInstruction.deleteCharAt(currPromptCol - 1);
currPromptCol--;
} else {
terminal.bell();
}
break;
case Enter:
if (currInstruction.length() > 0) {
prevInstructions.push(currInstruction.toString());
instructionIndex = prevInstructions.size();
currInstruction.delete(0, currInstruction.length());
// Setup the cursor for potential output from inputHandler.
if (++currLine >= terminal.getTerminalSize().getRows()) {
terminal.scrollLines(0, currLine - 1, 1);
}
terminal.setCursorPosition(0, currLine);
inputHandler.apply(prevInstructions.peek());
currLine = terminal.getCursorPosition().getRow();
} else {
currLine++;
}
if (currLine >= terminal.getTerminalSize().getRows()) {
/*
Note that currLine is potentially pointing ahead of the last row shown in the terminal
currently because the inputHandler may have output multiple lines. In this case, this
scrollLines method is being told to scroll lines that are currently below the fold, but
it appears that it handles this well.
*/
terminal.scrollLines(0, currLine, 1);
}
currPromptCol = 0;
break;
}
// Print the currInstruction in two parts to leave the cursor exactly where the user expects it.
textGraphics.putString(0, currLine, PROMPT + currInstruction.toString(), SGR.BOLD);
textGraphics.putString(0, currLine, PROMPT + currInstruction.substring(0, currPromptCol));
terminal.flush();
keyStroke = terminal.readInput();
}
} catch (IOException e) {
e.printStackTrace();
} finally {
if (terminal != null) {
try {
terminal.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
Aggregations