Start converting terminal classes to kotlin
This commit is contained in:
parent
516603a948
commit
e76aefa3d1
|
@ -1,6 +1,5 @@
|
||||||
package recursion
|
package recursion
|
||||||
|
|
||||||
@FunctionalInterface
|
|
||||||
interface TailCall<T> {
|
interface TailCall<T> {
|
||||||
|
|
||||||
fun isComplete() = false
|
fun isComplete() = false
|
||||||
|
|
|
@ -1,14 +0,0 @@
|
||||||
package terminal;
|
|
||||||
|
|
||||||
import com.googlecode.lanterna.terminal.IOSafeTerminal;
|
|
||||||
|
|
||||||
public interface ControlSequence {
|
|
||||||
|
|
||||||
default String getCode() {
|
|
||||||
return "";
|
|
||||||
}
|
|
||||||
|
|
||||||
default void applyTo(IOSafeTerminal terminal) {}
|
|
||||||
|
|
||||||
public static class NullControlSequence implements ControlSequence {}
|
|
||||||
}
|
|
|
@ -0,0 +1,13 @@
|
||||||
|
package terminal
|
||||||
|
|
||||||
|
import com.googlecode.lanterna.terminal.IOSafeTerminal
|
||||||
|
|
||||||
|
interface ControlSequence {
|
||||||
|
|
||||||
|
val code
|
||||||
|
get() = ""
|
||||||
|
|
||||||
|
fun applyTo(terminal: IOSafeTerminal) {}
|
||||||
|
|
||||||
|
class NullControlSequence : ControlSequence
|
||||||
|
}
|
|
@ -1,58 +0,0 @@
|
||||||
package terminal;
|
|
||||||
|
|
||||||
import stream.SafeInputStream;
|
|
||||||
import util.Characters;
|
|
||||||
|
|
||||||
import static java.lang.Character.isDigit;
|
|
||||||
|
|
||||||
class ControlSequenceHandler {
|
|
||||||
|
|
||||||
public static final boolean isEscape(char c) {
|
|
||||||
return c == Characters.UNICODE_ESCAPE;
|
|
||||||
}
|
|
||||||
|
|
||||||
private ControlSequenceLookup controlSequenceLookup;
|
|
||||||
private SafeInputStream input;
|
|
||||||
private String code;
|
|
||||||
private int currentCharacter;
|
|
||||||
|
|
||||||
public ControlSequenceHandler() {
|
|
||||||
this.controlSequenceLookup = new ControlSequenceLookup();
|
|
||||||
}
|
|
||||||
|
|
||||||
public ControlSequence parse(SafeInputStream inputStream) {
|
|
||||||
input = inputStream;
|
|
||||||
code = "";
|
|
||||||
|
|
||||||
readCharacter();
|
|
||||||
if (isExpectedFirstCharacter())
|
|
||||||
readCode();
|
|
||||||
|
|
||||||
return controlSequenceLookup.get((char) currentCharacter, code);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void readCharacter() {
|
|
||||||
currentCharacter = input.read();
|
|
||||||
}
|
|
||||||
|
|
||||||
private boolean isExpectedFirstCharacter() {
|
|
||||||
return isCharacter() && isLeftBracket();
|
|
||||||
}
|
|
||||||
|
|
||||||
private boolean isCharacter() {
|
|
||||||
return currentCharacter != Characters.EOF;
|
|
||||||
}
|
|
||||||
|
|
||||||
private boolean isLeftBracket() {
|
|
||||||
return (char) currentCharacter == Characters.LEFT_SQUARE_BRACKET;
|
|
||||||
}
|
|
||||||
|
|
||||||
private void readCode() {
|
|
||||||
for (readCharacter(); isPartOfCode(); readCharacter())
|
|
||||||
code += (char) currentCharacter;
|
|
||||||
}
|
|
||||||
|
|
||||||
private boolean isPartOfCode() {
|
|
||||||
return isCharacter() && isDigit((char) currentCharacter);
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -0,0 +1,53 @@
|
||||||
|
package terminal
|
||||||
|
|
||||||
|
import stream.SafeInputStream
|
||||||
|
import util.Characters.EOF
|
||||||
|
import util.Characters.LEFT_SQUARE_BRACKET
|
||||||
|
import util.Characters.UNICODE_ESCAPE
|
||||||
|
import java.lang.Character.isDigit
|
||||||
|
|
||||||
|
class ControlSequenceHandler {
|
||||||
|
|
||||||
|
private val controlSequenceLookup: ControlSequenceLookup = ControlSequenceLookup()
|
||||||
|
private var currentCharacter: Int = 0
|
||||||
|
private lateinit var input: SafeInputStream
|
||||||
|
private lateinit var code: String
|
||||||
|
|
||||||
|
private fun isExpectedFirstCharacter() = isCharacter() && isLeftBracket()
|
||||||
|
private fun isCharacter() = currentCharacter != EOF
|
||||||
|
private fun isLeftBracket() = currentCharacter.toChar() == LEFT_SQUARE_BRACKET
|
||||||
|
private fun isPartOfCode() = isCharacter() && isDigit(currentCharacter.toChar())
|
||||||
|
|
||||||
|
fun parse(inputStream: SafeInputStream): ControlSequence {
|
||||||
|
input = inputStream
|
||||||
|
code = ""
|
||||||
|
|
||||||
|
readCharacter()
|
||||||
|
|
||||||
|
if (isExpectedFirstCharacter())
|
||||||
|
readCode()
|
||||||
|
|
||||||
|
return controlSequenceLookup[currentCharacter.toChar(), code]
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun readCharacter() {
|
||||||
|
currentCharacter = input.read()
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun readCode() {
|
||||||
|
readCharacter()
|
||||||
|
|
||||||
|
while (isPartOfCode()) {
|
||||||
|
code += currentCharacter.toChar()
|
||||||
|
readCharacter()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
companion object {
|
||||||
|
|
||||||
|
@JvmStatic
|
||||||
|
fun isEscape(c: Char): Boolean {
|
||||||
|
return c == UNICODE_ESCAPE
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,34 +0,0 @@
|
||||||
package terminal;
|
|
||||||
|
|
||||||
import terminal.ControlSequence.NullControlSequence;
|
|
||||||
|
|
||||||
import java.util.HashMap;
|
|
||||||
import java.util.Map;
|
|
||||||
|
|
||||||
import static terminal.SelectGraphicRendition.SGR_COMMAND;
|
|
||||||
|
|
||||||
public class ControlSequenceLookup {
|
|
||||||
|
|
||||||
private Map<Character, Map<String, ControlSequence>> commands;
|
|
||||||
|
|
||||||
public ControlSequenceLookup() {
|
|
||||||
this.commands = new HashMap<>();
|
|
||||||
|
|
||||||
initializeCommands();
|
|
||||||
}
|
|
||||||
|
|
||||||
private void initializeCommands() {
|
|
||||||
Map<String, ControlSequence> sgrCodes = new HashMap<>();
|
|
||||||
|
|
||||||
for (SelectGraphicRendition sgr : SelectGraphicRendition.values())
|
|
||||||
sgrCodes.put(sgr.getCode(), sgr);
|
|
||||||
|
|
||||||
commands.put(SGR_COMMAND, sgrCodes);
|
|
||||||
}
|
|
||||||
|
|
||||||
public ControlSequence get(char command, String code) {
|
|
||||||
Map<String, ControlSequence> codes = commands.getOrDefault(command, new HashMap<>());
|
|
||||||
|
|
||||||
return codes.getOrDefault(code, new NullControlSequence());
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -0,0 +1,15 @@
|
||||||
|
package terminal
|
||||||
|
|
||||||
|
import terminal.ControlSequence.NullControlSequence
|
||||||
|
import terminal.SelectGraphicRendition.Companion.SGR_COMMAND
|
||||||
|
|
||||||
|
class ControlSequenceLookup {
|
||||||
|
|
||||||
|
private val commands = mapOf(SGR_COMMAND to SelectGraphicRendition.values().associateBy({ it.code }, { it }))
|
||||||
|
|
||||||
|
operator fun get(command: Char, code: String): ControlSequence {
|
||||||
|
val codes = commands.getOrDefault(command, emptyMap())
|
||||||
|
|
||||||
|
return codes.getOrDefault(code, NullControlSequence())
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,70 +0,0 @@
|
||||||
package terminal;
|
|
||||||
|
|
||||||
import com.googlecode.lanterna.TextColor;
|
|
||||||
import com.googlecode.lanterna.terminal.IOSafeTerminal;
|
|
||||||
|
|
||||||
public enum SelectGraphicRendition implements ControlSequence {
|
|
||||||
|
|
||||||
RESET {
|
|
||||||
@Override
|
|
||||||
public String getCode() {
|
|
||||||
return "0";
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void applyTo(IOSafeTerminal terminal) {
|
|
||||||
terminal.resetColorAndSGR();
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
RED {
|
|
||||||
@Override
|
|
||||||
public String getCode() {
|
|
||||||
return "31";
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void applyTo(IOSafeTerminal terminal) {
|
|
||||||
terminal.setForegroundColor(TextColor.ANSI.RED);
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
GREEN {
|
|
||||||
@Override
|
|
||||||
public String getCode() {
|
|
||||||
return "32";
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void applyTo(IOSafeTerminal terminal) {
|
|
||||||
terminal.setForegroundColor(TextColor.ANSI.GREEN);
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
YELLOW {
|
|
||||||
@Override
|
|
||||||
public String getCode() {
|
|
||||||
return "33";
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void applyTo(IOSafeTerminal terminal) {
|
|
||||||
terminal.setForegroundColor(TextColor.ANSI.YELLOW);
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
PURPLE {
|
|
||||||
@Override
|
|
||||||
public String getCode() {
|
|
||||||
return "35";
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void applyTo(IOSafeTerminal terminal) {
|
|
||||||
terminal.setForegroundColor(TextColor.ANSI.MAGENTA);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
public static final char SGR_COMMAND = 'm';
|
|
||||||
|
|
||||||
}
|
|
|
@ -0,0 +1,53 @@
|
||||||
|
package terminal
|
||||||
|
|
||||||
|
import com.googlecode.lanterna.TextColor.ANSI
|
||||||
|
import com.googlecode.lanterna.terminal.IOSafeTerminal
|
||||||
|
|
||||||
|
enum class SelectGraphicRendition : ControlSequence {
|
||||||
|
|
||||||
|
RESET {
|
||||||
|
override val code = "0"
|
||||||
|
|
||||||
|
override fun applyTo(terminal: IOSafeTerminal) {
|
||||||
|
terminal.resetColorAndSGR()
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
RED {
|
||||||
|
override val code = "31"
|
||||||
|
|
||||||
|
override fun applyTo(terminal: IOSafeTerminal) {
|
||||||
|
terminal.setForegroundColor(ANSI.RED)
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
GREEN {
|
||||||
|
override val code = "32"
|
||||||
|
|
||||||
|
override fun applyTo(terminal: IOSafeTerminal) {
|
||||||
|
terminal.setForegroundColor(ANSI.GREEN)
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
YELLOW {
|
||||||
|
override val code = "33"
|
||||||
|
|
||||||
|
override fun applyTo(terminal: IOSafeTerminal) {
|
||||||
|
terminal.setForegroundColor(ANSI.YELLOW)
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
PURPLE {
|
||||||
|
override val code = "35"
|
||||||
|
|
||||||
|
override fun applyTo(terminal: IOSafeTerminal) {
|
||||||
|
terminal.setForegroundColor(ANSI.MAGENTA)
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
companion object {
|
||||||
|
|
||||||
|
@JvmStatic
|
||||||
|
val SGR_COMMAND = 'm'
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,69 +0,0 @@
|
||||||
package terminal;
|
|
||||||
|
|
||||||
import com.googlecode.lanterna.terminal.IOSafeTerminal;
|
|
||||||
import stream.LispIOException;
|
|
||||||
|
|
||||||
import java.io.IOException;
|
|
||||||
import java.io.PipedInputStream;
|
|
||||||
import java.io.PipedOutputStream;
|
|
||||||
|
|
||||||
public class TerminalConfiguration {
|
|
||||||
|
|
||||||
private PipedOutputStream inputWriter;
|
|
||||||
private PipedInputStream inputReader;
|
|
||||||
private PipedOutputStream outputWriter;
|
|
||||||
private PipedInputStream outputReader;
|
|
||||||
private IOSafeTerminal terminal;
|
|
||||||
|
|
||||||
public void setInputPair(PipedOutputStream inputWriter, PipedInputStream inputReader) {
|
|
||||||
this.inputWriter = inputWriter;
|
|
||||||
this.inputReader = inputReader;
|
|
||||||
connectInputPair();
|
|
||||||
}
|
|
||||||
|
|
||||||
private void connectInputPair() {
|
|
||||||
try {
|
|
||||||
inputWriter.connect(inputReader);
|
|
||||||
} catch (IOException e) {
|
|
||||||
throw new LispIOException(e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setOutputPair(PipedOutputStream outputWriter, PipedInputStream outputReader) {
|
|
||||||
this.outputWriter = outputWriter;
|
|
||||||
this.outputReader = outputReader;
|
|
||||||
connectOutputPair();
|
|
||||||
}
|
|
||||||
|
|
||||||
private void connectOutputPair() {
|
|
||||||
try {
|
|
||||||
outputWriter.connect(outputReader);
|
|
||||||
} catch (IOException e) {
|
|
||||||
throw new LispIOException(e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setTerminal(IOSafeTerminal terminal) {
|
|
||||||
this.terminal = terminal;
|
|
||||||
}
|
|
||||||
|
|
||||||
public PipedOutputStream getInputWriter() {
|
|
||||||
return inputWriter;
|
|
||||||
}
|
|
||||||
|
|
||||||
public PipedInputStream getInputReader() {
|
|
||||||
return inputReader;
|
|
||||||
}
|
|
||||||
|
|
||||||
public PipedOutputStream getOutputWriter() {
|
|
||||||
return outputWriter;
|
|
||||||
}
|
|
||||||
|
|
||||||
public PipedInputStream getOutputReader() {
|
|
||||||
return outputReader;
|
|
||||||
}
|
|
||||||
|
|
||||||
public IOSafeTerminal getTerminal() {
|
|
||||||
return terminal;
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -0,0 +1,49 @@
|
||||||
|
package terminal
|
||||||
|
|
||||||
|
import com.googlecode.lanterna.terminal.IOSafeTerminal
|
||||||
|
import stream.LispIOException
|
||||||
|
|
||||||
|
import java.io.IOException
|
||||||
|
import java.io.PipedInputStream
|
||||||
|
import java.io.PipedOutputStream
|
||||||
|
|
||||||
|
class TerminalConfiguration {
|
||||||
|
|
||||||
|
var inputWriter: PipedOutputStream? = null
|
||||||
|
private set
|
||||||
|
lateinit var inputReader: PipedInputStream
|
||||||
|
private set
|
||||||
|
var outputWriter: PipedOutputStream? = null
|
||||||
|
private set
|
||||||
|
var outputReader: PipedInputStream? = null
|
||||||
|
private set
|
||||||
|
var terminal: IOSafeTerminal? = null
|
||||||
|
|
||||||
|
fun setInputPair(inputWriter: PipedOutputStream, inputReader: PipedInputStream) {
|
||||||
|
this.inputWriter = inputWriter
|
||||||
|
this.inputReader = inputReader
|
||||||
|
connectInputPair()
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun connectInputPair() {
|
||||||
|
try {
|
||||||
|
inputWriter!!.connect(inputReader!!)
|
||||||
|
} catch (e: IOException) {
|
||||||
|
throw LispIOException(e)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun setOutputPair(outputWriter: PipedOutputStream, outputReader: PipedInputStream) {
|
||||||
|
this.outputWriter = outputWriter
|
||||||
|
this.outputReader = outputReader
|
||||||
|
connectOutputPair()
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun connectOutputPair() {
|
||||||
|
try {
|
||||||
|
outputWriter!!.connect(outputReader!!)
|
||||||
|
} catch (e: IOException) {
|
||||||
|
throw LispIOException(e)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,52 +0,0 @@
|
||||||
package terminal;
|
|
||||||
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
public class TerminalHistory {
|
|
||||||
|
|
||||||
private List<String> history;
|
|
||||||
private int lineIndex;
|
|
||||||
|
|
||||||
public TerminalHistory() {
|
|
||||||
this.history = new ArrayList<>();
|
|
||||||
this.history.add("");
|
|
||||||
this.lineIndex = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void addLine(String line) {
|
|
||||||
history.set(lastIndex(), line);
|
|
||||||
history.add("");
|
|
||||||
lineIndex = lastIndex();
|
|
||||||
}
|
|
||||||
|
|
||||||
private int lastIndex() {
|
|
||||||
return history.size() - 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void updateCurrentLine(String line) {
|
|
||||||
history.set(lineIndex, line);
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getPreviousLine() {
|
|
||||||
if (isBeginning())
|
|
||||||
return history.get(lineIndex);
|
|
||||||
|
|
||||||
return history.get(--lineIndex);
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean isBeginning() {
|
|
||||||
return lineIndex == 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getNextLine() {
|
|
||||||
if (isEnd())
|
|
||||||
return history.get(lineIndex);
|
|
||||||
|
|
||||||
return history.get(++lineIndex);
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean isEnd() {
|
|
||||||
return lineIndex == lastIndex();
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -0,0 +1,41 @@
|
||||||
|
package terminal
|
||||||
|
|
||||||
|
import java.util.ArrayList
|
||||||
|
|
||||||
|
class TerminalHistory {
|
||||||
|
|
||||||
|
private val history: MutableList<String>
|
||||||
|
private var lineIndex: Int = 0
|
||||||
|
|
||||||
|
val previousLine: String
|
||||||
|
get() = if (isBeginning) history[lineIndex] else history[--lineIndex]
|
||||||
|
|
||||||
|
val isBeginning: Boolean
|
||||||
|
get() = lineIndex == 0
|
||||||
|
|
||||||
|
val nextLine: String
|
||||||
|
get() = if (isEnd) history[lineIndex] else history[++lineIndex]
|
||||||
|
|
||||||
|
val isEnd: Boolean
|
||||||
|
get() = lineIndex == lastIndex()
|
||||||
|
|
||||||
|
init {
|
||||||
|
this.history = ArrayList()
|
||||||
|
this.history.add("")
|
||||||
|
this.lineIndex = 0
|
||||||
|
}
|
||||||
|
|
||||||
|
fun addLine(line: String) {
|
||||||
|
history[lastIndex()] = line
|
||||||
|
history.add("")
|
||||||
|
lineIndex = lastIndex()
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun lastIndex(): Int {
|
||||||
|
return history.size - 1
|
||||||
|
}
|
||||||
|
|
||||||
|
fun updateCurrentLine(line: String) {
|
||||||
|
history[lineIndex] = line
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue