Skip to main content

Tools for working with TEX Shinobi keyboard keymap files

Project description

TEX Shinobi Keymap Tools

Python tools for working with TEX Shinobi keyboard keymap files (.TEX format).

Features

  • Parse binary .TEX keymap files into a format-agnostic Keymap model.
  • Convert between .TEX and a human-readable YAML format.
  • Render an ASCII visualisation of the layout, with per-profile / per-layer views.
  • Emulate the keyboard at a REPL to test how a keymap behaves before flashing.
  • Dump and diff .TEX binaries with annotated hex output.
  • Byte-equal round-trip with the .TEX output of TEX's web configurator (including its padding and ghost-row quirks).

Installation

pip install -e .

This installs the shinobi-keymap command.

Quick Start

# Inspect a binary keymap
shinobi-keymap ascii KEYMAP.TEX --layout ANSI

# Convert it to editable YAML
shinobi-keymap convert KEYMAP.TEX --layout ANSI -o keymap.yaml

# Edit keymap.yaml, then write a new binary
shinobi-keymap convert keymap.yaml -o NEW_KEYMAP.TEX

CLI Commands

shinobi-keymap convert

Convert between .TEX and YAML. Input/output formats are inferred from the file extension; pass --from / --to to override.

# .TEX -> YAML (stdout)
shinobi-keymap convert KEYMAP.TEX --layout ANSI

# .TEX -> YAML (file)
shinobi-keymap convert KEYMAP.TEX --layout ANSI -o keymap.yaml

# YAML -> .TEX
shinobi-keymap convert keymap.yaml -o KEYMAP.TEX

Options:

  • --layout {ANSI,ISO,JIS} -- required when reading .TEX.
  • -o, --output FILE -- output path; format inferred from extension.
  • --from {yaml,tex} -- explicit input format.
  • --to {yaml,tex} -- explicit output format.

shinobi-keymap ascii

Render an ASCII visualisation of a keymap, or of the tool's defaults.

shinobi-keymap ascii keymap.yaml
shinobi-keymap ascii KEYMAP.TEX --layout ANSI

# Filter by profile/layer
shinobi-keymap ascii keymap.yaml --profile 1 --layer fn1

# Reference views (no input file needed)
shinobi-keymap ascii --key-names --layout ANSI
shinobi-keymap ascii --key-ids --layout ANSI
shinobi-keymap ascii --key-matrix --layout ANSI
shinobi-keymap ascii --show-default --layout ANSI

shinobi-keymap emulate

Interactive REPL for exercising a keymap.

shinobi-keymap emulate KEYMAP.TEX --layout ANSI
shinobi-keymap emulate keymap.yaml --profile profile2

REPL commands:

  • press KEY -- press and hold a key
  • release KEY -- release a held key
  • tap KEY... -- press and release keys in sequence
  • state -- show current layer and held keys
  • reset -- reset emulator
  • quit / Ctrl+D -- exit

TAB completion is available for key names.

shinobi-keymap dump

Annotated hex dump of a .TEX file.

shinobi-keymap dump KEYMAP.TEX --layout ANSI
shinobi-keymap dump KEYMAP.TEX --layout ANSI --diffable

shinobi-keymap diff

Diff two .TEX files via their annotated dumps.

shinobi-keymap diff KEYMAP1.TEX KEYMAP2.TEX --layout ANSI

shinobi-keymap actions

Print every action name usable on the right side of a YAML binding (or inside a macro key:), one per line. Names are clustered by keycode group (so e.g. F1..F12 and NUM_* stay together); pipe to sort for alphabetical order or to grep to search.

shinobi-keymap actions | grep -i vol

YAML Format

The YAML format is sparse: only overrides of the layout's default keymap are listed. Each of the three profiles is emitted (possibly as {}); within a profile, only layers with overrides appear, and within a layer, only keys that differ from the cascade.

version: 1
layout: ANSI
profiles:
  profile1:
    base:
      CAPS_LOCK: ESC        # CapsLock -> Escape
      PGUP: END             # PgUp acts as End
    fn1:
      H: M_hi               # FN1 + H types "hi"
  profile2: {}
  profile3: {}
macros:
  hi:
  - action: press
    key: H
  - action: release
    key: H
  - action: press
    key: I
  - action: release
    key: I

Key points

  • Physical key names -- A, ESC, L_SHIFT, G12, etc. instead of matrix indices. For the list of valid LHS keys, run shinobi-keymap ascii --key-names --layout ANSI (or --layout ISO / JIS), or see the "Matrix Index Reference" section of docs/TEX_FORMAT.md; for the list of valid RHS action names, run shinobi-keymap actions, or see the "Action-Only Keycodes" section of docs/TEX_FORMAT.md.
  • Sparse layers -- anything matching the layout default is omitted.
  • Cascade -- on read, an unset fn1/fn2/fn3 slot for a key falls back to that key's base value (which itself falls back to the layout default).
  • Special action values:
    • FN1 / FN2 / FN3 on base make a key a layer trigger.
    • NONE means "no binding" (suppresses the cascade for that slot).
    • M_<name> references a macro defined under macros:.
  • Macro events are action: press|release, key: <action-keycode>, optional delay: (milliseconds to wait after the event). delay: 0 may be omitted.
  • compat: block -- optional, used to preserve quirks of TEX's web configurator (padding, ghost rows, fn-position ordering) for byte-equal round-trips. Hand-written keymaps don't need it.

Python API

from shinobi_keymap import (
    Keymap, KeyBinding,
    keyinfo_from_name, keyaction_from_name,
)
from shinobi_keymap import tex_reader, tex_writer, yaml_reader, yaml_writer

# Load
keymap = tex_reader.read("KEYMAP.TEX", layout="ANSI")
# or
keymap = yaml_reader.read("keymap.yaml")

# Inspect / modify
caps = keyinfo_from_name("CAPS_LOCK")
keymap.bindings[caps] = {
    1: KeyBinding(base=keyaction_from_name("ESC")),
}

# Save
yaml_writer.dump(keymap, "out.yaml")
tex_writer.dump(keymap, "out.TEX")

Keymap.bindings is keyed KeyInfo -> {profile_id: KeyBinding}, where profile_id is 1, 2, or 3. A KeyBinding has either a non-None fn_role (making the key a layer trigger) or up to four layer slots (base, fn1, fn2, fn3), each holding a KeyAction, a MacroAction, or None.

Development

pip install -e '.[dev]'
pytest

See docs/TEX_FORMAT.md for the binary format reference.

License

GPL-2.0-or-later

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

shinobi_keymap-0.1.0.tar.gz (283.7 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

shinobi_keymap-0.1.0-py3-none-any.whl (44.0 kB view details)

Uploaded Python 3

File details

Details for the file shinobi_keymap-0.1.0.tar.gz.

File metadata

  • Download URL: shinobi_keymap-0.1.0.tar.gz
  • Upload date:
  • Size: 283.7 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for shinobi_keymap-0.1.0.tar.gz
Algorithm Hash digest
SHA256 82aade98729bd1bf388d67fa129c327959be3a1596be602133018609d946807a
MD5 e142c84751e2a9d091263e60bc47eb9b
BLAKE2b-256 449d279c1202fd9dbf4ca7484dfe2ed4cc8fc2f325f2eddf9e89aa51da54c0de

See more details on using hashes here.

Provenance

The following attestation bundles were made for shinobi_keymap-0.1.0.tar.gz:

Publisher: publish.yml on gabifalk/shinobi-keymap

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file shinobi_keymap-0.1.0-py3-none-any.whl.

File metadata

  • Download URL: shinobi_keymap-0.1.0-py3-none-any.whl
  • Upload date:
  • Size: 44.0 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for shinobi_keymap-0.1.0-py3-none-any.whl
Algorithm Hash digest
SHA256 5392acc73c2d7450f1441a8fe1cb96843ad8bd7e0a30d5e092922b8664a464aa
MD5 e87449f19152e3a4d5ddb85ca6980d8a
BLAKE2b-256 1bb53278b6328e4100c7fd57848cca4dd1288acd46192215b21d284bf18784e5

See more details on using hashes here.

Provenance

The following attestation bundles were made for shinobi_keymap-0.1.0-py3-none-any.whl:

Publisher: publish.yml on gabifalk/shinobi-keymap

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page