term-keymap
v0.2.5
Published
Parse stdin buffers into readable data and assign keymaps.
Downloads
973
Maintainers
Readme
term-keymap
Parses raw keyboard and mouse stdin buffers in Node and returns structured data. Provides a flexible keymap API with support for dynamically assigning and removing keymaps at runtime.
Supports a wide range of key combinations, mouse actions, and full compatibility with the Kitty Keyboard Protocol
Key features:
- Comprehensive Key Combination: Parses
ctrlandaltcombinations by default. - Kitty Keyboard Protocol Support: Enables extended combinations if
supported by the terminal (e.g.
ctrl+ uppercase characters,super,meta, volume keys). - Dynamic Keymap API: Subscribe/unsubscribe individual keymaps at runtime. Supports sequences, leader/prefix keys, optional callbacks and names.
- Mouse Support: movement, buttons, scroll, drag, release.
- Vim-style Keymap Strings:
"<C-a><Tab>foo"notation or structured token objects. - Raw Stdin Buffer Parser: Bypass the keymap API and directly use the parsed buffer data if desired.
Documentation & Resources
Quickstart
Matching stateful stdin with keymaps
import { configureStdin, key, KeyMapState } from "term-keymap";
configureStdin({
enableMouse: true,
enableKittyProtocol: true,
})
const state = new KeyMapState({
// Initialize with optional Actions
actions: [
{
keymap: [{ input: "foo" }, { key: "ctrl", input: "d" }],
// can also write as:
//
// // string form
// keymap: "foo<C-d>",
//
// // builder form
// keymap: key.input("foo").ctrl.input("d"),
//
// // expanded token form
// keymap: [{ input: "f" }, { input: "o" }, { input: "o" }, { key: "ctrl", input: "d" }]
callback: () => {
// handler
}
},
// If InputState.process matches <C-c> it will return the Action's name if
// it exists. This provides a different way of handling matched keymaps
{
keymap: "<C-c>",
// keymap: key.ctrl.input("c"),
// keymap: { key: "ctrl", input: "c" },
name: "quit",
},
],
leader: key.input(" "),
});
// Or add an Action directly. KeyMapState.addAction returns a callback to remove it
// (or you can use KeyMapState.removeAction if you have a reference to the Action)
//
// KeyMapState.clearActions() removes all Actions at once
const removeEscAction = state.addAction({
keymap: "<Esc>",
// keymap: { key: "esc" },
// keymap: key.esc,
callback: () => {
// handler
}
});
state.addAction({
keymap: key.leader.input("foo"),
// keymap: "<leader>foo",
// keymap: { leader: true, input: "foo" },
callback: () => {
// handler
}
})
process.stdin.on("data", (buf: Buffer) => {
const { data, name } = inputState.process(buf, actions);
// data provides parsed key/input sets (including ambiguities if any)
// If there is a match, and you chose not to assign a callback, you handle
// the `name` manually here.
if (name === "quit") {
process.exit();
}
if (data.mouse) {
// Handle mouse data here
}
})Handling raw data
parseBufferprovides direct stdin parsing when stateful matching provided byInputStateandActionStoreisn't needed. It returns aDataobject which contains the parsed info.Data.keyandData.inputare extended Set objects with anonly(...values)method for easier matching.
configureStdin({
enableMouse: false,
enableKittyProtocol: true,
});
process.stdin.on("data", (buf: Buffer) => {
console.clear();
const data = parseBuffer(buf);
print(data);
if (data.key.only("backspace")) {
// handler
}
if (!data.key.size && data.input.only("a")) {
// handler
}
if (data.key.only("ctrl") && data.input.only("a")) {
// handler
}
if (data.key.only("ctrl", "alt", "super") && data.input.only("U")) {
// handler
}
if (data.key.only("ctrl") && data.input.only("c")) {
process.exit();
}
});Mouse Data
| Property | Type | Description | |----------|------|-------------| | x | number | 0 based x index of cursor within term window | | y | number | 0 based y index of cursor within term window | | leftBtnDown | boolean | true when left mouse button pressed | | rightBtnDown | boolean | true when right mouse button pressed | | scrollBtnDown | boolean | true when scroll button is down (not the same as scrolling with the scroll wheel) | releaseBtn | boolean | true immediately after releasing any of the trackable mouse button | | scrollUp | boolean | true when scrolling up on the scroll wheel | | scrollDown | boolean | true when scroll down on the scroll wheel | | mousemove | boolean | true when mouse is moving within term window |
