# AFK
[![CI Status](https://github.com/doughsay/afk/workflows/CI/badge.svg)](https://github.com/doughsay/afk/actions)
[![codecov](https://codecov.io/gh/doughsay/afk/branch/master/graph/badge.svg)](https://codecov.io/gh/doughsay/afk)
[![SourceLevel](https://app.sourcelevel.io/github/doughsay/afk.svg)](https://app.sourcelevel.io/github/doughsay/afk)
[![Hex.pm Version](https://img.shields.io/hexpm/v/afk.svg?style=flat)](https://hex.pm/packages/afk)
[![License](https://img.shields.io/hexpm/l/afk.svg)](LICENSE.md)
[![Dependabot Status](https://api.dependabot.com/badges/status?host=github&repo=doughsay/afk)](https://dependabot.com)
A library for modeling the internal state of a computer keyboard. It supports
arbitrary layouts with any number of layers, and outputs a basic 6-key HID
report byte string.
Its intended use is to model the state for keyboard firmware. A work-in-progress
firmware using Nerves is being attempted [over
here](https://github.com/doughsay/keyboard).
## Installation
AFK can be installed by adding `afk` to your list of dependencies in `mix.exs`:
```elixir
def deps do
[
{:afk, "~> 0.1.0"}
]
end
```
## Basic Usage
First, you define a keymap:
```elixir
keymap = [
# Layer 0 (default)
%{
k001: AFK.Keycode.Key.new(:a),
k002: AFK.Keycode.Modifier.new(:left_control),
k003: AFK.Keycode.Layer.new(:hold, 1),
k004: AFK.Keycode.Key.new(:caps_lock)
},
# Layer 1
%{
k001: AFK.Keycode.Key.new(:z),
k002: AFK.Keycode.Modifier.new(:right_super),
k003: AFK.Keycode.None.new(),
k004: AFK.Keycode.Transparent.new()
}
]
```
You can now start a state process using `AFK.State.start_link/2`, by providing a
keymap, an event receiver PID, and a module that implements the `AFK.HIDReport`
behaviour.
```elixir
{:ok, state} =
AFK.State.start_link(
keymap: keymap,
event_receiver: self(),
hid_report_mod: AFK.HIDReport.SixKeyRollover
)
AFK.State.press_key(state, :k003)
AFK.State.press_key(state, :k002)
AFK.State.press_key(state, :k001)
AFK.State.release_key(state, :k002)
# take a look at our process mailbox
:erlang.process_info(self(), :messages)
# {:messages,
# [
# hid_report: <<0, 0, 0, 0, 0, 0, 0, 0>>,
# hid_report: <<128, 0, 0, 0, 0, 0, 0, 0>>,
# hid_report: <<128, 0, 29, 0, 0, 0, 0, 0>>,
# hid_report: <<0, 0, 29, 0, 0, 0, 0, 0>>
# ]}
```
## Future Features
AFK provides a behaviour for defining how to convert the state into a HID
report. Currently only a 6-key rollover implementation is provided, but an N-key
rollover implementation would be a great addition. (Pull requests welcome!)
It may eventually also support more complex interactions, such as sticky keys,
macros, leader keys, etc. These features require a lot more thinking though, as
they will require the state undergoing changes over time.
## Docs
Documentation can be found at [https://hexdocs.pm/afk](https://hexdocs.pm/afk).