chkb turns a regular keyboard into a fully programmable keyboard. It is a cheap programmable keyboard

chkb Go Report Card coveralls. Coverage Status Go Reference

chkb turns a regular keyboard intro a fully programmable keyboard.

So you basically get a cheap programmable keyboard.

It has been inspired by QMK firmware and kmonad.

Usage

This applies to the current preview version, this will change in the future but I will try to keep this info updated.

ATTENTION: if you manage to block your keyboard, hold ESC and the application will quit. This is a safe guard and cannot be disabled and is handled before any key event.

create a keys.yaml with at least a base layer keyMap.

layers:
  base:
    keyMap:

find the input file from your keyboard. This files are located at /dev/input/by-id/. The id should be enough to tell which one is your keyboard. if not, you can sudo cat /dev/input/by-id/file and see if you can see data when you type on your keyboard.

To avoid sudo, you can add your user to the input group.

sudo usermod -a -G input $USER

chkb needs access to /dev/uinput in order to generate key events. You can create a rule for this. so you don't need sudo.

Extracted from here: https://github.com/bendahl/uinput

echo KERNEL==\"uinput\", GROUP=\"$USER\", MODE:=\"0660\" | sudo tee /etc/udev/rules.d/99-$USER.rules
sudo udevadm trigger

Run chkb from the directory containing this file providing as first parameter the path to your device. If everything works, you should see a message push layer base which means that everything is running. You can start typing to see some captured events.

./chkb -i /dev/input/by-id/usb-Logitech_USB_Receiver-if01-event-kbd
# TIP add -v flag for debug info

Remap keys

This example remaps the CAPSLOCK to LEFTMETA. This means that pressing caps will behave as if you've pressed leftmeta.

layers:
  base:
    keyMap:
      KEY_CAPSLOCK:
        Map:
          - keyCode: KEY_LEFTMETA

Change Layer

A layer modifies how your keys behave. Base layer is pushed at startup and cannot be removed but it can be changed. Just make sure that you always have a way to move between layers or you will be stuck.

Move between base and control layers

layers:
  base:
    keyMap:
      KEY_CAPSLOCK:
        Tap:
          ## Change base layer for control layer
          - action: ChangeLayer
            layerName: control

  control:
    keyMap:
      KEY_CAPSLOCK:
        Tap:
          ## Go back to base 
          - action: ChangeLayer
            layerName: base

Push/Pop layers

You can push other layers to extend the functionality of the base layer. The layers are push into a stack and read from top to down. Once the event is handled by a layer, the next layers do not receive it. Most users will be fine using only ChangeLayer. but this is still an interesting feature to modify only parts of your keyboard.

swap AB keys

This example shows how to create a layer that temporally swaps keys AB

layers:
  base:
    keyMap:
      KEY_CAPSLOCK:
        # Tap means to press and release in less than 200ms
        Tap:
          # PushLayer requires the layer name to push that must match with yaml key
          - action: PushLayer
            layerName: swapAB
  # definition of swapAB layer
  swapAB:
    keyMap:
      # swap A
      KEY_A:
          - keyCode: KEY_B
      # swap B
      KEY_B:
          - keyCode: KEY_A
      # remove the layer if caps is tapped again,
      # as this event is handled by swapAB layer, 
      # base layer wont trigger the Tap action
      KEY_CAPSLOCK:
        Tap:
          - action: PopLayer
            layerName: swapAB

Tap / Hold

You can capture special events like tap/hold and perform custom actions

CAPSLOCK on SHIFT hold

This will tap CAPSLOCK if you hold LEFTSHIFT

layers:
  base:
    keyMap:
      KEY_LEFTSHIFT:
        Hold:
          - action: Tap
            keyCode: KEY_CAPSLOCK

Multiple maps

There are cases where you want to do multiple actions with a single input event. You may have noticed that the Keyboard events are a list, This means you can use as many as you need.

Pop layer and push another

This example shows how to enable a control layer that allows you to jump to another layer

layers:
  base:
    keyMap:
      KEY_CAPSLOCK:
        Tap:
          - action: PushLayer
            layerName: control
        Map:
          - keyCode: KEY_LEFTMETA

  ## Intermediate layer
  control:
    keyMap:
      KEY_CAPSLOCK:
        ## Go back to base
        Tap:
          - action: PopLayer
            layerName: control
        ## Ensure key still works as a meta key
        Map:
          - keyCode: KEY_LEFTMETA
      KEY_A:
        # If tap A, pop this layer and push arrows layer
        Tap:
          - action: PopLayer
            layerName: control
          - action: PushLayer
            layerName: arrows
        # Block a key so it doesn't type anything
        Map:
          - action: Nil
  arrows:
    keyMap:
      KEY_CAPSLOCK:
        ## Go back to base by poping arrows layer
        Tap:
          - action: PopLayer
            layerName: arrows
        ## Ensure key still works as a meta key
        Map:
          - keyCode: KEY_LEFTMETA

      ## Put arrows on hjkl vim style
      KEY_J:
        Map:
          - keyCode: "KEY_DOWN"
      KEY_K:
        Map:
          - keyCode: "KEY_UP"
      KEY_H:
        Map:
          - keyCode: "KEY_LEFT"
      KEY_L:
        Map:
          - keyCode: "KEY_RIGHT"

onMiss

onMiss event is triggered on keydown if a key contains no mapping in the current layer. It is useful to automatically leave a layer if you press something that it is not mapped. By default, the keydown event stops on the current layer, if you want to propagate it, you have to add the Map action to the onMiss action list

layers:
  base:
    keyMap:
      KEY_CAPSLOCK:
        Tap:
          - action: ChangeLayer
            layerName: control

  control:
    onMiss:
      ## If you press a non mapped key...
      Tap:
        ## Go back to base
        - action: ChangeLayer
          layerName: base
        ## And forward the down even to base layer
        - action: Map
    keyMap:
      ## (keymaps...)

Available key events

key events are used to capture events from your keyboard and map them into other keyboard events.

layers:
  base:
    keyMap:
      KEY_LEFTSHIFT:
        Hold: <--- This is the key event
          - action: Tap
            layerName: KEY_CAPSLOCK
  • Map: Forwards the up/down events to a different key
  • Down: On key down
  • Up: On key up
  • Tap: press and release in less than 200ms, no other keys are pressed in between
  • DoubleTap: tap twice!
  • Hold: keep the key down for more than 200ms or press another key while it is down.

Available keyboard events

These events are the ones generated by the keyMaps.

layers:
  base:
    keyMap:
      KEY_LEFTSHIFT:
        Hold: 
          - action: Tap  <--- This is a Keyboard Event
            layerName: KEY_CAPSLOCK 
  • Nil: does nothing
  • Map: Forwards the up/down events to a different key // Default behaviour
    • keyCode: Key used
  • Down: Simulate key up
    • keyCode: Key used
  • Up: Simulate key down
    • keyCode: Key used
  • Tap: press and release in less than 200ms
    • keyCode: Key used
  • DoubleTap: tap twice!
    • keyCode: Key used
  • Hold: press until the keyboard repeats the event
    • keyCode: Key used
  • PushLayer: push a layer into the stack
    • layerName: name of the layer
  • PopLayer: removes a layer from the stack
    • layerName: name of the layer
  • ChangeLayer: The base layer will be replaced
    • layerName: name of the layer

Keycodes

If you tap a key, you will see the code printed in the chkb log. This way you can find the name of any key from your keyboard.

To find extra keys, you can read ./pkg/chkb/ecodes.go and use anything starting with KEY_. This keys are just standard keycodes and you can also find them in linux source code /usr/include/linux/input-event-codes.h

TODO

  • integrate with cobra cli
  • allow to specify the location of the config file
  • Allow to disable layerFile functionality
  • extract tapDelay to configuration
  • implement testing run mode. just to see keypresses and final maps
  • easy autoshift functionality for layers
  • examples
  • Implement RESETKEY to start-stop the app in the background
  • add initialLayer as a configuration parameter
Owner
Victor
Gophers, are burrowing rodents. They are commonly known for their extensive tunnelling activities, their ability to destroy gardens and the Go programming skils
Victor
Similar Resources

Keyboard-firmware - Go Keyboard Firmware framework

Go Keyboard Firmware framework This is an experimental project that I am using t

Dec 31, 2022

User programmable screen overlay using web technologies

User programmable screen overlay using web technologies

Topframe User programmable screen overlay using web technologies Display information and always-on-top widgets Use HTML/JS/CSS to draw on your screen

Dec 29, 2022

A programmable, observable and distributed job orchestration system.

A programmable, observable and distributed job orchestration system.

📖 Overview Odin is a programmable, observable and distributed job orchestration system which allows for the scheduling, management and unattended bac

Dec 21, 2022

Mmpxmas-go - ModMyPi Programmable Christmas Tree examples written in Go with go-rpio

ModMyPi Programmable Christmas Tree examples in Go This small program contains examples similar to the examples provided by ModMyPi for interacting wi

Jan 4, 2022

KubeOrbit is an open-source abstraction layer library that turns easy apps testing&debuging on Kubernetes in a new way

KubeOrbit is an open-source abstraction layer library that turns easy apps testing&debuging on Kubernetes in a new way

KubeOrbit is an open-source abstraction layer library that turns easy apps testing&debuging on Kubernetes in a new way

Jan 6, 2023

🍫 A collection of common regular expressions for Go

CommonRegex A collection of often used regular expressions for Go Inspired by CommonRegex This is a collection of often used regular expressions. It p

Dec 31, 2022

An extremely fast Go (golang) HTTP router that supports regular expression route matching. Comes with full support for building RESTful APIs.

ozzo-routing You may consider using go-rest-api to jumpstart your new RESTful applications with ozzo-routing. Description ozzo-routing is a Go package

Dec 31, 2022

rxscan provides functionality to scan text to variables using regular expression capture group.

rxscan rxscan provides functionality to scan text to variables using regular expression capture group. This library is still experimental, use at your

Dec 21, 2020

A tool and library for using structural regular expressions.

Structural Regular Expressions sregx is a package and tool for using structural regular expressions as described by Rob Pike (link).

Dec 7, 2022

A command-line tool and library for generating regular expressions from user-provided test cases

A command-line tool and library for generating regular expressions from user-provided test cases

Table of Contents What does this tool do? Do I still need to learn to write regexes then? Current features How to install? 4.1 The command-line tool 4

Jan 9, 2023

A CLI tool that you can use create regular backups of your Notion.so Pages.

notion-offliner A CLI tool that you can use create regular backups of your Notion.so Pages. Perfect for disaster scenarios and offline usage. MacOS an

Jan 3, 2023

Compile Go regular expressions to Go code

regexp2go regexp2go is an alternate backend for the regexp package that allows to perform ahead-of-time compilation of regular expressions to Go code.

Jul 11, 2022

Machine-readable regular expressions for identifying accession numbers for cultural heritage organizations in text.

Machine-readable regular expressions for identifying accession numbers for cultural heritage organizations in text.

Jun 14, 2022

This image is primarily used to ping/call a URL on regular intervals using Kubernetes (k8s) CronJob.

A simple webhook caller This image is primarily used to ping/call a URL on regular intervals using Kubernetes (k8s) CronJob. A sample job would look s

Nov 30, 2021

run regular Docker images in KVM/Qemu

runq runq is a hypervisor-based Docker runtime based on runc to run regular Docker images as a lightweight KVM/Qemu virtual machine. The focus is on s

Jan 6, 2023

Converts NFAs (and DFAs) to a regular expressions using the state removal method.

nfa-to-regex: convert NFAs (and DFAs) to regular expressions An implementation of the state removal technique for converting an NFA to a regular expre

Apr 29, 2022

Converts NFAs (and DFAs) to a regular expressions using the state removal method

nfa2regex: convert NFAs (and DFAs) to regular expressions An implementation of the state removal technique for converting an NFA to a regular expressi

Apr 29, 2022

It's so many regular expression forms are difficult to understand, such as perl, python, grep awk

Introduction Jamie Zawinski: Some people, when confronted with a problem, think "I know, I'll use regular expressions." Now they have two problems. It

Mar 31, 2022

Graceful shutdown with repeating "cron" jobs (running at a regular interval) in Go

Graceful shutdown with repeating "cron" jobs (running at a regular interval) in Go Illustrates how to implement the following in Go: run functions ("j

May 30, 2022
Comments
  • When an action list contains down and then up events, up is ignored.

    When an action list contains down and then up events, up is ignored.

      symbols:
        onMiss:
          - action: ChangeLayer
            layerName: base
          - action: Map
        keyMap:
          KEY_U:
            Map: 
              - action: Nil*
            Tap:
              - action: Down
                keyCode: KEY_LEFTSHIFT
              - keyCode: KEY_8
              - action: Up
                keyCode: KEY_LEFTSHIFT
    
  • onMiss is triggered when the key has maps and it shouldn't

    onMiss is triggered when the key has maps and it shouldn't

    Do not triggers miss,  ok
        keyMap:
          KEY_CAPSLOCK:
            Tap:
              - action: ChangeLayer
                layerName: base
            Map:
              - keyCode: KEY_LEFTMETA
    triggers miss,  bad
        keyMap:
          KEY_CAPSLOCK:
            Tap:
              - action: ChangeLayer
                layerName: base
    
Cheap/fast/simple XLSX file writer for textual data

xlsxwriter Cheap/fast/simple XLSX file writer for textual data -- no fancy formatting or graphs go get github.com/mzimmerman/xlsxwriter data := [][]s

Feb 8, 2022
A code generator that turns plain old Go services into RPC-enabled (micro)services with robust HTTP APIs.

Frodo Frodo is a code generator and runtime library that helps you write RPC-enabled (micro) services and APIs. It parses the interfaces/structs/comme

Dec 16, 2022
A code generator that turns plain old Go services into RPC-enabled (micro)services with robust HTTP APIs.

Frodo is a code generator and runtime library that helps you write RPC-enabled (micro) services and APIs.

Dec 16, 2022
Deskreen turns any device with a web browser into a secondary screen for your computer
Deskreen turns any device with a web browser into a secondary screen for your computer

Deskreen Website: https://deskreen.com ▶️ Deskreen Youtube channel (video tutorials, demos, use cases for Deskreen day to day usage) Deskreen turns an

Jan 7, 2023
Jan 3, 2023
Turns any junk text into a usable wordlist for brute-forcing.

haklistgen Turns any junk text into a usable wordlist for brute-forcing. Installation go get -u github.com/hakluke/haklistgen Usage Examples Scrape a

Dec 22, 2022
Wuzzel turns fuzzel into a window picker

wuzzel wuzzel turns fuzzel into a window picker. Description fuzzel is an applic

Oct 13, 2022
Goket (Golang Keyboard Event Tree) is a proof-of-concept code for using keyboard events trees for performing operations.

Goket Goket (Golang Keyboard Event Tree) is a proof-of-concept code for using keyboard events trees for performing operations. Its main goal is to all

Jan 3, 2023
Hw-keyboard-remapper - This is key code remapper for the hardware keyboard

hw-keyboard-remapper hw-keyboard-remapper is key remapper independent the OS. ht

Jan 11, 2022
Keyboard-backlight - A utility for controlling keyboard backlight for System 76 computers

keyboard-backlight A utility for setting keyboard backlight on System 76 devices

Jan 12, 2022