Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

antsy

Package Overview
Dependencies
Maintainers
1
Versions
31
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

antsy - npm Package Compare versions

Comparing version 2.9.2 to 3.0.1

lib/antsy/cheap.d.ts

15

lib/antsy/keys.d.ts

@@ -42,4 +42,3 @@ export declare enum Modifier {

}
export declare class KeyParser {
emit: (keys: Key[]) => void;
export declare class KeyParser implements AsyncIterator<Key>, AsyncIterable<Key> {
state: State;

@@ -49,7 +48,13 @@ modifiers: Modifier;

lastKey: number;
constructor(emit: (keys: Key[]) => void);
queue: Key[];
resolve: ((value: IteratorResult<Key>) => void) | undefined;
ended: boolean;
[Symbol.asyncIterator](): this;
next(): Promise<IteratorResult<Key>>;
private wake;
end(): void;
feed(s: string): void;
feedCodepoint(c: number, rv: Key[]): boolean;
parseCsi(rv: Key[], command: string, args: number[]): void;
feedCodepoint(c: number): boolean;
parseCsi(command: string, args: number[]): void;
}
export {};

@@ -11,15 +11,2 @@ "use strict";

})(Modifier = exports.Modifier || (exports.Modifier = {}));
function modifiersFromFlags(n) {
const rv = [];
n -= 1;
if (n & 8)
rv.push(Modifier.Meta);
if (n & 2)
rv.push(Modifier.Alt);
if (n & 1)
rv.push(Modifier.Shift);
if (n & 4)
rv.push(Modifier.Control);
return rv;
}
var KeyType;

@@ -113,4 +100,3 @@ (function (KeyType) {

class KeyParser {
constructor(emit) {
this.emit = emit;
constructor() {
this.state = State.Normal;

@@ -120,13 +106,35 @@ this.modifiers = 0;

this.lastKey = Date.now();
// pass
// async iterator state: queued keys or waiting reader
this.queue = [];
this.ended = false;
}
[Symbol.asyncIterator]() {
return this;
}
next() {
return new Promise(resolve => {
this.resolve = resolve;
this.wake();
});
}
// check if we should hand out keys to a waiting reader
wake() {
if (!this.resolve || (!this.ended && this.queue.length == 0))
return;
const resolve = this.resolve;
this.resolve = undefined;
const value = this.queue.shift();
resolve({ done: this.ended, value });
}
end() {
this.ended = true;
this.wake();
}
feed(s) {
const rv = [];
let checkMeta = false;
for (let c of Array.from(s).map(s => s.codePointAt(0) || 0)) {
checkMeta = this.feedCodepoint(c, rv);
checkMeta = this.feedCodepoint(c);
}
this.lastKey = Date.now();
if (rv.length > 0)
this.emit(rv);
this.wake();
if (checkMeta) {

@@ -136,4 +144,5 @@ setTimeout(() => {

// dangling ESC, maybe it was just ESC...
this.emit([new Key(this.modifiers, KeyType.Esc)]);
this.queue.push(new Key(this.modifiers, KeyType.Esc));
this.state = State.Normal;
this.wake();
}

@@ -144,3 +153,3 @@ }, ESC_TIMEOUT);

// returns true if it processed a dangling ESC
feedCodepoint(c, rv) {
feedCodepoint(c) {
switch (this.state) {

@@ -150,7 +159,7 @@ case State.Normal:

case Ascii.TAB:
rv.push(new Key(this.modifiers, KeyType.Tab));
this.queue.push(new Key(this.modifiers, KeyType.Tab));
this.modifiers = 0;
return false;
case Ascii.CR:
rv.push(new Key(this.modifiers, KeyType.Return));
this.queue.push(new Key(this.modifiers, KeyType.Return));
this.modifiers = 0;

@@ -163,3 +172,3 @@ return false;

case Ascii.DEL:
rv.push(new Key(this.modifiers, KeyType.Backspace));
this.queue.push(new Key(this.modifiers, KeyType.Backspace));
this.modifiers = 0;

@@ -173,3 +182,3 @@ return false;

}
rv.push(new Key(this.modifiers, KeyType.Normal, String.fromCodePoint(c)));
this.queue.push(new Key(this.modifiers, KeyType.Normal, String.fromCodePoint(c)));
this.modifiers = 0;

@@ -191,3 +200,3 @@ return false;

this.state = State.Normal;
return this.feedCodepoint(c, rv);
return this.feedCodepoint(c);
}

@@ -199,3 +208,3 @@ case State.CSI:

}
this.parseCsi(rv, String.fromCodePoint(c), this.buffer.split(/[;:]/).map(s => parseInt(s, 10)));
this.parseCsi(String.fromCodePoint(c), this.buffer.split(/[;:]/).map(s => parseInt(s, 10)));
this.state = State.Normal;

@@ -206,3 +215,3 @@ this.modifiers = 0;

if (c >= Ascii.P && c <= Ascii.S) {
rv.push(new Key(this.modifiers, KeyType.Function, (1 + c - Ascii.P).toString()));
this.queue.push(new Key(this.modifiers, KeyType.Function, (1 + c - Ascii.P).toString()));
this.state = State.Normal;

@@ -214,9 +223,9 @@ this.modifiers = 0;

// what is ESC O (something)? we don't support it.
rv.push(new Key(Modifier.Meta, KeyType.Normal, "O"));
this.queue.push(new Key(Modifier.Meta, KeyType.Normal, "O"));
this.state = State.Normal;
return this.feedCodepoint(c, rv);
return this.feedCodepoint(c);
}
}
}
parseCsi(rv, command, args) {
parseCsi(command, args) {
if (args[0] == 1 && args.length >= 2)

@@ -226,34 +235,34 @@ this.modifiers |= (args[1] - 1);

case "A":
rv.push(new Key(this.modifiers, KeyType.Up));
this.queue.push(new Key(this.modifiers, KeyType.Up));
break;
case "B":
rv.push(new Key(this.modifiers, KeyType.Down));
this.queue.push(new Key(this.modifiers, KeyType.Down));
break;
case "C":
rv.push(new Key(this.modifiers, KeyType.Right));
this.queue.push(new Key(this.modifiers, KeyType.Right));
break;
case "D":
rv.push(new Key(this.modifiers, KeyType.Left));
this.queue.push(new Key(this.modifiers, KeyType.Left));
break;
case "H":
rv.push(new Key(this.modifiers, KeyType.Home));
this.queue.push(new Key(this.modifiers, KeyType.Home));
break;
case "F":
rv.push(new Key(this.modifiers, KeyType.End));
this.queue.push(new Key(this.modifiers, KeyType.End));
break;
case "P":
rv.push(new Key(this.modifiers, KeyType.Function, "1"));
this.queue.push(new Key(this.modifiers, KeyType.Function, "1"));
break;
case "Q":
rv.push(new Key(this.modifiers, KeyType.Function, "2"));
this.queue.push(new Key(this.modifiers, KeyType.Function, "2"));
break;
case "R":
rv.push(new Key(this.modifiers, KeyType.Function, "3"));
this.queue.push(new Key(this.modifiers, KeyType.Function, "3"));
break;
case "S":
rv.push(new Key(this.modifiers, KeyType.Function, "4"));
this.queue.push(new Key(this.modifiers, KeyType.Function, "4"));
break;
case "Z":
// xterm sends a special code for shift-tab!
rv.push(new Key(Modifier.Shift, KeyType.Tab));
this.queue.push(new Key(Modifier.Shift, KeyType.Tab));
break;

@@ -265,62 +274,62 @@ case "~": {

case 1:
rv.push(new Key(this.modifiers, KeyType.Home));
this.queue.push(new Key(this.modifiers, KeyType.Home));
break;
case 2:
rv.push(new Key(this.modifiers, KeyType.Insert));
this.queue.push(new Key(this.modifiers, KeyType.Insert));
break;
case 3:
rv.push(new Key(this.modifiers, KeyType.Delete));
this.queue.push(new Key(this.modifiers, KeyType.Delete));
break;
case 4:
rv.push(new Key(this.modifiers, KeyType.End));
this.queue.push(new Key(this.modifiers, KeyType.End));
break;
case 5:
rv.push(new Key(this.modifiers, KeyType.PageUp));
this.queue.push(new Key(this.modifiers, KeyType.PageUp));
break;
case 6:
rv.push(new Key(this.modifiers, KeyType.PageDown));
this.queue.push(new Key(this.modifiers, KeyType.PageDown));
break;
case 11:
rv.push(new Key(this.modifiers, KeyType.Function, "1"));
this.queue.push(new Key(this.modifiers, KeyType.Function, "1"));
break;
case 12:
rv.push(new Key(this.modifiers, KeyType.Function, "2"));
this.queue.push(new Key(this.modifiers, KeyType.Function, "2"));
break;
case 13:
rv.push(new Key(this.modifiers, KeyType.Function, "3"));
this.queue.push(new Key(this.modifiers, KeyType.Function, "3"));
break;
case 14:
rv.push(new Key(this.modifiers, KeyType.Function, "4"));
this.queue.push(new Key(this.modifiers, KeyType.Function, "4"));
break;
case 15:
rv.push(new Key(this.modifiers, KeyType.Function, "5"));
this.queue.push(new Key(this.modifiers, KeyType.Function, "5"));
break;
// what happened to 16?
case 17:
rv.push(new Key(this.modifiers, KeyType.Function, "6"));
this.queue.push(new Key(this.modifiers, KeyType.Function, "6"));
break;
case 18:
rv.push(new Key(this.modifiers, KeyType.Function, "7"));
this.queue.push(new Key(this.modifiers, KeyType.Function, "7"));
break;
case 19:
rv.push(new Key(this.modifiers, KeyType.Function, "8"));
this.queue.push(new Key(this.modifiers, KeyType.Function, "8"));
break;
case 20:
rv.push(new Key(this.modifiers, KeyType.Function, "9"));
this.queue.push(new Key(this.modifiers, KeyType.Function, "9"));
break;
case 21:
rv.push(new Key(this.modifiers, KeyType.Function, "10"));
this.queue.push(new Key(this.modifiers, KeyType.Function, "10"));
break;
// what happened to 22?
case 23:
rv.push(new Key(this.modifiers, KeyType.Function, "11"));
this.queue.push(new Key(this.modifiers, KeyType.Function, "11"));
break;
case 24:
rv.push(new Key(this.modifiers, KeyType.Function, "12"));
this.queue.push(new Key(this.modifiers, KeyType.Function, "12"));
break;
case 200:
rv.push(new Key(this.modifiers, KeyType.PasteBegin));
this.queue.push(new Key(this.modifiers, KeyType.PasteBegin));
break;
case 201:
rv.push(new Key(this.modifiers, KeyType.PasteEnd));
this.queue.push(new Key(this.modifiers, KeyType.PasteEnd));
break;

@@ -332,4 +341,4 @@ }

// well crap. CSI + garbage?
rv.push(new Key(Modifier.Meta, KeyType.Normal, "["));
rv.push(new Key(0, KeyType.Normal, command));
this.queue.push(new Key(Modifier.Meta, KeyType.Normal, "["));
this.queue.push(new Key(0, KeyType.Normal, command));
break;

@@ -336,0 +345,0 @@ }

"use strict";
var __asyncValues = (this && this.__asyncValues) || function (o) {
if (!Symbol.asyncIterator) throw new TypeError("Symbol.asyncIterator is not defined.");
var m = o[Symbol.asyncIterator], i;
return m ? m.call(o) : (o = typeof __values === "function" ? __values(o) : o[Symbol.iterator](), i = {}, verb("next"), verb("throw"), verb("return"), i[Symbol.asyncIterator] = function () { return this; }, i);
function verb(n) { i[n] = o[n] && function (v) { return new Promise(function (resolve, reject) { v = o[n](v), settle(resolve, reject, v.done, v.value); }); }; }
function settle(resolve, reject, d, v) { Promise.resolve(v).then(function(v) { resolve({ value: v, done: d }); }, reject); }
};
Object.defineProperty(exports, "__esModule", { value: true });

@@ -6,38 +13,56 @@ const keys_1 = require("../antsy/keys");

require("source-map-support/register");
function keyParser() {
const output = [];
const parser = new keys_1.KeyParser(keys => keys.forEach(k => output.push(k)));
return { parser, output };
}
function bundle(keys) {
return keys.map(k => k.toString()).join(",");
}
const delay = (msec) => new Promise(resolve => setTimeout(resolve, msec));
describe("KeyParser", () => {
it("handles ascii", () => {
const { parser, output } = keyParser();
let parser = new keys_1.KeyParser();
let output = [];
beforeEach(() => {
parser = new keys_1.KeyParser();
output = [];
setTimeout(async () => {
var e_1, _a;
try {
for (var parser_1 = __asyncValues(parser), parser_1_1; parser_1_1 = await parser_1.next(), !parser_1_1.done;) {
const key = parser_1_1.value;
output.push(key);
}
}
catch (e_1_1) { e_1 = { error: e_1_1 }; }
finally {
try {
if (parser_1_1 && !parser_1_1.done && (_a = parser_1.return)) await _a.call(parser_1);
}
finally { if (e_1) throw e_1.error; }
}
}, 0);
});
afterEach(() => {
parser.end();
});
it("handles ascii", async () => {
parser.feed("hell");
parser.feed("o");
await delay(1);
bundle(output).should.eql("h,e,l,l,o");
});
it("control codes", () => {
const { parser, output } = keyParser();
it("control codes", async () => {
parser.feed("hell\u0001s\u0009\u0008\u000d\u007f");
await delay(1);
bundle(output).should.eql("h,e,l,l,C-A,s,Tab,Backspace,Return,Backspace");
});
it("meta codes", () => {
const { parser, output } = keyParser();
it("meta codes", async () => {
parser.feed("x\u001bc\u001b[y");
await delay(1);
bundle(output).should.eql("x,M-c,M-[,y");
});
it("raw esc", done => {
const { parser, output } = keyParser();
it("raw esc", async () => {
parser.feed("\u001b");
setTimeout(() => {
parser.feed("a");
bundle(output).should.eql("Esc,a");
done();
}, 150);
await delay(150);
parser.feed("a");
await delay(1);
bundle(output).should.eql("Esc,a");
});
it("arrows", () => {
const { parser, output } = keyParser();
it("arrows", async () => {
parser.feed("\u001b[A");

@@ -47,6 +72,6 @@ parser.feed("\u001b");

parser.feed("B\u001b[D");
await delay(1);
bundle(output).should.eql("Up,Right,Down,Left");
});
it("arrows with modifiers", () => {
const { parser, output } = keyParser();
it("arrows with modifiers", async () => {
parser.feed("\u001b[1;2A");

@@ -56,34 +81,35 @@ parser.feed("\u001b[1;5A");

parser.feed("\u001b\u001b[1;2A");
await delay(1);
bundle(output).should.eql("S-Up,C-Up,S-C-Up,M-S-Up");
});
it("home/end", () => {
const { parser, output } = keyParser();
it("home/end", async () => {
parser.feed("\u001b[H\u001b[F\u001b[1~\u001b[4~");
await delay(1);
bundle(output).should.eql("Home,End,Home,End");
});
it("ins/del/pgup/pgdn", () => {
const { parser, output } = keyParser();
it("ins/del/pgup/pgdn", async () => {
parser.feed("\u001b[2~\u001b[3~\u001b[5~\u001b[6~");
await delay(1);
bundle(output).should.eql("Insert,Delete,PageUp,PageDown");
});
it("old f-keys", () => {
const { parser, output } = keyParser();
it("old f-keys", async () => {
parser.feed("\u001bOP\u001bOQ\u001bOR\u001bOS");
await delay(1);
bundle(output).should.eql("F1,F2,F3,F4");
});
it("new f-keys", () => {
const { parser, output } = keyParser();
it("new f-keys", async () => {
parser.feed("\u001b[11~\u001b[12~\u001b[13~\u001b[14~\u001b[15~");
parser.feed("\u001b[17~\u001b[18~\u001b[19~\u001b[20~\u001b[21~");
parser.feed("\u001b[23~\u001b[24~");
await delay(1);
bundle(output).should.eql("F1,F2,F3,F4,F5,F6,F7,F8,F9,F10,F11,F12");
});
it("f-keys with modifiers", () => {
const { parser, output } = keyParser();
it("f-keys with modifiers", async () => {
parser.feed("\u001b[11;2~\u001b[12;5~\u001b[13;6~\u001b[1;2P\u001b\u001b[1;5Q");
await delay(1);
bundle(output).should.eql("S-F1,C-F2,S-C-F3,S-F1,M-C-F2");
});
it("paste", () => {
const { parser, output } = keyParser();
it("paste", async () => {
parser.feed("\u001b[200~password\u001b[201~");
await delay(1);
bundle(output).should.eql("Paste,p,a,s,s,w,o,r,d,/Paste");

@@ -90,0 +116,0 @@ });

{
"name": "antsy",
"version": "2.9.2",
"version": "3.0.1",
"description": "draw full-color (xterm-256) ansi graphics into a buffer",

@@ -5,0 +5,0 @@ "keywords": [

@@ -136,3 +136,3 @@ # Antsy

+-----------------------+
````
```

@@ -190,2 +190,33 @@ ...you could use a grid layout with 2 columns and 2 rows. The left column and top row are stretchy:

## KeyParser
Antsy can also parse a stream of xterm/VT input and convert it into key events.
- `new KeyParser() // implements AsyncIterator<Key>, AsyncIterable<Key>`
Feed incoming bytes:
- `feed(s: string): void`
Parsed key events will emerge on the async iterator as `Key` objects. Each `Key` object contains three fields:
- `modifiers: Modifier`
A bitmap of modifier keys: `Shift`, `Alt`, `Control`, `Meta`
- `type: KeyType`
Either `Normal` for a common ASCII symbol (like "a" or "7" or ":"), or one of:
- `Up`, `Down`, `Left`, `Right` arrow keys
- `PageUp`, `PageDown`, `Home`, `End` extreme arrow keys
- `Insert`, `Delete` vestigial IBM keys
- `Tab`, `Return`, `Esc`, `Backspace`
- `Function` (with `key` being "1" through "12")
- `PasteBegin`, `PasteEnd` to mark xterm paste boundaries
- `key: string`
The ASCII key pressed, or the number of the function key, or "".
## How it works

@@ -192,0 +223,0 @@

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc