mirror of
https://github.com/nuintun/command-manager.git
synced 2025-06-28 02:12:43 +08:00
update files
This commit is contained in:
parent
04b948a429
commit
d4a1eb387d
@ -156,7 +156,7 @@ body {
|
||||
body {
|
||||
border: 1px solid #ccc;
|
||||
box-sizing: border-box;
|
||||
min-width: 1024px; !important;
|
||||
min-width: 1024px !important;
|
||||
min-height: 768px !important;
|
||||
}
|
||||
a {
|
||||
|
467
static/js/terminal/xterm.js
Normal file
467
static/js/terminal/xterm.js
Normal file
@ -0,0 +1,467 @@
|
||||
/**
|
||||
* Created by nuintun on 2015/11/30.
|
||||
*/
|
||||
|
||||
'use strict';
|
||||
|
||||
/**
|
||||
* range function for numbers [a, .., b-1]
|
||||
*
|
||||
* @param {number} a
|
||||
* @param {number} b
|
||||
* @return {Array}
|
||||
*/
|
||||
function r(a, b){
|
||||
var c = b - a;
|
||||
var arr = new Array(c);
|
||||
|
||||
while (c--) {
|
||||
arr[c] = --b;
|
||||
}
|
||||
|
||||
return arr;
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a transition to the transition table.
|
||||
*
|
||||
* @param table - table to add transition
|
||||
* @param {number} inp - input character code
|
||||
* @param {number} state - current state
|
||||
* @param {number=} action - action to be taken
|
||||
* @param {number=} next - next state
|
||||
*/
|
||||
function add(table, inp, state, action, next){
|
||||
table[state << 8 | inp] = ((action | 0) << 4) | ((next === undefined) ? state : next);
|
||||
}
|
||||
|
||||
/**
|
||||
* Add multiple transitions to the transition table.
|
||||
*
|
||||
* @param table - table to add transition
|
||||
* @param {Array} inps - array of input character codes
|
||||
* @param {number} state - current state
|
||||
* @param {number=} action - action to be taken
|
||||
* @param {number=} next - next state
|
||||
*/
|
||||
function add_list(table, inps, state, action, next){
|
||||
for (var i = 0; i < inps.length; i++)
|
||||
add(table, inps[i], state, action, next);
|
||||
}
|
||||
|
||||
/** global definition of printables and executables */
|
||||
var PRINTABLES = r(0x20, 0x7f);
|
||||
var EXECUTABLES = r(0x00, 0x18);
|
||||
EXECUTABLES.push(0x19);
|
||||
EXECUTABLES.concat(r(0x1c, 0x20));
|
||||
|
||||
/**
|
||||
* create the standard transition table - used by all parser instances
|
||||
*
|
||||
* table[state << 8 | character code] = action << 4 | next state
|
||||
*
|
||||
* - states are numbers from 0 to 13
|
||||
* - control character codes defined from 0 to 159 (C0 and C1)
|
||||
* - actions are numbers from 0 to 14
|
||||
* - any higher character than 159 is handled by the 'error' action
|
||||
*
|
||||
* state replacements (14 states):
|
||||
* 'GROUND' -> 0
|
||||
* 'ESCAPE' -> 1
|
||||
* 'ESCAPE_INTERMEDIATE' -> 2
|
||||
* 'CSI_ENTRY' -> 3
|
||||
* 'CSI_PARAM' -> 4
|
||||
* 'CSI_INTERMEDIATE' -> 5
|
||||
* 'CSI_IGNORE' -> 6
|
||||
* 'SOS_PM_APC_STRING' -> 7
|
||||
* 'OSC_STRING' -> 8
|
||||
* 'DCS_ENTRY' -> 9
|
||||
* 'DCS_PARAM' -> 10
|
||||
* 'DCS_IGNORE' -> 11
|
||||
* 'DCS_INTERMEDIATE' -> 12
|
||||
* 'DCS_PASSTHROUGH' -> 13
|
||||
*
|
||||
* action replacements (15 actions):
|
||||
* 'no action' -> 0
|
||||
* 'error' -> 1
|
||||
* 'print' -> 2
|
||||
* 'execute' -> 3
|
||||
* 'osc_start' -> 4
|
||||
* 'osc_put' -> 5
|
||||
* 'osc_end' -> 6
|
||||
* 'csi_dispatch' -> 7
|
||||
* 'param' -> 8
|
||||
* 'collect' -> 9
|
||||
* 'esc_dispatch' -> 10
|
||||
* 'clear' -> 11
|
||||
* 'dcs_hook' -> 12
|
||||
* 'dcs_put' -> 13
|
||||
* 'dcs_unhook' -> 14
|
||||
*/
|
||||
var TRANSITION_TABLE = (function (){
|
||||
//var table = [];
|
||||
var table = new Uint8Array(4095);
|
||||
|
||||
// table with default transition [any] --> [error, GROUND]
|
||||
for (var state = 0; state < 14; ++state) {
|
||||
for (var code = 0; code < 160; ++code) {
|
||||
table[state << 8 | code] = 16;
|
||||
}
|
||||
}
|
||||
|
||||
// apply transitions
|
||||
// printables
|
||||
add_list(table, PRINTABLES, 0, 2);
|
||||
|
||||
// global anywhere rules
|
||||
for (state = 0; state < 14; ++state) {
|
||||
add_list(table, [0x18, 0x1a, 0x99, 0x9a], state, 3, 0);
|
||||
add_list(table, r(0x80, 0x90), state, 3, 0);
|
||||
add_list(table, r(0x90, 0x98), state, 3, 0);
|
||||
add(table, 0x9c, state, 0, 0); // ST as terminator
|
||||
add(table, 0x1b, state, 11, 1); // ESC
|
||||
add(table, 0x9d, state, 4, 8); // OSC
|
||||
add_list(table, [0x98, 0x9e, 0x9f], state, 0, 7);
|
||||
add(table, 0x9b, state, 11, 3); // CSI
|
||||
add(table, 0x90, state, 11, 9); // DCS
|
||||
}
|
||||
|
||||
// rules for executables and 7f
|
||||
add_list(table, EXECUTABLES, 0, 3);
|
||||
add_list(table, EXECUTABLES, 1, 3);
|
||||
add(table, 0x7f, 1);
|
||||
add_list(table, EXECUTABLES, 8);
|
||||
add_list(table, EXECUTABLES, 3, 3);
|
||||
add(table, 0x7f, 3);
|
||||
add_list(table, EXECUTABLES, 4, 3);
|
||||
add(table, 0x7f, 4);
|
||||
add_list(table, EXECUTABLES, 6, 3);
|
||||
add_list(table, EXECUTABLES, 5, 3);
|
||||
add(table, 0x7f, 5);
|
||||
add_list(table, EXECUTABLES, 2, 3);
|
||||
add(table, 0x7f, 2);
|
||||
// osc
|
||||
add(table, 0x5d, 1, 4, 8);
|
||||
add_list(table, PRINTABLES, 8, 5);
|
||||
add(table, 0x7f, 8, 5);
|
||||
add_list(table, [0x9c, 0x1b, 0x18, 0x1a, 0x07], 8, 6, 0);
|
||||
add_list(table, r(0x1c, 0x20), 8, 0);
|
||||
// sos/pm/apc does nothing
|
||||
add_list(table, [0x58, 0x5e, 0x5f], 1, 0, 7);
|
||||
add_list(table, PRINTABLES, 7);
|
||||
add_list(table, EXECUTABLES, 7);
|
||||
add(table, 0x9c, 7, 0, 0);
|
||||
// csi entries
|
||||
add(table, 0x5b, 1, 11, 3);
|
||||
add_list(table, r(0x40, 0x7f), 3, 7, 0);
|
||||
add_list(table, r(0x30, 0x3a), 3, 8, 4);
|
||||
add(table, 0x3b, 3, 8, 4);
|
||||
add_list(table, [0x3c, 0x3d, 0x3e, 0x3f], 3, 9, 4);
|
||||
add_list(table, r(0x30, 0x3a), 4, 8);
|
||||
add(table, 0x3b, 4, 8);
|
||||
add_list(table, r(0x40, 0x7f), 4, 7, 0);
|
||||
add_list(table, [0x3a, 0x3c, 0x3d, 0x3e, 0x3f], 4, 0, 6);
|
||||
add_list(table, r(0x20, 0x40), 6);
|
||||
add(table, 0x7f, 6);
|
||||
add_list(table, r(0x40, 0x7f), 6, 0, 0);
|
||||
add(table, 0x3a, 3, 0, 6);
|
||||
add_list(table, r(0x20, 0x30), 3, 9, 5);
|
||||
add_list(table, r(0x20, 0x30), 5, 9);
|
||||
add_list(table, r(0x30, 0x40), 5, 0, 6);
|
||||
add_list(table, r(0x40, 0x7f), 5, 7, 0);
|
||||
add_list(table, r(0x20, 0x30), 4, 9, 5);
|
||||
// esc_intermediate
|
||||
add_list(table, r(0x20, 0x30), 1, 9, 2);
|
||||
add_list(table, r(0x20, 0x30), 2, 9);
|
||||
add_list(table, r(0x30, 0x7f), 2, 10, 0);
|
||||
add_list(table, r(0x30, 0x50), 1, 10, 0);
|
||||
add_list(table, [0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, 0x59, 0x5a, 0x5c], 1, 10, 0);
|
||||
add_list(table, r(0x60, 0x7f), 1, 10, 0);
|
||||
// dcs entry
|
||||
add(table, 0x50, 1, 11, 9);
|
||||
add_list(table, EXECUTABLES, 9);
|
||||
add(table, 0x7f, 9);
|
||||
add_list(table, r(0x1c, 0x20), 9);
|
||||
add_list(table, r(0x20, 0x30), 9, 9, 12);
|
||||
add(table, 0x3a, 9, 0, 11);
|
||||
add_list(table, r(0x30, 0x3a), 9, 8, 10);
|
||||
add(table, 0x3b, 9, 8, 10);
|
||||
add_list(table, [0x3c, 0x3d, 0x3e, 0x3f], 9, 9, 10);
|
||||
add_list(table, EXECUTABLES, 11);
|
||||
add_list(table, r(0x20, 0x80), 11);
|
||||
add_list(table, r(0x1c, 0x20), 11);
|
||||
add_list(table, EXECUTABLES, 10);
|
||||
add(table, 0x7f, 10);
|
||||
add_list(table, r(0x1c, 0x20), 10);
|
||||
add_list(table, r(0x30, 0x3a), 10, 8);
|
||||
add(table, 0x3b, 10, 8);
|
||||
add_list(table, [0x3a, 0x3c, 0x3d, 0x3e, 0x3f], 10, 0, 11);
|
||||
add_list(table, r(0x20, 0x30), 10, 9, 12);
|
||||
add_list(table, EXECUTABLES, 12);
|
||||
add(table, 0x7f, 12);
|
||||
add_list(table, r(0x1c, 0x20), 12);
|
||||
add_list(table, r(0x20, 0x30), 12, 9);
|
||||
add_list(table, r(0x30, 0x40), 12, 0, 11);
|
||||
add_list(table, r(0x40, 0x7f), 12, 12, 13);
|
||||
add_list(table, r(0x40, 0x7f), 10, 12, 13);
|
||||
add_list(table, r(0x40, 0x7f), 9, 12, 13);
|
||||
add_list(table, EXECUTABLES, 13, 13);
|
||||
add_list(table, PRINTABLES, 13, 13);
|
||||
add(table, 0x7f, 13);
|
||||
add_list(table, [0x1b, 0x9c], 13, 14, 0);
|
||||
|
||||
return table;
|
||||
})();
|
||||
|
||||
/**
|
||||
* helper for param conversion
|
||||
* @param {string} params - params string with ;
|
||||
* @return {Array}
|
||||
*/
|
||||
function parse_params(params){
|
||||
// params are separated by ';'
|
||||
// empty defaults to 0
|
||||
var p = params.split(';');
|
||||
|
||||
for (var i = 0; i < p.length; ++i) {
|
||||
p[i] = Number(p[i]);
|
||||
}
|
||||
|
||||
return p;
|
||||
}
|
||||
|
||||
/**
|
||||
* AnsiParser - Parser for ANSI terminal escape sequences.
|
||||
*
|
||||
* @param {Object=} terminal
|
||||
* @constructor
|
||||
*/
|
||||
function AnsiParser(terminal){
|
||||
this.initial_state = 0; // 'GROUND' is default
|
||||
this.current_state = this.initial_state;
|
||||
|
||||
// global non pushable buffers for multiple parse invocations
|
||||
this.osc = '';
|
||||
this.params = '';
|
||||
this.collected = '';
|
||||
|
||||
// back reference to terminal
|
||||
this.term = terminal || {};
|
||||
var instructions = [
|
||||
'inst_p', 'inst_o', 'inst_x', 'inst_c',
|
||||
'inst_e', 'inst_H', 'inst_P', 'inst_U', 'inst_E'
|
||||
];
|
||||
|
||||
for (var i = 0; i < instructions.length; ++i) {
|
||||
if (!(instructions[i] in this.term)) {
|
||||
this.term[instructions[i]] = function (){};
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Reset the parser.
|
||||
*/
|
||||
AnsiParser.prototype.reset = function (){
|
||||
this.current_state = this.initial_state;
|
||||
this.osc = '';
|
||||
this.params = '';
|
||||
this.collected = '';
|
||||
};
|
||||
|
||||
/**
|
||||
* Parse string s.
|
||||
* @param {string} s
|
||||
*/
|
||||
AnsiParser.prototype.parse = function (s){
|
||||
var error = false;
|
||||
var c, code, transition;
|
||||
var current_state = this.current_state;
|
||||
|
||||
// local buffers
|
||||
var printed = '';
|
||||
var dcs = '';
|
||||
var osc = this.osc;
|
||||
var collected = this.collected;
|
||||
var params = this.params;
|
||||
|
||||
// process input string
|
||||
for (var i = 0; i < s.length; ++i) {
|
||||
c = s.charAt(i);
|
||||
code = c.charCodeAt(0);
|
||||
|
||||
if (code < 0xa0) {
|
||||
transition = TRANSITION_TABLE[current_state << 8 | code];
|
||||
} else {
|
||||
transition = 16;
|
||||
}
|
||||
|
||||
switch (transition >> 4) {
|
||||
case 0:
|
||||
// no action
|
||||
break;
|
||||
case 1:
|
||||
// error
|
||||
// NOTE: real error recovery is not implemented
|
||||
// handle unicode chars in write buffers w'o state change
|
||||
if (code > 0x9f) {
|
||||
switch (current_state) {
|
||||
case 0:
|
||||
// GROUND -> add char to print string
|
||||
printed += c;
|
||||
break;
|
||||
case 8:
|
||||
// OSC_STRING -> add char to osc string
|
||||
osc += c;
|
||||
transition |= 8;
|
||||
break;
|
||||
case 6:
|
||||
// CSI_IGNORE -> ignore char
|
||||
transition |= 6;
|
||||
break;
|
||||
case 11:
|
||||
// DCS_IGNORE -> ignore char
|
||||
transition |= 11;
|
||||
break;
|
||||
case 13:
|
||||
// DCS_PASSTHROUGH -> add char to dcs
|
||||
dcs += c;
|
||||
transition |= 13;
|
||||
break;
|
||||
default:
|
||||
error = true;
|
||||
}
|
||||
} else {
|
||||
error = true;
|
||||
}
|
||||
|
||||
if (error) {
|
||||
if (
|
||||
this.term.inst_E({
|
||||
pos: i, // position in parse string
|
||||
character: c, // wrong character
|
||||
state: current_state, // in state
|
||||
print: printed, // print buffer
|
||||
dcs: dcs, // dcs buffer
|
||||
osc: osc, // osc buffer
|
||||
collect: collected, // collect buffer
|
||||
params: params // params buffer
|
||||
})
|
||||
) {
|
||||
return;
|
||||
}
|
||||
error = false;
|
||||
}
|
||||
break;
|
||||
case 2:
|
||||
// print
|
||||
printed += c;
|
||||
break;
|
||||
case 3:
|
||||
// execute
|
||||
if (printed) {
|
||||
this.term.inst_p(printed);
|
||||
}
|
||||
|
||||
printed = '';
|
||||
|
||||
this.term.inst_x(c);
|
||||
break;
|
||||
case 7:
|
||||
// csi_dispatch
|
||||
this.term.inst_c(collected, parse_params(params), c);
|
||||
break;
|
||||
case 8:
|
||||
// param
|
||||
params += c;
|
||||
break;
|
||||
case 9:
|
||||
// collect
|
||||
collected += c;
|
||||
break;
|
||||
case 10:
|
||||
// esc_dispatch
|
||||
this.term.inst_e(collected, c);
|
||||
break;
|
||||
case 11:
|
||||
// clear
|
||||
if (printed) {
|
||||
this.term.inst_p(printed);
|
||||
}
|
||||
|
||||
printed = '';
|
||||
osc = '';
|
||||
params = '';
|
||||
collected = '';
|
||||
dcs = '';
|
||||
break;
|
||||
case 4:
|
||||
// osc_start
|
||||
if (printed) {
|
||||
this.term.inst_p(printed);
|
||||
}
|
||||
|
||||
printed = '';
|
||||
osc = '';
|
||||
break;
|
||||
case 5:
|
||||
// osc_put
|
||||
osc += c;
|
||||
break;
|
||||
case 6:
|
||||
// osc_end
|
||||
if (osc && code !== 0x18 && code !== 0x1a) {
|
||||
this.term.inst_o(osc);
|
||||
}
|
||||
|
||||
if (code === 0x1b) {
|
||||
transition |= 1;
|
||||
}
|
||||
|
||||
osc = '';
|
||||
params = '';
|
||||
collected = '';
|
||||
dcs = '';
|
||||
break;
|
||||
case 12: // dcs_hook
|
||||
this.term.inst_H(collected, parse_params(params), c);
|
||||
break;
|
||||
case 13: // dcs_put
|
||||
dcs += c;
|
||||
break;
|
||||
case 14: // dcs_unhook
|
||||
if (dcs) {
|
||||
this.term.inst_P(dcs);
|
||||
}
|
||||
|
||||
this.term.inst_U();
|
||||
|
||||
if (code === 0x1b) {
|
||||
transition |= 1;
|
||||
}
|
||||
|
||||
osc = '';
|
||||
params = '';
|
||||
collected = '';
|
||||
dcs = '';
|
||||
break;
|
||||
}
|
||||
|
||||
current_state = transition & 15;
|
||||
}
|
||||
|
||||
// push leftover pushable buffers to terminal
|
||||
if (!current_state && printed) {
|
||||
this.term.inst_p(printed);
|
||||
} else if (current_state === 13 && dcs) {
|
||||
this.term.inst_P(dcs);
|
||||
}
|
||||
|
||||
// save non pushable buffers
|
||||
this.osc = osc;
|
||||
this.collected = collected;
|
||||
this.params = params;
|
||||
|
||||
// save state
|
||||
this.current_state = current_state;
|
||||
};
|
Loading…
x
Reference in New Issue
Block a user