Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- class Control {
- constructor(stream, raw) {
- this.data = "";
- this.tmp = "";
- this.stream = stream;
- this.raw = typeof raw !== 'undefined' ? raw : true
- if (this.raw) {
- this.stream.setRawMode(true);
- this.stream.resume();
- this.stream.setEncoding('utf8');
- }
- this.stream.on('data', data => this.inputHandler(data));
- this.cursorPosition = 0;
- this.commandHistory = ['console.log("This is a test command in history")', 'console.log("search test")'];
- this.historyPosition = this.commandHistory.length;
- this.searchIndex = this.commandHistory.length - 1;
- this.prevSearch = "";
- }
- processCommand(cmd) {
- if (cmd === "") { return }
- if (cmd !== this.commandHistory[this.commandHistory.length-1]) {
- this.commandHistory.push(cmd);
- }
- this.historyPosition = this.commandHistory.length;
- }
- inputHandler(data) {
- switch (data) {
- case '\u0003':
- // ctrl-c
- process.exit();
- break;
- case '\u0012':
- // ctrl-r
- this.search();
- break;
- case '\u001B\u005B\u0041':
- // up arrow
- this.showPrevCommand();
- break;
- case '\u001B\u005B\u0042':
- // down arrow
- this.showNextCommand();
- break;
- case '\u001B\u005B\u0044':
- // left arrow
- this.moveCursor('left');
- break;
- case '\u001B\u005B\u0043':
- // right arrow
- this.moveCursor('right');
- break;
- case '\u001B\u0062':
- // alt + left arrow
- this.moveCursor('left', true);
- break;
- case '\u001B\u0066':
- // alt + right arrow
- this.moveCursor('right', true);
- break;
- case '\u000D':
- // enter key
- this.stream.write("\n");
- this.processCommand(this.data);
- this.clearInput();
- this.data = "";
- this.tmp = "";
- break;
- case '\u007F':
- // backspace
- this.deleteCharacter();
- break;
- case '\u0009':
- // tab
- break;
- default:
- if (this.raw) {
- this.addCharacter(data);
- } else {
- this.data += data;
- let cmd;
- while (cmd = this.sliceCommand()){
- this.processCommand(cmd);
- }
- }
- }
- }
- clearInput() {
- if (!this.raw) { return }
- this.stream.write("\r" + Array(this.data.length).fill(" ").join("") + "\r");
- }
- moveCursor(direction, toWord) {
- if (direction === 'left') {
- this.cursorPosition = Math.max(0, this.cursorPosition - 1);
- if (toWord) {
- const idx = this.data.slice(0,this.cursorPosition).split("").reverse().join("").search(/\w[^\w]/);
- if (idx > -1) {
- this.cursorPosition = Math.max(0, this.cursorPosition - idx - 1);
- } else {
- this.cursorPosition = 0;
- }
- }
- } else if (direction === 'right') {
- this.cursorPosition = Math.min(this.data.length, this.cursorPosition + 1);
- if (toWord) {
- const idx = this.data.slice(this.cursorPosition).search(/[^\w]\w/);
- if (idx > -1) {
- this.cursorPosition = Math.min(this.data.length, this.cursorPosition + idx + 1);
- } else {
- this.cursorPosition = this.data.length;
- }
- }
- }
- this.stream.write("\r" + this.data.slice(0, this.cursorPosition));
- }
- updateLine(ifAtEnd) {
- if (this.cursorPosition === this.data.length) {
- this.stream.write(ifAtEnd);
- } else {
- this.stream.write("\r" + this.data);
- this.stream.write("\r" + this.data.slice(0, this.cursorPosition));
- }
- }
- addCharacter(character) {
- this.data = this.data.slice(0, this.cursorPosition) + character + this.data.slice(this.cursorPosition);
- this.tmp = this.data;
- this.cursorPosition++;
- this.updateLine(character);
- }
- deleteCharacter() {
- this.clearInput();
- this.data = this.data.slice(0, this.cursorPosition - 1) + this.data.slice(this.cursorPosition);
- this.tmp = this.data;
- this.cursorPosition = Math.max(0, this.cursorPosition - 1);
- this.updateLine(this.data);
- }
- showCommand(cmd) {
- this.clearInput();
- this.data = cmd;
- this.cursorPosition = this.data.length;
- this.stream.write("\r" + this.data);
- }
- showPrevCommand() {
- if (this.historyPosition > 0) {
- this.historyPosition--;
- this.showCommand(this.commandHistory[this.historyPosition]);
- }
- }
- showNextCommand() {
- if (this.historyPosition <= this.commandHistory.length - 1) {
- this.historyPosition++;
- this.showCommand(this.commandHistory[this.historyPosition] || this.tmp);
- } else {
- this.showCommand("");
- }
- }
- lookUp(start) {
- for (let i=start; i>-1; i--) {
- if (this.commandHistory[i].match(this.tmp)) {
- this.searchIndex = i - 1;
- this.showCommand(this.commandHistory[i]);
- return true;
- }
- }
- for (let i=this.commandHistory.length - 1; i>start; i--) {
- if (this.commandHistory[i].match(this.tmp)) {
- this.searchIndex = i - 1;
- this.showCommand(this.commandHistory[i]);
- return true;
- }
- }
- }
- search() {
- if (this.tmp === "") { return }
- if (this.tmp !== this.prevSearch) {
- this.searchIndex = this.commandHistory.length - 1;
- this.prevSearch = this.tmp
- }
- this.lookUp(this.searchIndex);
- }
- sliceCommand() {
- if (this.data.indexOf("\n") > -1){
- const cmd = this.data.split("\n")[0];
- this.data = this.data.slice(this.data.indexOf("\n") + 1);
- return cmd;
- }
- }
- }
- class EvalControl extends Control {
- processCommand(cmd) {
- super.processCommand();
- try {
- eval(cmd);
- } catch (e) {
- console.log(cmd);
- }
- }
- }
- module.exports = {Control, EvalControl}
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement