Advertisement
Guest User

Untitled

a guest
Sep 23rd, 2017
111
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. class Control {
  2.     constructor(stream, raw) {
  3.         this.data = "";
  4.         this.tmp = "";
  5.  
  6.         this.stream = stream;
  7.         this.raw = typeof raw !== 'undefined' ? raw : true
  8.         if (this.raw) {
  9.             this.stream.setRawMode(true);
  10.             this.stream.resume();
  11.             this.stream.setEncoding('utf8');
  12.         }
  13.         this.stream.on('data', data => this.inputHandler(data));
  14.  
  15.         this.cursorPosition = 0;
  16.         this.commandHistory = ['console.log("This is a test command in history")', 'console.log("search test")'];
  17.         this.historyPosition = this.commandHistory.length;
  18.         this.searchIndex = this.commandHistory.length - 1;
  19.         this.prevSearch = "";
  20.     }
  21.  
  22.     processCommand(cmd) {
  23.         if (cmd === "") { return }
  24.         if (cmd !== this.commandHistory[this.commandHistory.length-1]) {
  25.             this.commandHistory.push(cmd);
  26.         }
  27.         this.historyPosition = this.commandHistory.length;
  28.     }
  29.  
  30.     inputHandler(data) {
  31.         switch (data) {
  32.             case '\u0003':
  33.                 // ctrl-c
  34.                 process.exit();
  35.                 break;
  36.             case '\u0012':
  37.                 // ctrl-r
  38.                 this.search();
  39.                 break;
  40.             case '\u001B\u005B\u0041':
  41.                 // up arrow
  42.                 this.showPrevCommand();
  43.                 break;
  44.             case '\u001B\u005B\u0042':
  45.                 // down arrow
  46.                 this.showNextCommand();
  47.                 break;
  48.             case '\u001B\u005B\u0044':
  49.                 // left arrow
  50.                 this.moveCursor('left');
  51.                 break;
  52.             case '\u001B\u005B\u0043':
  53.                 // right arrow
  54.                 this.moveCursor('right');
  55.                 break;
  56.             case '\u001B\u0062':
  57.                 // alt + left arrow
  58.                 this.moveCursor('left', true);
  59.                 break;
  60.             case '\u001B\u0066':
  61.                 // alt + right arrow
  62.                 this.moveCursor('right', true);
  63.                 break;
  64.             case '\u000D':
  65.                 // enter key
  66.                 this.stream.write("\n");
  67.                 this.processCommand(this.data);
  68.                 this.clearInput();
  69.                 this.data = "";
  70.                 this.tmp = "";
  71.                 break;
  72.             case '\u007F':
  73.                 // backspace
  74.                 this.deleteCharacter();
  75.                 break;
  76.             case '\u0009':
  77.                 // tab
  78.                 break;
  79.             default:
  80.                 if (this.raw) {
  81.                     this.addCharacter(data);
  82.                 } else {
  83.                     this.data += data;
  84.                     let cmd;
  85.                     while (cmd = this.sliceCommand()){
  86.                         this.processCommand(cmd);
  87.                     }
  88.                 }
  89.         }
  90.     }
  91.  
  92.     clearInput() {
  93.         if (!this.raw) { return }
  94.         this.stream.write("\r" + Array(this.data.length).fill(" ").join("") + "\r");
  95.     }
  96.  
  97.     moveCursor(direction, toWord) {
  98.         if (direction === 'left') {
  99.             this.cursorPosition = Math.max(0, this.cursorPosition - 1);
  100.             if (toWord) {
  101.                 const idx = this.data.slice(0,this.cursorPosition).split("").reverse().join("").search(/\w[^\w]/);
  102.                 if (idx > -1) {
  103.                     this.cursorPosition = Math.max(0, this.cursorPosition - idx - 1);
  104.                 } else {
  105.                     this.cursorPosition = 0;
  106.                 }
  107.             }
  108.         } else if (direction === 'right') {
  109.             this.cursorPosition = Math.min(this.data.length, this.cursorPosition + 1);
  110.             if (toWord) {
  111.                 const idx = this.data.slice(this.cursorPosition).search(/[^\w]\w/);
  112.                 if (idx > -1) {
  113.                     this.cursorPosition = Math.min(this.data.length, this.cursorPosition + idx + 1);
  114.                 } else {
  115.                     this.cursorPosition = this.data.length;
  116.                 }
  117.             }
  118.         }
  119.         this.stream.write("\r" + this.data.slice(0, this.cursorPosition));
  120.     }
  121.  
  122.     updateLine(ifAtEnd) {
  123.         if (this.cursorPosition === this.data.length) {
  124.             this.stream.write(ifAtEnd);
  125.         } else {
  126.             this.stream.write("\r" + this.data);
  127.             this.stream.write("\r" + this.data.slice(0, this.cursorPosition));
  128.         }
  129.     }
  130.  
  131.     addCharacter(character) {
  132.         this.data = this.data.slice(0, this.cursorPosition) + character + this.data.slice(this.cursorPosition);
  133.         this.tmp = this.data;
  134.         this.cursorPosition++;
  135.         this.updateLine(character);
  136.     }
  137.  
  138.     deleteCharacter() {
  139.         this.clearInput();
  140.         this.data = this.data.slice(0, this.cursorPosition - 1) + this.data.slice(this.cursorPosition);
  141.         this.tmp = this.data;
  142.         this.cursorPosition = Math.max(0, this.cursorPosition - 1);
  143.         this.updateLine(this.data);
  144.     }
  145.  
  146.     showCommand(cmd) {
  147.         this.clearInput();
  148.         this.data = cmd;
  149.         this.cursorPosition = this.data.length;
  150.         this.stream.write("\r" + this.data);
  151.     }
  152.  
  153.     showPrevCommand() {
  154.         if (this.historyPosition > 0) {
  155.             this.historyPosition--;
  156.             this.showCommand(this.commandHistory[this.historyPosition]);
  157.         }
  158.     }
  159.  
  160.     showNextCommand() {
  161.         if (this.historyPosition <= this.commandHistory.length - 1) {
  162.             this.historyPosition++;
  163.             this.showCommand(this.commandHistory[this.historyPosition] || this.tmp);
  164.         } else {
  165.             this.showCommand("");
  166.         }
  167.     }
  168.  
  169.     lookUp(start) {
  170.         for (let i=start; i>-1; i--) {
  171.             if (this.commandHistory[i].match(this.tmp)) {
  172.                 this.searchIndex = i - 1;
  173.                 this.showCommand(this.commandHistory[i]);
  174.                 return true;
  175.             }
  176.         }
  177.        
  178.         for (let i=this.commandHistory.length - 1; i>start; i--) {
  179.             if (this.commandHistory[i].match(this.tmp)) {
  180.                 this.searchIndex = i - 1;
  181.                 this.showCommand(this.commandHistory[i]);
  182.                 return true;
  183.             }
  184.         }
  185.     }
  186.  
  187.     search() {
  188.         if (this.tmp === "") { return }
  189.  
  190.         if (this.tmp !== this.prevSearch) {
  191.             this.searchIndex = this.commandHistory.length - 1;
  192.             this.prevSearch = this.tmp
  193.         }
  194.         this.lookUp(this.searchIndex);
  195.     }
  196.  
  197.     sliceCommand() {
  198.         if (this.data.indexOf("\n") > -1){
  199.             const cmd = this.data.split("\n")[0];
  200.             this.data = this.data.slice(this.data.indexOf("\n") + 1);
  201.             return cmd;
  202.         }
  203.     }
  204. }
  205.  
  206. class EvalControl extends Control {
  207.     processCommand(cmd) {
  208.         super.processCommand();
  209.         try {
  210.             eval(cmd);
  211.         } catch (e) {
  212.             console.log(cmd);
  213.         }
  214.     }
  215. }
  216.  
  217. module.exports = {Control, EvalControl}
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement