improved terminal with history
This commit is contained in:
parent
dbd8038851
commit
3a2613d916
@ -1,6 +1,5 @@
|
||||
package bin;
|
||||
|
||||
import kernel.log.Log;
|
||||
import kernel.binstore.BinStore;
|
||||
import kernel.ps.ProcessHandle;
|
||||
import kernel.ps.Process;
|
||||
@ -11,11 +10,18 @@ import kernel.ui.WindowContext;
|
||||
using tink.CoreApi;
|
||||
|
||||
class Terminal implements Process {
|
||||
private var context:WindowContext;
|
||||
private static inline final MAX_BACKLOG:Int = 100;
|
||||
|
||||
private var handle:ProcessHandle;
|
||||
|
||||
private var ctx:WindowContext;
|
||||
private var requestRender: () -> Void;
|
||||
|
||||
private var input:String = "";
|
||||
private var backlog:Array<String> = [];
|
||||
private var handle:ProcessHandle;
|
||||
private var requestRender: () -> Void;
|
||||
private var history:Array<String> = [];
|
||||
private var historyIndex:Int = 0;
|
||||
|
||||
private var runningPID:PID = -1;
|
||||
|
||||
public function new() {}
|
||||
@ -25,18 +31,20 @@ class Terminal implements Process {
|
||||
|
||||
var statelessContext = handle.createStatelessWindowContext();
|
||||
|
||||
this.context = statelessContext.ctx;
|
||||
this.ctx = statelessContext.ctx;
|
||||
this.requestRender = statelessContext.requestRender;
|
||||
|
||||
statelessContext.setRenderFunc(this.render);
|
||||
|
||||
handle.addCallbackLink(this.context.onChar.handle(char -> {
|
||||
// Add input event handlers
|
||||
handle.addCallbackLink(this.ctx.onChar.handle(char -> {
|
||||
if (this.runningPID > 0) return;
|
||||
this.input += char;
|
||||
this.requestRender();
|
||||
}));
|
||||
|
||||
handle.addCallbackLink(this.context.onKey.handle(e -> {
|
||||
// Add key event handlers
|
||||
handle.addCallbackLink(this.ctx.onKey.handle(e -> {
|
||||
switch (e.keyCode) {
|
||||
case 259: // Backspace
|
||||
if (this.runningPID > 0) return;
|
||||
@ -48,9 +56,16 @@ class Terminal implements Process {
|
||||
var command = this.input;
|
||||
this.input = "";
|
||||
this.requestRender();
|
||||
this.historyIndex = 0;
|
||||
this.invokeCommand(command);
|
||||
case 269: // END
|
||||
this.stopCurrentPS();
|
||||
case 265: // UP
|
||||
if (this.historyIndex < this.history.length) {
|
||||
this.historyIndex++;
|
||||
this.input = this.history[this.history.length - this.historyIndex];
|
||||
this.requestRender();
|
||||
}
|
||||
}
|
||||
}));
|
||||
|
||||
@ -66,12 +81,7 @@ class Terminal implements Process {
|
||||
}
|
||||
|
||||
private function render() {
|
||||
redrawBacklog();
|
||||
redrawInput();
|
||||
}
|
||||
|
||||
private function redrawBacklog() {
|
||||
var size = this.context.getSize();
|
||||
var size = this.ctx.getSize();
|
||||
var linesAvailable = size.y - 1;
|
||||
|
||||
var start:Int = this.backlog.length - linesAvailable;
|
||||
@ -79,29 +89,28 @@ class Terminal implements Process {
|
||||
for (i in 0...linesAvailable) {
|
||||
var line = this.backlog[start + i];
|
||||
|
||||
this.context.setCursorPos(0, i);
|
||||
this.context.clearLine();
|
||||
this.ctx.setCursorPos(0, i);
|
||||
this.ctx.clearLine();
|
||||
|
||||
if (line != null) {
|
||||
this.context.write(line);
|
||||
this.ctx.write(line);
|
||||
}
|
||||
}
|
||||
this.moveCursorToInput();
|
||||
}
|
||||
|
||||
private function redrawInput() {
|
||||
var size = this.context.getSize();
|
||||
this.ctx.setCursorPos(0, size.y - 1);
|
||||
this.ctx.clearLine();
|
||||
|
||||
this.context.setCursorPos(0, size.y - 1);
|
||||
this.context.clearLine();
|
||||
this.ctx.setTextColor(Color.Blue);
|
||||
this.ctx.write("> ");
|
||||
|
||||
this.context.setTextColor(Color.Blue);
|
||||
this.context.write("> ");
|
||||
this.ctx.setTextColor(Color.White);
|
||||
this.ctx.write(this.input);
|
||||
|
||||
this.context.setTextColor(Color.White);
|
||||
this.context.write(this.input);
|
||||
|
||||
this.context.setCursorBlink(true);
|
||||
if (this.runningPID < 0) {
|
||||
this.ctx.setCursorBlink(true);
|
||||
} else {
|
||||
this.ctx.setCursorBlink(false);
|
||||
}
|
||||
}
|
||||
|
||||
private function invokeCommand(command:String):Void {
|
||||
@ -110,6 +119,13 @@ class Terminal implements Process {
|
||||
if (args.length == 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
this.history.push(command);
|
||||
|
||||
if (this.history.length > MAX_BACKLOG) {
|
||||
this.history.shift();
|
||||
}
|
||||
|
||||
var commandName = args[0];
|
||||
|
||||
// Handle built-in commands
|
||||
@ -125,8 +141,7 @@ class Terminal implements Process {
|
||||
var ps = getProgByName(commandName);
|
||||
if (ps == null) {
|
||||
this.backlog.push("Unknown command: " + commandName);
|
||||
this.redrawBacklog();
|
||||
this.redrawInput();
|
||||
this.requestRender();
|
||||
return;
|
||||
}
|
||||
|
||||
@ -149,6 +164,11 @@ class Terminal implements Process {
|
||||
} else {
|
||||
this.backlog[this.backlog.length - 1] += s;
|
||||
}
|
||||
|
||||
// Trim the backlog if it's too long
|
||||
if (this.backlog.length > MAX_BACKLOG) {
|
||||
this.backlog.shift();
|
||||
}
|
||||
}
|
||||
|
||||
this.requestRender();
|
||||
@ -163,9 +183,12 @@ class Terminal implements Process {
|
||||
}
|
||||
});
|
||||
|
||||
this.context.setCursorBlink(false);
|
||||
this.ctx.setCursorBlink(false);
|
||||
}
|
||||
|
||||
/**
|
||||
Convter a command string into an array of arguments where the first element is the command name
|
||||
**/
|
||||
private function parseArgs(command:String):Array<String> {
|
||||
// TODO: tim and quote handling
|
||||
return command.split(" ");
|
||||
@ -173,7 +196,7 @@ class Terminal implements Process {
|
||||
|
||||
private function clear() {
|
||||
this.backlog = [];
|
||||
this.redrawBacklog();
|
||||
this.requestRender();
|
||||
}
|
||||
|
||||
private function getProgByName(name:String):Process {
|
||||
@ -186,7 +209,7 @@ class Terminal implements Process {
|
||||
}
|
||||
|
||||
private function moveCursorToInput() {
|
||||
var size = this.context.getSize();
|
||||
this.context.setCursorPos(this.input.length + 2, size.y - 1);
|
||||
var size = this.ctx.getSize();
|
||||
this.ctx.setCursorPos(this.input.length + 2, size.y - 1);
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user