added terminal app with example hello world
This commit is contained in:
17
src/bin/HelloWorld.hx
Normal file
17
src/bin/HelloWorld.hx
Normal file
@@ -0,0 +1,17 @@
|
||||
package bin;
|
||||
|
||||
import lib.TermHandle;
|
||||
import kernel.fs.FileHandler.WriteHandle;
|
||||
import lib.CLIBase;
|
||||
|
||||
class HelloWorld extends CLIBase {
|
||||
public function invoke(handle: TermHandle):Bool {
|
||||
var world:String = "world";
|
||||
if (handle.args.length > 0) {
|
||||
world = handle.args[0];
|
||||
}
|
||||
|
||||
handle.write('Hello, $world!');
|
||||
return true;
|
||||
}
|
||||
}
|
||||
151
src/bin/Terminal.hx
Normal file
151
src/bin/Terminal.hx
Normal file
@@ -0,0 +1,151 @@
|
||||
package bin;
|
||||
|
||||
import lib.TermHandle;
|
||||
import lib.CLIBase;
|
||||
import util.Color;
|
||||
import kernel.ui.WindowContext;
|
||||
import kernel.ui.WindowManager;
|
||||
|
||||
class Terminal {
|
||||
private var context:WindowContext;
|
||||
private var input:String = "";
|
||||
private var backlog: Array<String> = [];
|
||||
|
||||
public function new() {}
|
||||
|
||||
public function execute() {
|
||||
this.context = WindowManager.instance.createNewContext();
|
||||
|
||||
this.context.onChar.handle(char -> {
|
||||
this.input += char;
|
||||
this.redrawInput();
|
||||
});
|
||||
|
||||
this.context.onKey.handle(e -> {
|
||||
if (e.keyCode == 259) {
|
||||
this.input = this.input.substr(0, this.input.length - 1);
|
||||
this.redrawInput();
|
||||
} else if (e.keyCode == 257) {
|
||||
this.backlog.push("> " + this.input);
|
||||
var command = this.input;
|
||||
this.input = "";
|
||||
this.redrawBacklog();
|
||||
this.redrawInput();
|
||||
this.invokeCommand(command);
|
||||
}
|
||||
});
|
||||
|
||||
WindowManager.instance.focusContextToOutput(context, "main");
|
||||
this.redrawInput();
|
||||
}
|
||||
|
||||
private function redrawBacklog() {
|
||||
var size = this.context.getSize();
|
||||
var linesAvailable = size.y - 1;
|
||||
|
||||
var start:Int = this.backlog.length - linesAvailable;
|
||||
|
||||
for (i in 0...linesAvailable){
|
||||
var line = this.backlog[start + i];
|
||||
|
||||
this.context.setCursorPos(0, i);
|
||||
this.context.clearLine();
|
||||
|
||||
if (line != null) {
|
||||
this.context.write(line);
|
||||
}
|
||||
}
|
||||
this.moveCursorToInput();
|
||||
}
|
||||
|
||||
private function redrawInput() {
|
||||
var size = this.context.getSize();
|
||||
|
||||
this.context.setCursorPos(0, size.y - 1);
|
||||
this.context.clearLine();
|
||||
|
||||
this.context.setTextColor(Color.Blue);
|
||||
this.context.write("> ");
|
||||
|
||||
this.context.setTextColor(Color.White);
|
||||
this.context.write(this.input);
|
||||
|
||||
this.context.setCursorBlink(true);
|
||||
}
|
||||
|
||||
private function invokeCommand(command: String):Void{
|
||||
var args = this.parseArgs(command);
|
||||
|
||||
if (args.length == 0) {
|
||||
return;
|
||||
}
|
||||
var commandName = args[0];
|
||||
|
||||
// Handle built-in commands
|
||||
switch (commandName) {
|
||||
case "clear":
|
||||
this.clear();
|
||||
return;
|
||||
}
|
||||
|
||||
var commandArgs:Array<String> = args.slice(1);
|
||||
var hadInput = false;
|
||||
var handle = new TermHandle(commandArgs,{
|
||||
onWrite: (s:String) -> {
|
||||
if (!hadInput) {
|
||||
this.backlog.push("");
|
||||
hadInput = true;
|
||||
}
|
||||
this.backlog[this.backlog.length - 1] += s;
|
||||
this.redrawBacklog();
|
||||
},
|
||||
onNewLine: () -> {
|
||||
this.backlog.push("");
|
||||
this.redrawBacklog();
|
||||
}
|
||||
});
|
||||
|
||||
var prog:CLIBase = getProgByName(commandName);
|
||||
|
||||
if (prog == null) {
|
||||
this.backlog.push("Command not found: " + commandName);
|
||||
this.redrawBacklog();
|
||||
return;
|
||||
}
|
||||
|
||||
this.context.setCursorBlink(false);
|
||||
|
||||
prog.invoke(handle);
|
||||
|
||||
// Cleanup extra newline
|
||||
if (this.backlog[this.backlog.length - 1] == "") {
|
||||
this.backlog.pop();
|
||||
}
|
||||
|
||||
this.redrawInput();
|
||||
}
|
||||
|
||||
private function parseArgs(command: String): Array<String> {
|
||||
// TODO: tim and quote handling
|
||||
return command.split(" ");
|
||||
}
|
||||
|
||||
private function clear() {
|
||||
this.backlog = [];
|
||||
this.redrawBacklog();
|
||||
}
|
||||
|
||||
private function getProgByName(name: String): CLIBase {
|
||||
switch (name) {
|
||||
case "hello":
|
||||
return new HelloWorld();
|
||||
default:
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
private function moveCursorToInput() {
|
||||
var size = this.context.getSize();
|
||||
this.context.setCursorPos(this.input.length + 2, size.y - 1);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user