Latest Threat Research:SANDWORM_MODE: Shai-Hulud-Style npm Worm Hijacks CI Workflows and Poisons AI Toolchains.Details
Socket
Book a DemoInstallSign in
Socket

emit-keypress

Package Overview
Dependencies
Maintainers
1
Versions
36
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

emit-keypress - npm Package Compare versions

Comparing version
1.0.1
to
2.0.0
+153
-22
dist/index.js

@@ -22,4 +22,9 @@ "use strict";

// index.ts
var emit_keypress_exports = {};
__export(emit_keypress_exports, {
var index_exports = {};
__export(index_exports, {
DISABLE_MOUSE: () => DISABLE_MOUSE,
DISABLE_PASTE_BRACKET_MODE: () => DISABLE_PASTE_BRACKET_MODE,
ENABLE_MOUSE: () => ENABLE_MOUSE,
ENABLE_PASTE_BRACKET_MODE: () => ENABLE_PASTE_BRACKET_MODE,
MAX_PASTE_BUFFER: () => MAX_PASTE_BUFFER,
NON_PRINTABLE_CHAR_REGEX: () => NON_PRINTABLE_CHAR_REGEX,

@@ -30,3 +35,3 @@ PRINTABLE_CHAR_REGEX: () => PRINTABLE_CHAR_REGEX,

cursor: () => cursor,
default: () => emit_keypress_default,
default: () => index_default,
disableMouse: () => disableMouse,

@@ -43,2 +48,3 @@ disablePaste: () => disablePaste,

isPrintableCharacter: () => isPrintableCharacter,
isWindows: () => isWindows,
keycodes: () => keycodes,

@@ -56,4 +62,5 @@ metaKeys: () => metaKeys,

});
module.exports = __toCommonJS(emit_keypress_exports);
module.exports = __toCommonJS(index_exports);
var import_node_process = require("process");
var import_detect_terminal = require("detect-terminal");

@@ -66,3 +73,2 @@ // src/emit-keypress.ts

var kEscape = "\x1B";
var kSubstringSearch = Symbol("kSubstringSearch");
var kUTF16SurrogateThreshold = 65536;

@@ -85,2 +91,6 @@ function CSI(strings, ...args) {

CSI.kClearScreenDown = CSI`0J`;
var CSI_U_ENABLE = `${kEscape}[>4;1m`;
var CSI_U_DISABLE = `${kEscape}[>4;0m`;
var KITTY_ENABLE = `${kEscape}[>1u`;
var KITTY_DISABLE = `${kEscape}[<u`;
function charLengthAt(str, i) {

@@ -147,2 +157,41 @@ if (str.length <= i) {

let match;
const SPECIAL_NAMES = {
8: "backspace",
// BS (ctrl+h legacy)
9: "tab",
10: "enter",
// LF
13: "return",
// CR
27: "escape",
32: "space",
127: "backspace"
// DEL
};
if (match = /^(\d+);(\d+)u$/.exec(cmd)) {
const charCode = parseInt(match[1], 10);
modifier = parseInt(match[2], 10) - 1;
const char = String.fromCharCode(charCode);
key.name = SPECIAL_NAMES[charCode] || char.toLowerCase();
key.ctrl = Boolean(modifier & 4);
key.meta = Boolean(modifier & 10);
key.shift = Boolean(modifier & 1) || char !== char.toLowerCase();
key.code = `[${match[1]}u`;
key.sequence = s;
stream.emit("keypress", void 0, key);
continue;
}
if (match = /^27;(\d+);(\d+)~$/.exec(cmd)) {
modifier = parseInt(match[1], 10) - 1;
const charCode = parseInt(match[2], 10);
const char = String.fromCharCode(charCode);
key.name = SPECIAL_NAMES[charCode] || char.toLowerCase();
key.ctrl = Boolean(modifier & 4);
key.meta = Boolean(modifier & 10);
key.shift = Boolean(modifier & 1) || char !== char.toLowerCase();
key.code = `[27;${match[1]};${match[2]}~`;
key.sequence = s;
stream.emit("keypress", void 0, key);
continue;
}
if (match = /^(?:(\d\d?)(?:;(\d))?([~^$])|(\d{3}~))$/.exec(cmd)) {

@@ -186,2 +235,3 @@ if (match[4]) {

}
/* xterm/gnome ESC [ letter (with modifier) */
case "[P":

@@ -203,2 +253,3 @@ key.name = "f1";

break;
/* xterm/gnome ESC O letter (without modifier) */
case "OP":

@@ -220,2 +271,3 @@ key.name = "f1";

break;
/* xterm/rxvt ESC [ number ~ */
case "[11~":

@@ -237,2 +289,3 @@ key.name = "f1";

break;
/* paste bracket mode */
case "[200~":

@@ -244,2 +297,3 @@ key.name = "paste-start";

break;
/* from Cygwin and used in libuv */
case "[[A":

@@ -265,2 +319,3 @@ key.name = "f1";

break;
/* common */
case "[15~":

@@ -298,2 +353,3 @@ key.name = "f5";

break;
/* common */
case "[15;10":

@@ -341,2 +397,3 @@ key.name = "f5";

break;
/* xterm ESC [ letter */
case "[A":

@@ -363,2 +420,3 @@ key.name = "up";

break;
/* xterm/gnome ESC O letter */
case "OA":

@@ -385,2 +443,3 @@ key.name = "up";

break;
/* xterm/rxvt ESC [ number ~ */
case "[1~":

@@ -406,2 +465,3 @@ key.name = "home";

break;
/* putty */
case "[[5~":

@@ -413,2 +473,3 @@ key.name = "pageup";

break;
/* rxvt */
case "[7~":

@@ -420,2 +481,3 @@ key.name = "home";

break;
/* rxvt keys with modifiers */
case "[a":

@@ -635,2 +697,3 @@ key.name = "up";

break;
/* misc. */
case "[Z":

@@ -689,5 +752,5 @@ key.name = "tab";

var { kEscape: kEscape2 } = CSI;
var KEYPRESS_DECODER = Symbol("keypress-decoder");
var ESCAPE_DECODER = Symbol("escape-decoder");
var kSawKeyPress = Symbol("saw-key-press");
var KEYPRESS_DECODER = /* @__PURE__ */ Symbol("keypress-decoder");
var ESCAPE_DECODER = /* @__PURE__ */ Symbol("escape-decoder");
var kSawKeyPress = /* @__PURE__ */ Symbol("saw-key-press");
var ESCAPE_CODE_TIMEOUT = 500;

@@ -1058,6 +1121,6 @@ function emitKeypressEvents(stream, iface = {}) {

// <fn>
{ sequence: "\x1B[6~", shortcut: "fn+down", name: "end" },
{ sequence: "\x1B[H", shortcut: "fn+left", name: "home" },
{ sequence: "\x1B[F", shortcut: "fn+right", name: "pagedown" },
{ sequence: "\x1B[F", shortcut: "fn+right", name: "end" },
{ sequence: "\x1B[5~", shortcut: "fn+up", name: "pageup" },
{ sequence: "\x1B[6~", shortcut: "fn+down", name: "pagedown" },
// <fn+ctrl>

@@ -1156,2 +1219,50 @@ { sequence: "\x1B[1;5F", shortcut: "fn+ctrl+right" },

// src/keyboard-protocol.ts
var KITTY_PROTOCOL = {
name: "kitty",
enable: `${kEscape}[>1u`,
disable: `${kEscape}[<u`
};
var MOK_PROTOCOL = {
name: "mok",
enable: `${kEscape}[>4;1m`,
disable: `${kEscape}[>4;0m`
};
var KITTY_PROTOCOL_TERMINALS = /* @__PURE__ */ new Set([
"kitty",
"alacritty",
"foot",
"ghostty",
"iterm",
"rio",
"wezterm"
]);
var MOK_TERMINALS = /* @__PURE__ */ new Set([
"windows_terminal",
"xterm",
"gnome_terminal",
"konsole",
"vscode",
"xfce4_terminal",
"mate_terminal",
"terminator"
]);
var getKeyboardProtocol = /* @__PURE__ */ __name((terminal) => {
if (KITTY_PROTOCOL_TERMINALS.has(terminal)) return KITTY_PROTOCOL;
if (MOK_TERMINALS.has(terminal)) return MOK_PROTOCOL;
return null;
}, "getKeyboardProtocol");
var resetKeyboardProtocol = /* @__PURE__ */ __name((output) => {
output.write(KITTY_PROTOCOL.disable);
output.write(MOK_PROTOCOL.disable);
}, "resetKeyboardProtocol");
var enableKeyboardProtocol = /* @__PURE__ */ __name((terminal, output) => {
const protocol = getKeyboardProtocol(terminal);
if (!protocol) return null;
output.write(protocol.enable);
return () => {
output.write(protocol.disable);
};
}, "enableKeyboardProtocol");
// src/utils.ts

@@ -1246,2 +1357,5 @@ var PRINTABLE_CHAR_REGEX = /^(?!.*[\uFEFF])[\p{L}\p{N}\p{P}\p{S}\p{Z}\p{M}\u200D\s]+$/u;

if (keyName === "undefined") keyName = "";
if (keyName === "end" || keyName === "home") {
modifiers.delete("fn");
}
const output = modifiers.size > 0 && keyName ? `${sortModifiers([...modifiers]).join("+")}+${keyName}` : keyName;

@@ -1265,5 +1379,5 @@ return output.length > 1 ? output : "";

b.weight ||= 0;
return a.weight === b.weight ? 0 : a.weight > b.weight ? 1 : -1;
return a.weight === b.weight ? 0 : b.weight > a.weight ? 1 : -1;
});
return bindings;
return bindings.filter((b) => b.weight !== -1);
}, "prioritizeKeymap");

@@ -1275,9 +1389,8 @@ var isPrintableCharacter = /* @__PURE__ */ __name((s) => {

// index.ts
var ESC = "\x1B";
var isWindows = globalThis.process.platform === "win32";
var MAX_PASTE_BUFFER = 1024 * 1024;
var ENABLE_PASTE_BRACKET_MODE = `${ESC}[?2004h`;
var DISABLE_PASTE_BRACKET_MODE = `${ESC}[?2004l`;
var ENABLE_MOUSE = `${ESC}[?1003h`;
var DISABLE_MOUSE = `${ESC}[?1003l`;
var ENABLE_PASTE_BRACKET_MODE = `${kEscape}[?2004h`;
var DISABLE_PASTE_BRACKET_MODE = `${kEscape}[?2004l`;
var ENABLE_MOUSE = `${kEscape}[?1003h`;
var DISABLE_MOUSE = `${kEscape}[?1003l`;
var enablePaste = /* @__PURE__ */ __name((stdout2) => {

@@ -1297,9 +1410,9 @@ stdout2.write(ENABLE_PASTE_BRACKET_MODE);

hide: /* @__PURE__ */ __name((stdout2) => {
stdout2.write(`${ESC}[?25l`);
stdout2.write(`${kEscape}[?25l`);
}, "hide"),
show: /* @__PURE__ */ __name((stdout2) => {
stdout2.write(`${ESC}[?25h`);
stdout2.write(`${kEscape}[?25h`);
}, "show"),
position: /* @__PURE__ */ __name((stdout2) => {
stdout2.write(`${ESC}[6n`);
stdout2.write(`${kEscape}[6n`);
}, "position")

@@ -1375,3 +1488,4 @@ };

enablePasteMode = false,
pasteModeTimeout = 100
pasteModeTimeout = 100,
keyboardProtocol = false
}) => {

@@ -1388,2 +1502,3 @@ if (!input || input !== process.stdin && !input.isTTY) {

let pasteTimeout = null;
let disableProtocol = null;
const clearPasteState = /* @__PURE__ */ __name(() => {

@@ -1447,2 +1562,7 @@ pasting = false;

}
const found = keymap.filter((k) => k.sequence === key.sequence);
if (found.length === 1) {
key = { ...key, ...found[0] };
addShortcut = false;
}
const shortcut = key.shortcut ? sortShortcutModifier(key.shortcut) : createShortcut(key);

@@ -1487,2 +1607,3 @@ if (!key.shortcut && hasModifier(key)) {

if (enablePasteMode) disablePaste(output);
if (disableProtocol) disableProtocol();
if (onKeypress) input.off("keypress", handleKeypress);

@@ -1502,2 +1623,6 @@ if (pasteTimeout) clearTimeout(pasteTimeout);

}
resetKeyboardProtocol(output);
if (keyboardProtocol) {
disableProtocol = enableKeyboardProtocol((0, import_detect_terminal.detectTerminal)(), output);
}
if (!isWindows && input.isTTY) input.setRawMode(true);

@@ -1523,5 +1648,10 @@ if (hideCursor) cursor.hide(output);

var { emitKeypress } = createEmitKeypress();
var emit_keypress_default = emitKeypress;
var index_default = emitKeypress;
// Annotate the CommonJS export names for ESM import in node:
0 && (module.exports = {
DISABLE_MOUSE,
DISABLE_PASTE_BRACKET_MODE,
ENABLE_MOUSE,
ENABLE_PASTE_BRACKET_MODE,
MAX_PASTE_BUFFER,
NON_PRINTABLE_CHAR_REGEX,

@@ -1543,2 +1673,3 @@ PRINTABLE_CHAR_REGEX,

isPrintableCharacter,
isWindows,
keycodes,

@@ -1545,0 +1676,0 @@ metaKeys,

@@ -5,11 +5,11 @@ var __defProp = Object.defineProperty;

// index.ts
import { stdin, stdout } from "node:process";
import { stdin, stdout } from "process";
import { detectTerminal } from "detect-terminal";
// src/emit-keypress.ts
import { StringDecoder } from "node:string_decoder";
import { clearTimeout as clearTimeout2, setTimeout as setTimeout2 } from "node:timers";
import { StringDecoder } from "string_decoder";
import { clearTimeout as clearTimeout2, setTimeout as setTimeout2 } from "timers";
// src/keypress.ts
var kEscape = "\x1B";
var kSubstringSearch = Symbol("kSubstringSearch");
var kUTF16SurrogateThreshold = 65536;

@@ -32,2 +32,6 @@ function CSI(strings, ...args) {

CSI.kClearScreenDown = CSI`0J`;
var CSI_U_ENABLE = `${kEscape}[>4;1m`;
var CSI_U_DISABLE = `${kEscape}[>4;0m`;
var KITTY_ENABLE = `${kEscape}[>1u`;
var KITTY_DISABLE = `${kEscape}[<u`;
function charLengthAt(str, i) {

@@ -94,2 +98,41 @@ if (str.length <= i) {

let match;
const SPECIAL_NAMES = {
8: "backspace",
// BS (ctrl+h legacy)
9: "tab",
10: "enter",
// LF
13: "return",
// CR
27: "escape",
32: "space",
127: "backspace"
// DEL
};
if (match = /^(\d+);(\d+)u$/.exec(cmd)) {
const charCode = parseInt(match[1], 10);
modifier = parseInt(match[2], 10) - 1;
const char = String.fromCharCode(charCode);
key.name = SPECIAL_NAMES[charCode] || char.toLowerCase();
key.ctrl = Boolean(modifier & 4);
key.meta = Boolean(modifier & 10);
key.shift = Boolean(modifier & 1) || char !== char.toLowerCase();
key.code = `[${match[1]}u`;
key.sequence = s;
stream.emit("keypress", void 0, key);
continue;
}
if (match = /^27;(\d+);(\d+)~$/.exec(cmd)) {
modifier = parseInt(match[1], 10) - 1;
const charCode = parseInt(match[2], 10);
const char = String.fromCharCode(charCode);
key.name = SPECIAL_NAMES[charCode] || char.toLowerCase();
key.ctrl = Boolean(modifier & 4);
key.meta = Boolean(modifier & 10);
key.shift = Boolean(modifier & 1) || char !== char.toLowerCase();
key.code = `[27;${match[1]};${match[2]}~`;
key.sequence = s;
stream.emit("keypress", void 0, key);
continue;
}
if (match = /^(?:(\d\d?)(?:;(\d))?([~^$])|(\d{3}~))$/.exec(cmd)) {

@@ -133,2 +176,3 @@ if (match[4]) {

}
/* xterm/gnome ESC [ letter (with modifier) */
case "[P":

@@ -150,2 +194,3 @@ key.name = "f1";

break;
/* xterm/gnome ESC O letter (without modifier) */
case "OP":

@@ -167,2 +212,3 @@ key.name = "f1";

break;
/* xterm/rxvt ESC [ number ~ */
case "[11~":

@@ -184,2 +230,3 @@ key.name = "f1";

break;
/* paste bracket mode */
case "[200~":

@@ -191,2 +238,3 @@ key.name = "paste-start";

break;
/* from Cygwin and used in libuv */
case "[[A":

@@ -212,2 +260,3 @@ key.name = "f1";

break;
/* common */
case "[15~":

@@ -245,2 +294,3 @@ key.name = "f5";

break;
/* common */
case "[15;10":

@@ -288,2 +338,3 @@ key.name = "f5";

break;
/* xterm ESC [ letter */
case "[A":

@@ -310,2 +361,3 @@ key.name = "up";

break;
/* xterm/gnome ESC O letter */
case "OA":

@@ -332,2 +384,3 @@ key.name = "up";

break;
/* xterm/rxvt ESC [ number ~ */
case "[1~":

@@ -353,2 +406,3 @@ key.name = "home";

break;
/* putty */
case "[[5~":

@@ -360,2 +414,3 @@ key.name = "pageup";

break;
/* rxvt */
case "[7~":

@@ -367,2 +422,3 @@ key.name = "home";

break;
/* rxvt keys with modifiers */
case "[a":

@@ -582,2 +638,3 @@ key.name = "up";

break;
/* misc. */
case "[Z":

@@ -636,5 +693,5 @@ key.name = "tab";

var { kEscape: kEscape2 } = CSI;
var KEYPRESS_DECODER = Symbol("keypress-decoder");
var ESCAPE_DECODER = Symbol("escape-decoder");
var kSawKeyPress = Symbol("saw-key-press");
var KEYPRESS_DECODER = /* @__PURE__ */ Symbol("keypress-decoder");
var ESCAPE_DECODER = /* @__PURE__ */ Symbol("escape-decoder");
var kSawKeyPress = /* @__PURE__ */ Symbol("saw-key-press");
var ESCAPE_CODE_TIMEOUT = 500;

@@ -1005,6 +1062,6 @@ function emitKeypressEvents(stream, iface = {}) {

// <fn>
{ sequence: "\x1B[6~", shortcut: "fn+down", name: "end" },
{ sequence: "\x1B[H", shortcut: "fn+left", name: "home" },
{ sequence: "\x1B[F", shortcut: "fn+right", name: "pagedown" },
{ sequence: "\x1B[F", shortcut: "fn+right", name: "end" },
{ sequence: "\x1B[5~", shortcut: "fn+up", name: "pageup" },
{ sequence: "\x1B[6~", shortcut: "fn+down", name: "pagedown" },
// <fn+ctrl>

@@ -1103,2 +1160,50 @@ { sequence: "\x1B[1;5F", shortcut: "fn+ctrl+right" },

// src/keyboard-protocol.ts
var KITTY_PROTOCOL = {
name: "kitty",
enable: `${kEscape}[>1u`,
disable: `${kEscape}[<u`
};
var MOK_PROTOCOL = {
name: "mok",
enable: `${kEscape}[>4;1m`,
disable: `${kEscape}[>4;0m`
};
var KITTY_PROTOCOL_TERMINALS = /* @__PURE__ */ new Set([
"kitty",
"alacritty",
"foot",
"ghostty",
"iterm",
"rio",
"wezterm"
]);
var MOK_TERMINALS = /* @__PURE__ */ new Set([
"windows_terminal",
"xterm",
"gnome_terminal",
"konsole",
"vscode",
"xfce4_terminal",
"mate_terminal",
"terminator"
]);
var getKeyboardProtocol = /* @__PURE__ */ __name((terminal) => {
if (KITTY_PROTOCOL_TERMINALS.has(terminal)) return KITTY_PROTOCOL;
if (MOK_TERMINALS.has(terminal)) return MOK_PROTOCOL;
return null;
}, "getKeyboardProtocol");
var resetKeyboardProtocol = /* @__PURE__ */ __name((output) => {
output.write(KITTY_PROTOCOL.disable);
output.write(MOK_PROTOCOL.disable);
}, "resetKeyboardProtocol");
var enableKeyboardProtocol = /* @__PURE__ */ __name((terminal, output) => {
const protocol = getKeyboardProtocol(terminal);
if (!protocol) return null;
output.write(protocol.enable);
return () => {
output.write(protocol.disable);
};
}, "enableKeyboardProtocol");
// src/utils.ts

@@ -1193,2 +1298,5 @@ var PRINTABLE_CHAR_REGEX = /^(?!.*[\uFEFF])[\p{L}\p{N}\p{P}\p{S}\p{Z}\p{M}\u200D\s]+$/u;

if (keyName === "undefined") keyName = "";
if (keyName === "end" || keyName === "home") {
modifiers.delete("fn");
}
const output = modifiers.size > 0 && keyName ? `${sortModifiers([...modifiers]).join("+")}+${keyName}` : keyName;

@@ -1212,5 +1320,5 @@ return output.length > 1 ? output : "";

b.weight ||= 0;
return a.weight === b.weight ? 0 : a.weight > b.weight ? 1 : -1;
return a.weight === b.weight ? 0 : b.weight > a.weight ? 1 : -1;
});
return bindings;
return bindings.filter((b) => b.weight !== -1);
}, "prioritizeKeymap");

@@ -1222,9 +1330,8 @@ var isPrintableCharacter = /* @__PURE__ */ __name((s) => {

// index.ts
var ESC = "\x1B";
var isWindows = globalThis.process.platform === "win32";
var MAX_PASTE_BUFFER = 1024 * 1024;
var ENABLE_PASTE_BRACKET_MODE = `${ESC}[?2004h`;
var DISABLE_PASTE_BRACKET_MODE = `${ESC}[?2004l`;
var ENABLE_MOUSE = `${ESC}[?1003h`;
var DISABLE_MOUSE = `${ESC}[?1003l`;
var ENABLE_PASTE_BRACKET_MODE = `${kEscape}[?2004h`;
var DISABLE_PASTE_BRACKET_MODE = `${kEscape}[?2004l`;
var ENABLE_MOUSE = `${kEscape}[?1003h`;
var DISABLE_MOUSE = `${kEscape}[?1003l`;
var enablePaste = /* @__PURE__ */ __name((stdout2) => {

@@ -1244,9 +1351,9 @@ stdout2.write(ENABLE_PASTE_BRACKET_MODE);

hide: /* @__PURE__ */ __name((stdout2) => {
stdout2.write(`${ESC}[?25l`);
stdout2.write(`${kEscape}[?25l`);
}, "hide"),
show: /* @__PURE__ */ __name((stdout2) => {
stdout2.write(`${ESC}[?25h`);
stdout2.write(`${kEscape}[?25h`);
}, "show"),
position: /* @__PURE__ */ __name((stdout2) => {
stdout2.write(`${ESC}[6n`);
stdout2.write(`${kEscape}[6n`);
}, "position")

@@ -1322,3 +1429,4 @@ };

enablePasteMode = false,
pasteModeTimeout = 100
pasteModeTimeout = 100,
keyboardProtocol = false
}) => {

@@ -1335,2 +1443,3 @@ if (!input || input !== process.stdin && !input.isTTY) {

let pasteTimeout = null;
let disableProtocol = null;
const clearPasteState = /* @__PURE__ */ __name(() => {

@@ -1394,2 +1503,7 @@ pasting = false;

}
const found = keymap.filter((k) => k.sequence === key.sequence);
if (found.length === 1) {
key = { ...key, ...found[0] };
addShortcut = false;
}
const shortcut = key.shortcut ? sortShortcutModifier(key.shortcut) : createShortcut(key);

@@ -1434,2 +1548,3 @@ if (!key.shortcut && hasModifier(key)) {

if (enablePasteMode) disablePaste(output);
if (disableProtocol) disableProtocol();
if (onKeypress) input.off("keypress", handleKeypress);

@@ -1449,2 +1564,6 @@ if (pasteTimeout) clearTimeout(pasteTimeout);

}
resetKeyboardProtocol(output);
if (keyboardProtocol) {
disableProtocol = enableKeyboardProtocol(detectTerminal(), output);
}
if (!isWindows && input.isTTY) input.setRawMode(true);

@@ -1470,4 +1589,9 @@ if (hideCursor) cursor.hide(output);

var { emitKeypress } = createEmitKeypress();
var emit_keypress_default = emitKeypress;
var index_default = emitKeypress;
export {
DISABLE_MOUSE,
DISABLE_PASTE_BRACKET_MODE,
ENABLE_MOUSE,
ENABLE_PASTE_BRACKET_MODE,
MAX_PASTE_BUFFER,
NON_PRINTABLE_CHAR_REGEX,

@@ -1478,3 +1602,3 @@ PRINTABLE_CHAR_REGEX,

cursor,
emit_keypress_default as default,
index_default as default,
disableMouse,

@@ -1491,2 +1615,3 @@ disablePaste,

isPrintableCharacter,
isWindows,
keycodes,

@@ -1493,0 +1618,0 @@ metaKeys,

+15
-9
{
"name": "emit-keypress",
"description": "Drop-dead simple keypress event emitter for Node.js. Create powerful CLI applications and experiences with ease.",
"version": "1.0.1",
"version": "2.0.0",
"main": "dist/index.js",

@@ -9,3 +9,6 @@ "module": "dist/index.mjs",

"author": "Jon Schlinkert (https://github.com/jonschlinkert)",
"repository": "enquirer/emit-keypress",
"repository": {
"type": "git",
"url": "git+https://github.com/enquirer/emit-keypress.git"
},
"bugs": {

@@ -23,14 +26,17 @@ "url": "https://github.com/enquirer/emit-keypress/issues"

},
"dependencies": {
"detect-terminal": "^2.0.0"
},
"devDependencies": {
"@types/node": "^20.12.7",
"@typescript-eslint/eslint-plugin": "^7.13.1",
"@typescript-eslint/parser": "^7.13.1",
"@types/node": "^24.10.1",
"@typescript-eslint/eslint-plugin": "^8.48.1",
"@typescript-eslint/parser": "^8.48.1",
"ansi-colors": "^4.1.3",
"esbuild-register": "^3.5.0",
"esbuild-register": "^3.6.0",
"eslint": "^8.57.0",
"gulp-format-md": "^2.0.0",
"prettier": "^3.5.3",
"ts-mocha": "^10.0.0",
"prettier": "^3.7.4",
"ts-mocha": "^11.1.0",
"tsconfig-paths": "^4.2.0",
"tsup": "^8.0.2"
"tsup": "^8.5.1"
},

@@ -37,0 +43,0 @@ "keywords": [

+131
-2

@@ -25,3 +25,3 @@ # emit-keypress [![NPM version](https://img.shields.io/npm/v/emit-keypress.svg?style=flat)](https://www.npmjs.com/package/emit-keypress) [![NPM monthly downloads](https://img.shields.io/npm/dm/emit-keypress.svg?style=flat)](https://npmjs.org/package/emit-keypress) [![NPM total downloads](https://img.shields.io/npm/dt/emit-keypress.svg?style=flat)](https://npmjs.org/package/emit-keypress)

It's lightweight, no dependencies, easy to use, and easy to customize. It's designed to be used in a wide range of use-cases, from simple command-line utilities to complex terminal applications.
It's lightweight with only one dependency for detecting the terminal. It's easy to use, and easy to customize. It's designed to be used in a wide range of use-cases, from simple command-line utilities to complex terminal applications.

@@ -144,2 +144,131 @@ Powerful CLI applications can be built with this module.

### onMousepress
Pass an `onMousepress` function to handle mouse events. When provided, mouse tracking is automatically enabled.
```ts
emitKeypress({
onKeypress: (input, key, close) => {
console.log('key:', key);
},
onMousepress: (mouse, close) => {
console.log('mouse:', mouse);
// mouse.x, mouse.y, mouse.button, mouse.action, etc.
}
});
```
### Paste Mode
Enable bracketed paste mode to handle multi-line pastes as a single event.
```ts
emitKeypress({
enablePasteMode: true,
pasteModeTimeout: 100, // timeout in ms
maxPasteBuffer: 1024 * 1024, // 1MB limit
onKeypress: (input, key, close) => {
if (key.name === 'paste') {
console.log('pasted:', key.sequence);
}
}
});
```
### Enhanced Keyboard Protocol
Enable the Kitty or modifyOtherKeys keyboard protocol for better key detection in supported terminals.
```ts
emitKeypress({
keyboardProtocol: true,
onKeypress: (input, key, close) => {
// Enhanced key reporting with better modifier detection
console.log({ input, key });
}
});
```
Supported terminals include: kitty, alacritty, foot, ghostty, iterm, rio, wezterm (Kitty protocol), and windows_terminal, xterm, gnome_terminal, konsole, vscode, xfce4_terminal, mate_terminal, terminator (modifyOtherKeys protocol).
### Cursor Control
Control cursor visibility and get cursor position.
```ts
import { cursor, emitKeypress } from 'emit-keypress';
// Hide/show cursor
cursor.hide(process.stdout);
cursor.show(process.stdout);
// Or use the hideCursor option
emitKeypress({
hideCursor: true,
onKeypress: (input, key, close) => {
// cursor is automatically shown when close() is called
}
});
// Get initial cursor position
emitKeypress({
initialPosition: true,
onKeypress: (input, key, close) => {
if (key.name === 'position') {
console.log('cursor at:', key.x, key.y);
}
}
});
```
### Options
| Option | Type | Default | Description |
| --- | --- | --- | --- |
| `input` | `ReadStream` | `process.stdin` | Input stream to listen on |
| `output` | `WriteStream` | `process.stdout` | Output stream for escape sequences |
| `keymap` | `Array` | `[]` | Custom key mappings |
| `onKeypress` | `Function` | required | Keypress event handler |
| `onMousepress` | `Function` | `undefined` | Mouse event handler (enables mouse tracking) |
| `onExit` | `Function` | `undefined` | Called when the stream closes |
| `escapeCodeTimeout` | `number` | `500` | Timeout for escape sequences (ms) |
| `handleClose` | `boolean` | `true` | Register cleanup on process exit |
| `hideCursor` | `boolean` | `false` | Hide cursor while listening |
| `initialPosition` | `boolean` | `false` | Request initial cursor position |
| `enablePasteMode` | `boolean` | `false` | Enable bracketed paste mode |
| `pasteModeTimeout` | `number` | `100` | Paste mode timeout (ms) |
| `maxPasteBuffer` | `number` | `1048576` | Max paste buffer size (bytes) |
| `keyboardProtocol` | `boolean` | `false` | Enable enhanced keyboard protocol |
### createEmitKeypress
Create an isolated instance with its own exit handlers.
```ts
import { createEmitKeypress } from 'emit-keypress';
const { emitKeypress, onExitHandlers } = createEmitKeypress({
setupProcessHandlers: true
});
```
## History
### v2.0.0
* Added `onMousepress` option for mouse event handling with automatic mouse tracking
* Added bracketed paste mode support (`enablePasteMode`, `pasteModeTimeout`, `maxPasteBuffer`)
* Added enhanced keyboard protocol support for Kitty and modifyOtherKeys (`keyboardProtocol` option)
* Added `createEmitKeypress` factory for creating isolated instances with separate exit handlers
* Added `cursor` utilities for hiding/showing cursor and getting position
* Added `initialPosition` option to request cursor position on start
* Added `hideCursor` option for automatic cursor visibility management
* Added `onExit` callback option
* Added CSI u (Kitty) and modifyOtherKeys protocol parsing for better modifier key detection
* Added `fn` modifier support to key objects
* Added automatic terminal detection for keyboard protocol selection
* Added `keycodes` export with comprehensive key sequence mappings
* Improved exit handler management with WeakMap-based session counting
* Improved cleanup: protocols are reset, mouse/paste modes disabled on close
## About

@@ -193,2 +322,2 @@

_This file was generated by [verb-generate-readme](https://github.com/verbose/verb-generate-readme), v0.8.0, on February 05, 2025._
_This file was generated by [verb-generate-readme](https://github.com/verbose/verb-generate-readme), v0.8.0, on December 10, 2025._

Sorry, the diff of this file is too big to display

Sorry, the diff of this file is too big to display