@unblessed/core
Version:
Platform-agnostic terminal UI core library with runtime dependency injection
1,630 lines (1,621 loc) • 563 kB
JavaScript
'use strict';
// ../../node_modules/.pnpm/tsup@8.5.0_@swc+core@1.14.0_jiti@2.6.1_postcss@8.5.6_tsx@4.20.6_typescript@5.9.3_yaml@2.8.1/node_modules/tsup/assets/cjs_shims.js
var getImportMetaUrl = () => typeof document === "undefined" ? new URL(`file:${__filename}`).href : document.currentScript && document.currentScript.src || new URL("main.js", document.baseURI).href;
var importMetaUrl = /* @__PURE__ */ getImportMetaUrl();
// src/runtime.ts
function hasImageSupport(runtime2) {
return runtime2.images !== void 0;
}
function hasProcessSupport(runtime2) {
return runtime2.processes !== void 0;
}
function hasNetworkSupport(runtime2) {
return runtime2.networking !== void 0;
}
// src/runtime-context.ts
var runtime = null;
function setRuntime(rt) {
runtime = rt;
}
function getRuntime() {
if (!runtime) {
throw new Error(
"Runtime not initialized. Call initNode() from @unblessed/node or initBrowser() from @unblessed/browser first.\n\nExample:\n import { initNode, Screen } from '@unblessed/node';\n initNode();\n const screen = new Screen();"
);
}
return runtime;
}
// src/lib/colors.ts
var colors = {};
colors.match = function(r1, g1, b1) {
if (typeof r1 === "string") {
const hex = r1;
if (hex[0] !== "#") {
return -1;
}
const rgb = colors.hexToRGB(hex);
r1 = rgb[0];
g1 = rgb[1];
b1 = rgb[2];
} else if (Array.isArray(r1)) {
b1 = r1[2];
g1 = r1[1];
r1 = r1[0];
}
const hash = r1 << 16 | g1 << 8 | b1;
if (colors._cache[hash] != null) {
return colors._cache[hash];
}
let ldiff = Infinity;
let li = -1;
let i = 0;
let c;
let r2;
let g2;
let b2;
let diff;
for (; i < colors.vcolors.length; i++) {
c = colors.vcolors[i];
r2 = c[0];
g2 = c[1];
b2 = c[2];
diff = colorDistance(r1, g1, b1, r2, g2, b2);
if (diff === 0) {
li = i;
break;
}
if (diff < ldiff) {
ldiff = diff;
li = i;
}
}
return colors._cache[hash] = li;
};
colors.RGBToHex = function(r, g, b) {
if (Array.isArray(r)) {
b = r[2];
g = r[1];
r = r[0];
}
function hex(n) {
let result = n.toString(16);
if (result.length < 2) result = "0" + result;
return result;
}
return "#" + hex(r) + hex(g) + hex(b);
};
colors.hexToRGB = function(hex) {
if (hex.length === 4) {
hex = hex[0] + hex[1] + hex[1] + hex[2] + hex[2] + hex[3] + hex[3];
}
const col = parseInt(hex.substring(1), 16);
const r = col >> 16 & 255;
const g = col >> 8 & 255;
const b = col & 255;
return [r, g, b];
};
function colorDistance(r1, g1, b1, r2, g2, b2) {
return Math.pow(30 * (r1 - r2), 2) + Math.pow(59 * (g1 - g2), 2) + Math.pow(11 * (b1 - b2), 2);
}
colors.mixColors = function(c1, c2, alpha) {
if (c1 === 511) c1 = 0;
if (c2 === 511) c2 = 0;
if (alpha == null) alpha = 0.5;
const color1 = colors.vcolors[c1];
let r1 = color1[0];
let g1 = color1[1];
let b1 = color1[2];
const color2 = colors.vcolors[c2];
const r2 = color2[0];
const g2 = color2[1];
const b2 = color2[2];
r1 += (r2 - r1) * alpha | 0;
g1 += (g2 - g1) * alpha | 0;
b1 += (b2 - b1) * alpha | 0;
return colors.match([r1, g1, b1]);
};
colors.blend = function blend(attr, attr2, alpha) {
if (!blend._cache) blend._cache = {};
const cache = blend._cache;
let name;
let i;
let c;
let nc;
let bg = attr & 511;
if (attr2 != null) {
let bg2 = attr2 & 511;
if (bg === 511) bg = 0;
if (bg2 === 511) bg2 = 0;
bg = colors.mixColors(bg, bg2, alpha);
} else {
if (cache[bg] != null) {
bg = cache[bg];
} else if (bg >= 8 && bg <= 15) {
bg -= 8;
} else {
name = colors.ncolors[bg];
if (name) {
for (i = 0; i < colors.ncolors.length; i++) {
if (name === colors.ncolors[i] && i !== bg) {
c = colors.vcolors[bg];
nc = colors.vcolors[i];
if (nc[0] + nc[1] + nc[2] < c[0] + c[1] + c[2]) {
cache[bg] = i;
bg = i;
break;
}
}
}
}
}
}
attr &= -512;
attr |= bg;
let fg = attr >> 9 & 511;
if (attr2 != null) {
let fg2 = attr2 >> 9 & 511;
if (fg === 511) {
fg = 248;
} else {
if (fg === 511) fg = 7;
if (fg2 === 511) fg2 = 7;
fg = colors.mixColors(fg, fg2, alpha);
}
} else {
if (cache[fg] != null) {
fg = cache[fg];
} else if (fg >= 8 && fg <= 15) {
fg -= 8;
} else {
name = colors.ncolors[fg];
if (name) {
for (i = 0; i < colors.ncolors.length; i++) {
if (name === colors.ncolors[i] && i !== fg) {
c = colors.vcolors[fg];
nc = colors.vcolors[i];
if (nc[0] + nc[1] + nc[2] < c[0] + c[1] + c[2]) {
cache[fg] = i;
fg = i;
break;
}
}
}
}
}
}
attr &= -261633;
attr |= fg << 9;
return attr;
};
colors._cache = {};
colors.reduce = function(color, total) {
if (color >= 16 && total <= 16) {
color = colors.ccolors[color];
} else if (color >= 8 && total <= 8) {
color -= 8;
} else if (color >= 2 && total <= 2) {
color %= 2;
}
return color;
};
colors.xterm = [
"#000000",
// black
"#cd0000",
// red3
"#00cd00",
// green3
"#cdcd00",
// yellow3
"#0000ee",
// blue2
"#cd00cd",
// magenta3
"#00cdcd",
// cyan3
"#e5e5e5",
// gray90
"#7f7f7f",
// gray50
"#ff0000",
// red
"#00ff00",
// green
"#ffff00",
// yellow
"#5c5cff",
// rgb:5c/5c/ff
"#ff00ff",
// magenta
"#00ffff",
// cyan
"#ffffff"
// white
];
colors.colors = (function() {
const cols = colors.colors = [];
const _cols = colors.vcolors = [];
let r;
let g;
let b;
let i;
let l;
function hex(n) {
let result = n.toString(16);
if (result.length < 2) result = "0" + result;
return result;
}
function push(i2, r2, g2, b2) {
cols[i2] = "#" + hex(r2) + hex(g2) + hex(b2);
_cols[i2] = [r2, g2, b2];
}
colors.xterm.forEach(function(c, i2) {
const colorValue = parseInt(c.substring(1), 16);
push(
i2,
colorValue >> 16 & 255,
colorValue >> 8 & 255,
colorValue & 255
);
});
for (r = 0; r < 6; r++) {
for (g = 0; g < 6; g++) {
for (b = 0; b < 6; b++) {
i = 16 + r * 36 + g * 6 + b;
push(i, r ? r * 40 + 55 : 0, g ? g * 40 + 55 : 0, b ? b * 40 + 55 : 0);
}
}
}
for (g = 0; g < 24; g++) {
l = g * 10 + 8;
i = 232 + g;
push(i, l, l, l);
}
return cols;
})();
colors.ccolors = (function() {
const _cols = colors.vcolors.slice();
const cols = colors.colors.slice();
let out;
colors.vcolors = colors.vcolors.slice(0, 8);
colors.colors = colors.colors.slice(0, 8);
out = cols.map(colors.match);
colors.colors = cols;
colors.vcolors = _cols;
colors.ccolors = out;
return out;
})();
var colorNames = colors.colorNames = {
// special
default: -1,
normal: -1,
bg: -1,
fg: -1,
// normal
black: 0,
red: 1,
green: 2,
yellow: 3,
blue: 4,
magenta: 5,
cyan: 6,
white: 7,
// light
lightblack: 8,
lightred: 9,
lightgreen: 10,
lightyellow: 11,
lightblue: 12,
lightmagenta: 13,
lightcyan: 14,
lightwhite: 15,
// bright
brightblack: 8,
brightred: 9,
brightgreen: 10,
brightyellow: 11,
brightblue: 12,
brightmagenta: 13,
brightcyan: 14,
brightwhite: 15,
// alternate spellings
grey: 8,
gray: 8,
lightgrey: 7,
lightgray: 7,
brightgrey: 7,
brightgray: 7
};
colors.convert = function(color) {
if (typeof color === "number") ; else if (typeof color === "string") {
color = color.replace(/[\- ]/g, "");
if (colorNames[color] != null) {
color = colorNames[color];
} else {
color = colors.match(color);
}
} else if (Array.isArray(color)) {
color = colors.match(color);
} else {
color = -1;
}
return color !== -1 ? color : 511;
};
colors.ccolors = {
blue: [
4,
12,
[17, 21],
[24, 27],
[31, 33],
[38, 39],
45,
[54, 57],
[60, 63],
[67, 69],
[74, 75],
81,
[91, 93],
[97, 99],
[103, 105],
[110, 111],
117,
[128, 129],
[134, 135],
[140, 141],
[146, 147],
153,
165,
171,
177,
183,
189
],
green: [
2,
10,
22,
[28, 29],
[34, 36],
[40, 43],
[46, 50],
[64, 65],
[70, 72],
[76, 79],
[82, 86],
[106, 108],
[112, 115],
[118, 122],
[148, 151],
[154, 158],
[190, 194]
],
cyan: [
6,
14,
23,
30,
37,
44,
51,
66,
73,
80,
87,
109,
116,
123,
152,
159,
195
],
red: [
1,
9,
52,
[88, 89],
[94, 95],
[124, 126],
[130, 132],
[136, 138],
[160, 163],
[166, 169],
[172, 175],
[178, 181],
[196, 200],
[202, 206],
[208, 212],
[214, 218],
[220, 224]
],
magenta: [
5,
13,
53,
90,
96,
127,
133,
139,
164,
170,
176,
182,
201,
207,
213,
219,
225
],
yellow: [3, 11, 58, [100, 101], [142, 144], [184, 187], [226, 230]],
black: [0, 8, 16, 59, 102, [232, 243]],
white: [7, 15, 145, 188, 231, [244, 255]]
};
colors.ncolors = [];
Object.keys(colors.ccolors).forEach(function(name) {
colors.ccolors[name].forEach(function(offset) {
if (typeof offset === "number") {
colors.ncolors[offset] = name;
colors.ccolors[offset] = colors.colorNames[name];
return;
}
for (let i = offset[0], l = offset[1]; i <= l; i++) {
colors.ncolors[i] = name;
colors.ccolors[i] = colors.colorNames[name];
}
});
delete colors.ccolors[name];
});
var colors_default = colors;
// src/lib/runtime-helpers.ts
var envCache = /* @__PURE__ */ new Map();
function getEnvVar(varName) {
if (envCache.has(varName)) {
return envCache.get(varName);
}
const value = getRuntime().process.env[varName] || "";
envCache.set(varName, value);
return value;
}
var nextTick = null;
function getNextTick() {
if (!nextTick) {
nextTick = (callback) => getRuntime().process.nextTick(callback);
}
return nextTick;
}
var __dirname$1 = null;
function getDir() {
if (!__dirname$1) {
const rt = getRuntime();
__dirname$1 = rt.path.dirname(rt.url.fileURLToPath(importMetaUrl));
}
return __dirname$1;
}
var __dataPath = null;
function getDataPath() {
if (!__dataPath) {
const rt = getRuntime();
const dir = getDir();
__dataPath = rt.path.resolve(rt.path.join(dir, "data"));
}
return __dataPath;
}
// src/lib/event-emitter-base.ts
var EventEmitterBase = class {
constructor() {
const runtime2 = getRuntime();
const EventEmitter2 = runtime2.events.EventEmitter;
this._emitter = new EventEmitter2();
}
on(event, listener) {
this._emitter.on(event, listener);
return this;
}
addListener(event, listener) {
this._emitter.addListener(event, listener);
return this;
}
once(event, listener) {
this._emitter.once(event, listener);
return this;
}
emit(event, ...args) {
return this._emitter.emit(event, ...args);
}
removeListener(event, listener) {
this._emitter.removeListener(event, listener);
return this;
}
off(event, listener) {
this._emitter.off(event, listener);
return this;
}
removeAllListeners(event) {
this._emitter.removeAllListeners(event);
return this;
}
listeners(event) {
return this._emitter.listeners(event);
}
listenerCount(event) {
return this._emitter.listenerCount(event);
}
eventNames() {
return this._emitter.eventNames();
}
setMaxListeners(n) {
this._emitter.setMaxListeners(n);
return this;
}
getMaxListeners() {
return this._emitter.getMaxListeners();
}
prependListener(event, listener) {
this._emitter.prependListener(event, listener);
return this;
}
prependOnceListener(event, listener) {
this._emitter.prependOnceListener(event, listener);
return this;
}
rawListeners(event) {
return this._emitter.rawListeners(event);
}
};
// src/lib/events.ts
var EventEmitter = class {
constructor() {
if (!this._events) this._events = {};
}
setMaxListeners(n) {
this._maxListeners = n;
}
addListener(type, listener) {
if (!this._events[type]) {
this._events[type] = listener;
} else if (typeof this._events[type] === "function") {
this._events[type] = [this._events[type], listener];
} else {
this._events[type].push(listener);
}
this._emit("newListener", [type, listener]);
}
on(type, listener) {
return this.addListener(type, listener);
}
removeListener(type, listener) {
const handler = this._events[type];
if (!handler) return;
if (typeof handler === "function" || handler.length === 1) {
delete this._events[type];
this._emit("removeListener", [type, listener]);
return;
}
for (let i = 0; i < handler.length; i++) {
if (handler[i] === listener || handler[i].listener === listener) {
handler.splice(i, 1);
this._emit("removeListener", [type, listener]);
return;
}
}
}
off(type, listener) {
return this.removeListener(type, listener);
}
removeAllListeners(type) {
if (type) {
delete this._events[type];
} else {
this._events = {};
}
}
once(type, listener) {
const self = this;
function on(...args) {
self.removeListener(type, on);
return listener.apply(this, args);
}
on.listener = listener;
return this.on(type, on);
}
listeners(type) {
return typeof this._events[type] === "function" ? [this._events[type]] : this._events[type] || [];
}
_emit(type, args) {
const handler = this._events[type];
let ret;
if (!handler) {
if (type === "error") {
throw new args[0]();
}
return;
}
if (typeof handler === "function") {
return handler.apply(this, args);
}
for (let i = 0; i < handler.length; i++) {
if (handler[i].apply(this, args) === false) {
ret = false;
}
}
return ret !== false;
}
emit(type, ...rest) {
const args = rest;
const params = [type, ...rest];
let el = this;
this._emit("event", params);
if (this.type === "screen") {
return this._emit(type, args);
}
if (this._emit(type, args) === false) {
return false;
}
type = "element " + type;
args.unshift(this);
do {
if (!el._events[type]) continue;
if (el._emit(type, args) === false) {
return false;
}
} while (el = el.parent);
return true;
}
};
var GPM_MOVE = 1;
var GPM_DRAG = 2;
var GPM_DOWN = 4;
var GPM_UP = 8;
var GPM_DOUBLE = 32;
var GPM_MFLAG = 128;
var GPM_REQ_NOPASTE = 3;
var GPM_HARD = 256;
var GPM_SOCKET = "/dev/gpmctl";
function send_config(socket, Gpm_Connect, callback) {
const runtime2 = getRuntime();
const Buffer = runtime2.buffer.Buffer;
let buffer;
{
buffer = Buffer.alloc(16);
buffer.writeUInt16LE(Gpm_Connect.eventMask, 0);
buffer.writeUInt16LE(Gpm_Connect.defaultMask, 2);
buffer.writeUInt16LE(Gpm_Connect.minMod, 4);
buffer.writeUInt16LE(Gpm_Connect.maxMod, 6);
buffer.writeInt16LE(Gpm_Connect.pid, 8);
buffer.writeInt16LE(Gpm_Connect.vc, 12);
}
socket.write(buffer, () => {
if (callback) callback();
});
}
function parseEvent(raw) {
const evnt = {};
evnt.buttons = raw[0];
evnt.modifiers = raw[1];
evnt.vc = raw.readUInt16LE(2);
evnt.dx = raw.readInt16LE(4);
evnt.dy = raw.readInt16LE(6);
evnt.x = raw.readInt16LE(8);
evnt.y = raw.readInt16LE(10);
evnt.type = raw.readInt16LE(12);
evnt.clicks = raw.readInt32LE(16);
evnt.margin = raw.readInt32LE(20);
evnt.wdx = raw.readInt16LE(24);
evnt.wdy = raw.readInt16LE(26);
return evnt;
}
var GpmClient = class extends EventEmitter {
constructor(_options = {}) {
super();
const runtime2 = getRuntime();
const pid = process.pid;
let path;
try {
path = runtime2.fs.readlinkSync("/proc/" + pid + "/fd/0");
} catch (e) {
}
let tty = /tty[0-9]+$/.exec(path || "");
let vc;
if (tty) {
const ttyName = tty[0];
const match = /[0-9]+$/.exec(ttyName);
if (match) {
vc = +match[0];
}
}
if (tty) {
runtime2.fs.stat(GPM_SOCKET, (err, stat) => {
if (err || !stat.isSocket()) {
return;
}
const conf = {
eventMask: 65535,
defaultMask: GPM_MOVE | GPM_HARD,
minMod: 0,
maxMod: 65535,
pid,
vc
};
const gpm = runtime2.networking.net.createConnection(GPM_SOCKET);
this.gpm = gpm;
gpm.on("connect", () => {
send_config(gpm, conf, () => {
conf.pid = 0;
conf.vc = GPM_REQ_NOPASTE;
});
});
gpm.on("data", (packet) => {
const evnt = parseEvent(packet);
switch (evnt.type & 15) {
case GPM_MOVE:
if (evnt.dx || evnt.dy) {
this.emit("move", evnt.buttons, evnt.modifiers, evnt.x, evnt.y);
}
if (evnt.wdx || evnt.wdy) {
this.emit(
"mousewheel",
evnt.buttons,
evnt.modifiers,
evnt.x,
evnt.y,
evnt.wdx,
evnt.wdy
);
}
break;
case GPM_DRAG:
if (evnt.dx || evnt.dy) {
this.emit("drag", evnt.buttons, evnt.modifiers, evnt.x, evnt.y);
}
if (evnt.wdx || evnt.wdy) {
this.emit(
"mousewheel",
evnt.buttons,
evnt.modifiers,
evnt.x,
evnt.y,
evnt.wdx,
evnt.wdy
);
}
break;
case GPM_DOWN:
this.emit(
"btndown",
evnt.buttons,
evnt.modifiers,
evnt.x,
evnt.y
);
if (evnt.type & GPM_DOUBLE) {
this.emit(
"dblclick",
evnt.buttons,
evnt.modifiers,
evnt.x,
evnt.y
);
}
break;
case GPM_UP:
this.emit("btnup", evnt.buttons, evnt.modifiers, evnt.x, evnt.y);
if (!(evnt.type & GPM_MFLAG)) {
this.emit(
"click",
evnt.buttons,
evnt.modifiers,
evnt.x,
evnt.y
);
}
break;
}
});
gpm.on("error", () => {
this.stop();
});
});
}
}
stop() {
if (this.gpm) {
this.gpm.end();
}
delete this.gpm;
}
ButtonName(btn) {
if (btn & 4) return "left";
if (btn & 2) return "middle";
if (btn & 1) return "right";
return "";
}
hasShiftKey(mod) {
return !!(mod & 1);
}
hasCtrlKey(mod) {
return !!(mod & 4);
}
hasMetaKey(mod) {
return !!(mod & 8);
}
};
var gpmclient_default = GpmClient;
// src/lib/keys.ts
function listenerCount(stream, event) {
return typeof stream.listenerCount === "function" ? stream.listenerCount(event) : stream.listeners(event).length;
}
function emitKeypressEvents(stream) {
if (stream._keypressDecoder) return;
const runtime2 = getRuntime();
stream._keypressDecoder = new runtime2.stringDecoder.StringDecoder("utf8");
function onData(b) {
if (listenerCount(stream, "keypress") > 0) {
const r = stream._keypressDecoder.write(b);
if (r) emitKeys(stream, r);
} else {
stream.removeListener("data", onData);
stream.on("newListener", onNewListener);
}
}
function onNewListener(event) {
if (event === "keypress") {
stream.on("data", onData);
stream.removeListener("newListener", onNewListener);
}
}
if (listenerCount(stream, "keypress") > 0) {
stream.on("data", onData);
} else {
stream.on("newListener", onNewListener);
}
}
var metaKeyCodeReAnywhere = /(?:\x1b)([a-zA-Z0-9])/;
var metaKeyCodeRe = new RegExp("^" + metaKeyCodeReAnywhere.source + "$");
var functionKeyCodeReAnywhere = new RegExp(
"(?:\x1B+)(O|N|\\[|\\[\\[)(?:" + [
"(\\d+)(?:;(\\d+))?([~^$])",
"(?:M([@ #!a`])(.)(.))",
// mouse
"(?:1;)?(\\d+)?([a-zA-Z])"
].join("|") + ")"
);
var functionKeyCodeRe = new RegExp("^" + functionKeyCodeReAnywhere.source);
var escapeCodeReAnywhere = new RegExp(
[
functionKeyCodeReAnywhere.source,
metaKeyCodeReAnywhere.source,
/\x1b./.source
].join("|")
);
function emitKeys(stream, s) {
const runtime2 = getRuntime();
const Buffer = runtime2.buffer.Buffer;
if (Buffer.isBuffer(s)) {
if (s[0] > 127 && s[1] === void 0) {
s[0] -= 128;
s = "\x1B" + s.toString(stream.encoding || "utf-8");
} else {
s = s.toString(stream.encoding || "utf-8");
}
}
if (isMouse(s)) return;
let buffer = [];
let match;
while (match = escapeCodeReAnywhere.exec(s)) {
buffer = buffer.concat(s.slice(0, match.index).split(""));
buffer.push(match[0]);
s = s.slice(match.index + match[0].length);
}
buffer = buffer.concat(s.split(""));
buffer.forEach(function(s2) {
let ch;
let key = {
sequence: s2,
name: void 0,
ctrl: false,
meta: false,
shift: false
};
let parts;
if (s2 === "\r") {
key.name = "return";
} else if (s2 === "\n") {
key.name = "enter";
} else if (s2 === " ") {
key.name = "tab";
} else if (s2 === "\b" || s2 === "\x7F" || s2 === "\x1B\x7F" || s2 === "\x1B\b") {
key.name = "backspace";
key.meta = s2.charAt(0) === "\x1B";
} else if (s2 === "\x1B" || s2 === "\x1B\x1B") {
key.name = "escape";
key.meta = s2.length === 2;
} else if (s2 === " " || s2 === "\x1B ") {
key.name = "space";
key.meta = s2.length === 2;
} else if (s2.length === 1 && s2 <= "") {
key.name = String.fromCharCode(s2.charCodeAt(0) + "a".charCodeAt(0) - 1);
key.ctrl = true;
} else if (s2.length === 1 && s2 >= "a" && s2 <= "z") {
key.name = s2;
} else if (s2.length === 1 && s2 >= "A" && s2 <= "Z") {
key.name = s2.toLowerCase();
key.shift = true;
} else if (parts = metaKeyCodeRe.exec(s2)) {
key.name = parts[1].toLowerCase();
key.meta = true;
key.shift = /^[A-Z]$/.test(parts[1]);
} else if (parts = functionKeyCodeRe.exec(s2)) {
const code = (parts[1] || "") + (parts[2] || "") + (parts[4] || "") + (parts[9] || "");
const modifier = (Number(parts[3]) || Number(parts[8]) || 1) - 1;
key.ctrl = !!(modifier & 4);
key.meta = !!(modifier & 10);
key.shift = !!(modifier & 1);
key.code = code;
switch (code) {
/* xterm/gnome ESC O letter */
case "OP":
key.name = "f1";
break;
case "OQ":
key.name = "f2";
break;
case "OR":
key.name = "f3";
break;
case "OS":
key.name = "f4";
break;
/* xterm/rxvt ESC [ number ~ */
case "[11~":
key.name = "f1";
break;
case "[12~":
key.name = "f2";
break;
case "[13~":
key.name = "f3";
break;
case "[14~":
key.name = "f4";
break;
/* from Cygwin and used in libuv */
case "[[A":
key.name = "f1";
break;
case "[[B":
key.name = "f2";
break;
case "[[C":
key.name = "f3";
break;
case "[[D":
key.name = "f4";
break;
case "[[E":
key.name = "f5";
break;
/* common */
case "[15~":
key.name = "f5";
break;
case "[17~":
key.name = "f6";
break;
case "[18~":
key.name = "f7";
break;
case "[19~":
key.name = "f8";
break;
case "[20~":
key.name = "f9";
break;
case "[21~":
key.name = "f10";
break;
case "[23~":
key.name = "f11";
break;
case "[24~":
key.name = "f12";
break;
/* xterm ESC [ letter */
case "[A":
key.name = "up";
break;
case "[B":
key.name = "down";
break;
case "[C":
key.name = "right";
break;
case "[D":
key.name = "left";
break;
case "[E":
key.name = "clear";
break;
case "[F":
key.name = "end";
break;
case "[H":
key.name = "home";
break;
/* xterm/gnome ESC O letter */
case "OA":
key.name = "up";
break;
case "OB":
key.name = "down";
break;
case "OC":
key.name = "right";
break;
case "OD":
key.name = "left";
break;
case "OE":
key.name = "clear";
break;
case "OF":
key.name = "end";
break;
case "OH":
key.name = "home";
break;
/* xterm/rxvt ESC [ number ~ */
case "[1~":
key.name = "home";
break;
case "[2~":
key.name = "insert";
break;
case "[3~":
key.name = "delete";
break;
case "[4~":
key.name = "end";
break;
case "[5~":
key.name = "pageup";
break;
case "[6~":
key.name = "pagedown";
break;
/* putty */
case "[[5~":
key.name = "pageup";
break;
case "[[6~":
key.name = "pagedown";
break;
/* rxvt */
case "[7~":
key.name = "home";
break;
case "[8~":
key.name = "end";
break;
/* rxvt keys with modifiers */
case "[a":
key.name = "up";
key.shift = true;
break;
case "[b":
key.name = "down";
key.shift = true;
break;
case "[c":
key.name = "right";
key.shift = true;
break;
case "[d":
key.name = "left";
key.shift = true;
break;
case "[e":
key.name = "clear";
key.shift = true;
break;
case "[2$":
key.name = "insert";
key.shift = true;
break;
case "[3$":
key.name = "delete";
key.shift = true;
break;
case "[5$":
key.name = "pageup";
key.shift = true;
break;
case "[6$":
key.name = "pagedown";
key.shift = true;
break;
case "[7$":
key.name = "home";
key.shift = true;
break;
case "[8$":
key.name = "end";
key.shift = true;
break;
case "Oa":
key.name = "up";
key.ctrl = true;
break;
case "Ob":
key.name = "down";
key.ctrl = true;
break;
case "Oc":
key.name = "right";
key.ctrl = true;
break;
case "Od":
key.name = "left";
key.ctrl = true;
break;
case "Oe":
key.name = "clear";
key.ctrl = true;
break;
case "[2^":
key.name = "insert";
key.ctrl = true;
break;
case "[3^":
key.name = "delete";
key.ctrl = true;
break;
case "[5^":
key.name = "pageup";
key.ctrl = true;
break;
case "[6^":
key.name = "pagedown";
key.ctrl = true;
break;
case "[7^":
key.name = "home";
key.ctrl = true;
break;
case "[8^":
key.name = "end";
key.ctrl = true;
break;
/* misc. */
case "[Z":
key.name = "tab";
key.shift = true;
break;
default:
key.name = "undefined";
break;
}
}
if (key.name === void 0) {
key = void 0;
}
if (s2.length === 1) {
ch = s2;
}
if (key || ch) {
stream.emit("keypress", ch, key);
}
});
}
function isMouse(s) {
return /\x1b\[M/.test(s) || /\x1b\[M([\x00\u0020-\uffff]{3})/.test(s) || /\x1b\[(\d+;\d+;\d+)M/.test(s) || /\x1b\[<(\d+;\d+;\d+)([mM])/.test(s) || /\x1b\[<(\d+;\d+;\d+;\d+)&w/.test(s) || /\x1b\[24([0135])~\[(\d+),(\d+)\]\r/.test(s) || /\x1b\[(O|I)/.test(s);
}
// src/lib/alias.ts
var alias = {};
alias.bools = {
// Variable Cap- TCap Description
// Booleans name Code
"auto_left_margin": ["bw", "bw"],
// cub1 wraps from col‐ umn 0 to last column
"auto_right_margin": ["am", "am"],
// terminal has auto‐ matic margins
"back_color_erase": ["bce", "ut"],
// screen erased with background color
"can_change": ["ccc", "cc"],
// terminal can re- define existing col‐ ors
"ceol_standout_glitch": ["xhp", "xs"],
// standout not erased by overwriting (hp)
"col_addr_glitch": ["xhpa", "YA"],
// only positive motion for hpa/mhpa caps
"cpi_changes_res": ["cpix", "YF"],
// changing character pitch changes reso‐ lution
"cr_cancels_micro_mode": ["crxm", "YB"],
// using cr turns off micro mode
"dest_tabs_magic_smso": ["xt", "xt"],
// tabs destructive, magic so char (t1061)
"eat_newline_glitch": ["xenl", "xn"],
// newline ignored after 80 cols (con‐ cept)
"erase_overstrike": ["eo", "eo"],
// can erase over‐ strikes with a blank
"generic_type": ["gn", "gn"],
// generic line type
"hard_copy": ["hc", "hc"],
// hardcopy terminal
"hard_cursor": ["chts", "HC"],
// cursor is hard to see
"has_meta_key": ["km", "km"],
// Has a meta key (i.e., sets 8th-bit)
"has_print_wheel": ["daisy", "YC"],
// printer needs opera‐ tor to change char‐ acter set
"has_status_line": ["hs", "hs"],
// has extra status line
"hue_lightness_saturation": ["hls", "hl"],
// terminal uses only HLS color notation (Tektronix)
"insert_null_glitch": ["in", "in"],
// insert mode distin‐ guishes nulls
"lpi_changes_res": ["lpix", "YG"],
// changing line pitch changes resolution
"memory_above": ["da", "da"],
// display may be retained above the screen
"memory_below": ["db", "db"],
// display may be retained below the screen
"move_insert_mode": ["mir", "mi"],
// safe to move while in insert mode
"move_standout_mode": ["msgr", "ms"],
// safe to move while in standout mode
"needs_xon_xoff": ["nxon", "nx"],
// padding will not work, xon/xoff required
"no_esc_ctlc": ["xsb", "xb"],
// beehive (f1=escape, f2=ctrl C)
"no_pad_char": ["npc", "NP"],
// pad character does not exist
"non_dest_scroll_region": ["ndscr", "ND"],
// scrolling region is non-destructive
"non_rev_rmcup": ["nrrmc", "NR"],
// smcup does not reverse rmcup
"over_strike": ["os", "os"],
// terminal can over‐ strike
"prtr_silent": ["mc5i", "5i"],
// printer will not echo on screen
"row_addr_glitch": ["xvpa", "YD"],
// only positive motion for vpa/mvpa caps
"semi_auto_right_margin": ["sam", "YE"],
// printing in last column causes cr
"status_line_esc_ok": ["eslok", "es"],
// escape can be used on the status line
"tilde_glitch": ["hz", "hz"],
// cannot print ~'s (hazeltine)
"transparent_underline": ["ul", "ul"],
// underline character overstrikes
"xon_xoff": ["xon", "xo"]
// terminal uses xon/xoff handshaking
};
alias.numbers = {
// Variable Cap- TCap Description
// Numeric name Code
"columns": ["cols", "co"],
// number of columns in a line
"init_tabs": ["it", "it"],
// tabs initially every # spaces
"label_height": ["lh", "lh"],
// rows in each label
"label_width": ["lw", "lw"],
// columns in each label
"lines": ["lines", "li"],
// number of lines on screen or page
"lines_of_memory": ["lm", "lm"],
// lines of memory if > line. 0 means varies
"magic_cookie_glitch": ["xmc", "sg"],
// number of blank characters left by smso or rmso
"max_attributes": ["ma", "ma"],
// maximum combined attributes terminal can handle
"max_colors": ["colors", "Co"],
// maximum number of colors on screen
"max_pairs": ["pairs", "pa"],
// maximum number of color-pairs on the screen
"maximum_windows": ["wnum", "MW"],
// maximum number of defineable windows
"no_color_video": ["ncv", "NC"],
// video attributes that cannot be used with colors
"num_labels": ["nlab", "Nl"],
// number of labels on screen
"padding_baud_rate": ["pb", "pb"],
// lowest baud rate where padding needed
"virtual_terminal": ["vt", "vt"],
// virtual terminal number (CB/unix)
"width_status_line": ["wsl", "ws"],
// number of columns in status line
// The following numeric capabilities are present in the SVr4.0 term structure, but are not yet documented in the man page. They came in with
// SVr4's printer support.
// Variable Cap- TCap Description
// Numeric name Code
"bit_image_entwining": ["bitwin", "Yo"],
// number of passes for each bit-image row
"bit_image_type": ["bitype", "Yp"],
// type of bit-image device
"buffer_capacity": ["bufsz", "Ya"],
// numbers of bytes buffered before printing
"buttons": ["btns", "BT"],
// number of buttons on mouse
"dot_horz_spacing": ["spinh", "Yc"],
// spacing of dots hor‐ izontally in dots per inch
"dot_vert_spacing": ["spinv", "Yb"],
// spacing of pins ver‐ tically in pins per inch
"max_micro_address": ["maddr", "Yd"],
// maximum value in micro_..._address
"max_micro_jump": ["mjump", "Ye"],
// maximum value in parm_..._micro
"micro_col_size": ["mcs", "Yf"],
// character step size when in micro mode
"micro_line_size": ["mls", "Yg"],
// line step size when in micro mode
"number_of_pins": ["npins", "Yh"],
// numbers of pins in print-head
"output_res_char": ["orc", "Yi"],
// horizontal resolu‐ tion in units per line
"output_res_horz_inch": ["orhi", "Yk"],
// horizontal resolu‐ tion in units per inch
"output_res_line": ["orl", "Yj"],
// vertical resolution in units per line
"output_res_vert_inch": ["orvi", "Yl"],
// vertical resolution in units per inch
"print_rate": ["cps", "Ym"],
// print rate in char‐ acters per second
"wide_char_size": ["widcs", "Yn"]
// character step size when in double wide mode
};
alias.strings = {
// Variable Cap- TCap Description
// String name Code
"acs_chars": ["acsc", "ac"],
// graphics charset pairs, based on vt100
"back_tab": ["cbt", "bt"],
// back tab (P)
"bell": ["bel", "bl"],
// audible signal (bell) (P)
"carriage_return": ["cr", "cr"],
// carriage return (P*) (P*)
"change_char_pitch": ["cpi", "ZA"],
// Change number of characters per inch to #1
"change_line_pitch": ["lpi", "ZB"],
// Change number of lines per inch to #1
"change_res_horz": ["chr", "ZC"],
// Change horizontal resolution to #1
"change_res_vert": ["cvr", "ZD"],
// Change vertical res‐ olution to #1
"change_scroll_region": ["csr", "cs"],
// change region to line #1 to line #2 (P)
"char_padding": ["rmp", "rP"],
// like ip but when in insert mode
"clear_all_tabs": ["tbc", "ct"],
// clear all tab stops (P)
"clear_margins": ["mgc", "MC"],
// clear right and left soft margins
"clear_screen": ["clear", "cl"],
// clear screen and home cursor (P*)
"clr_bol": ["el1", "cb"],
// Clear to beginning of line
"clr_eol": ["el", "ce"],
// clear to end of line (P)
"clr_eos": ["ed", "cd"],
// clear to end of screen (P*)
"column_address": ["hpa", "ch"],
// horizontal position #1, absolute (P)
"command_character": ["cmdch", "CC"],
// terminal settable cmd character in prototype !?
"create_window": ["cwin", "CW"],
// define a window #1 from #2,#3 to #4,#5
"cursor_address": ["cup", "cm"],
// move to row #1 col‐ umns #2
"cursor_down": ["cud1", "do"],
// down one line
"cursor_home": ["home", "ho"],
// home cursor (if no cup)
"cursor_invisible": ["civis", "vi"],
// make cursor invisi‐ ble
"cursor_left": ["cub1", "le"],
// move left one space
"cursor_mem_address": ["mrcup", "CM"],
// memory relative cur‐ sor addressing, move to row #1 columns #2
"cursor_normal": ["cnorm", "ve"],
// make cursor appear normal (undo civis/cvvis)
"cursor_right": ["cuf1", "nd"],
// non-destructive space (move right one space)
"cursor_to_ll": ["ll", "ll"],
// last line, first column (if no cup)
"cursor_up": ["cuu1", "up"],
// up one line
"cursor_visible": ["cvvis", "vs"],
// make cursor very visible
"define_char": ["defc", "ZE"],
// Define a character #1, #2 dots wide, descender #3
"delete_character": ["dch1", "dc"],
// delete character (P*)
"delete_line": ["dl1", "dl"],
// delete line (P*)
"dial_phone": ["dial", "DI"],
// dial number #1
"dis_status_line": ["dsl", "ds"],
// disable status line
"display_clock": ["dclk", "DK"],
// display clock
"down_half_line": ["hd", "hd"],
// half a line down
"ena_acs": ["enacs", "eA"],
// enable alternate char set
"enter_alt_charset_mode": ["smacs", "as"],
// start alternate character set (P)
"enter_am_mode": ["smam", "SA"],
// turn on automatic margins
"enter_blink_mode": ["blink", "mb"],
// turn on blinking
"enter_bold_mode": ["bold", "md"],
// turn on bold (extra bright) mode
"enter_ca_mode": ["smcup", "ti"],
// string to start pro‐ grams using cup
"enter_delete_mode": ["smdc", "dm"],
// enter delete mode
"enter_dim_mode": ["dim", "mh"],
// turn on half-bright mode
"enter_doublewide_mode": ["swidm", "ZF"],
// Enter double-wide mode
"enter_draft_quality": ["sdrfq", "ZG"],
// Enter draft-quality mode
"enter_insert_mode": ["smir", "im"],
// enter insert mode
"enter_italics_mode": ["sitm", "ZH"],
// Enter italic mode
"enter_leftward_mode": ["slm", "ZI"],
// Start leftward car‐ riage motion
"enter_micro_mode": ["smicm", "ZJ"],
// Start micro-motion mode
"enter_near_letter_quality": ["snlq", "ZK"],
// Enter NLQ mode
"enter_normal_quality": ["snrmq", "ZL"],
// Enter normal-quality mode
"enter_protected_mode": ["prot", "mp"],
// turn on protected mode
"enter_reverse_mode": ["rev", "mr"],
// turn on reverse video mode
"enter_secure_mode": ["invis", "mk"],
// turn on blank mode (characters invisible)
"enter_shadow_mode": ["sshm", "ZM"],
// Enter shadow-print mode
"enter_standout_mode": ["smso", "so"],
// begin standout mode
"enter_subscript_mode": ["ssubm", "ZN"],
// Enter subscript mode
"enter_superscript_mode": ["ssupm", "ZO"],
// Enter superscript mode
"enter_underline_mode": ["smul", "us"],
// begin underline mode
"enter_upward_mode": ["sum", "ZP"],
// Start upward car‐ riage motion
"enter_xon_mode": ["smxon", "SX"],
// turn on xon/xoff handshaking
"erase_chars": ["ech", "ec"],
// erase #1 characters (P)
"exit_alt_charset_mode": ["rmacs", "ae"],
// end alternate char‐ acter set (P)
"exit_am_mode": ["rmam", "RA"],
// turn off automatic margins
"exit_attribute_mode": ["sgr0", "me"],
// turn off all attributes
"exit_ca_mode": ["rmcup", "te"],
// strings to end pro‐ grams using cup
"exit_delete_mode": ["rmdc", "ed"],
// end delete mode
"exit_doublewide_mode": ["rwidm", "ZQ"],
// End double-wide mode
"exit_insert_mode": ["rmir", "ei"],
// exit insert mode
"exit_italics_mode": ["ritm", "ZR"],
// End italic mode
"exit_leftward_mode": ["rlm", "ZS"],
// End left-motion mode
"exit_micro_mode": ["rmicm", "ZT"],
// End micro-motion mode
"exit_shadow_mode": ["rshm", "ZU"],
// End shadow-print mode
"exit_standout_mode": ["rmso", "se"],
// exit standout mode
"exit_subscript_mode": ["rsubm", "ZV"],
// End subscript mode
"exit_superscript_mode": ["rsupm", "ZW"],
// End superscript mode
"exit_underline_mode": ["rmul", "ue"],
// exit underline mode
"exit_upward_mode": ["rum", "ZX"],
// End reverse charac‐ ter motion
"exit_xon_mode": ["rmxon", "RX"],
// turn off xon/xoff handshaking
"fixed_pause": ["pause", "PA"],
// pause for 2-3 seconds
"flash_hook": ["hook", "fh"],
// flash switch hook
"flash_screen": ["flash", "vb"],
// visible bell (may not move cursor)
"form_feed": ["ff", "ff"],
// hardcopy terminal page eject (P*)
"from_status_line": ["fsl", "fs"],
// return from status line
"goto_window": ["wingo", "WG"],
// go to window #1
"hangup": ["hup", "HU"],
// hang-up phone
"init_1string": ["is1", "i1"],
// initialization string
"init_2string": ["is2", "is"],
// initialization string
"init_3string": ["is3", "i3"],
// initialization string
"init_file": ["if", "if"],
// name of initializa‐ tion file
"init_prog": ["iprog", "iP"],
// path name of program for initialization
"initialize_color": ["initc", "Ic"],
// initialize color #1 to (#2,#3,#4)
"initialize_pair": ["initp", "Ip"],
// Initialize color pair #1 to fg=(#2,#3,#4), bg=(#5,#6,#7)
"insert_character": ["ich1", "ic"],
// insert character (P)
"insert_line": ["il1", "al"],
// insert line (P*)
"insert_padding": ["ip", "ip"],
// insert padding after inserted character
"key_a1": ["ka1", "K1"],
// upper left of keypad
"key_a3": ["ka3", "K3"],
// upper right of key‐ pad
"key_b2": ["kb2", "K2"],
// center of keypad
"key_backspace": ["kbs", "kb"],
// backspace key
"key_beg": ["kbeg", "@1"],
// begin key
"key_btab": ["kcbt", "kB"],
// back-tab key
"key_c1": ["kc1", "K4"],
// lower left of keypad
"key_c3": ["kc3", "K5"],
// lower right of key‐ pad
"key_cancel": ["kcan", "@2"],
// cancel key
"key_catab": ["ktbc", "ka"],
// clear-all-tabs key
"key_clear": ["kclr", "kC"],
// clear-screen or erase key
"key_close": ["kclo", "@3"],
// close key
"key_command": ["kcmd", "@4"],
// command key
"key_copy": ["kcpy", "@5"],
// copy key
"key_create": ["kcrt", "@6"],
// create key
"key_ctab": ["kctab", "kt"],
// clear-tab key
"key_dc": ["kdch1", "kD"],
// delete-character key
"key_dl": ["kdl1", "kL"],
// delete-line key
"key_down": ["kcud1", "kd"],
// down-arrow key
"key_eic": ["krmir", "kM"],
// sent by rmir or smir in insert mode
"key_end": ["kend", "@7"],
// end key
"key_enter": ["kent", "@8"],
// enter/send key
"key_eol": ["kel", "kE"],
// clear-to-end-of- line key
"key_eos": ["ked", "kS"],
// clear-to-end-of- screen key
"key_exit": ["kext", "@9"],
// exit key
"key_f0": ["kf0", "k0"],
// F0 function key
"key_f1": ["kf1", "k1"],
// F1 function key
"key_f10": ["kf10", "k;"],
//