Genkey Docs

Table of Contents

Basic Usage

Genkey is a command line tool. This means that you perform actions by running the binary through the terminal.

The binary is called genkey.exe on Windows, or simply genkey on Linux or MacOS. From now on, the binary will just be referred to as genkey, so if you're using Windows, make sure to correct it. Also note that you can autocomplete with TAB, in the likely case that you don't want to type out the full name every time.

The general format of commands looks like this:

./genkey COMMAND ARGUMENT

Layouts

Layouts are stored as basic text files in the layouts subdirectory. Here is an example of its format, using the unholy layout as reference.

QWERTY
q w e r t y u i o p [ ] 
a s d f g h j k l ; '
z x c v b n m , . /
0 1 2 3 3 4 4 5 6 7 7 7 7
0 1 2 3 3 4 4 5 6 7 7
0 1 2 3 3 4 4 5 6 7 

The first line is used as the name of the layout - the name of the file is not used by the program. Note that if two files have the same layout name, only one will show up; the program will output no error if this happens, so make sure that you rename it!

The next block of lines is the layout itself. This is pretty much self-explanatory. However, at the moment genkey only supports 3 rows, adding more will confuse it.

The final block defines what finger is used to hit each key. Each finger, not including thumbs, is a digit from 0 to 7. Left pinky is 0, right pinky is 7, and everything in between follows the order you would expect. Thumb keys are not supported in genkey, but Apsu's fork does add experimental support.

generate

The _generate layout file is used to define the fingermap for layouts created with the generate function. In addition, the main key block can be used to pin keys for the improve function. Free keys are labeled with *, and pinned keys are labeled with X.

Weighting

The weights that determine how layouts are scored is configured in weights.hjson. Though the base weights are made to be an okay starting point, you are intended to experiment with them and shape them to your liking.

The "score" is a very arbitrary number that should not be considered an actual indicator of a layout's "objective" quality. The score is calculated from the user's approximations of their personal preferences. Anything that comes from personal preference can't be objective, so do not treat it as such. Beating some layout's score is great, but that doesn't mean it's actually better.

Note: higher score is worse, lower score is better.

Distance

This is the way to calculate distance between any two given keys on a layout.

Where l is the lateral movement multiplier, the expression for weighted distance is as follows:

\[ (l \times \Delta{x}^2) + (\Delta{y}^2) \]

This is the formula for distance, except not square rooted as to treat distance exponentially.

Finger Speed

At a high level, finger speed is basically just looking at bigrams and skipgrams with an adaptation of the rate equation:

\[ r=\frac{d}{n} \]

d is the distance between the two keys. n is the 'length' of the skip-gram, or how the distance between characters in the sequence. For a bigram, n is 1. For a skip-1-gram, (e.g. t_e in the) n is 2.

This equation effectively results in a time required to move a finger from one key to another. Finger speed as a metric is the average of all these times.

However, in reality there are more factors that affect this time. Namely, different fingers differ greatly in how fast they can be moved. Because of this, genkey has a KPS array, which defines how dexterous each finger is. KPS stands for "keys per second", which is what the numbers were originally based on.

In addition, though it would theoretically work out that a skip-1-gram has exactly twice the time to travel as a bigram, some people care about skipgrams less than others. Because of this, genkey allows you to weight it.1

Also, a KeyTravel weight is provided, which can help avoid the problem of double letters (e.g. oo) having 0 distance, and thus not being counted at all. It's used as a baseline value for distance.

Considering these factors, the equation for a pair of keys ends up more like the following (where k is key travel, F is the finger's dexterity, and c is the count of how many times the pair appears):

\[ r=c \times \frac{(d+k)\times F}{n} \]

Genkey then gets the average time all of these same-finger pairs. The lower that this metric is, the better. Though the original idea for this was to be able to calculate how fast your fingers need to move to maintain a given wpm, (hence the name) it is in reality much more complicated than this. It's still a very useful metric, but take it with a grain of salt.

Index Balance

This is a very simple metric that punishes one index finger being used much more than the other. It's just the expression \[ |l-r| \] where l and r are left and right index usage respectively. Increasing the weight increases its addition to the score.

LSB

LSB stands for Lateral Stretch Bigram. It refers to any adjacent finger bigram where \[ \Delta x \ge 2 \]. This typically is used to mean bigrams between index and middle fingers, but genkey also includes pinky and ring in this calculation. More is worse, so increasing the weight value increases how much it affects the score.

Trigrams

Genkey uses trigrams to calculate rolls, alternation, redirects, and onehand rolls.

The TrigramPrecision value determines how many of the most common trigrams are used for this calculation. Since there are far more trigrams than SFBs, the calculation slows down generation a lot, so you probably don't want to use all of them. However, if you do, you can set the value to 0. Otherwise, setting the value to -1 disables the calculation.

Rolls

Rolls are defined as 2 (not-same-finger) keys typed on one hand, following or preceding 1 key pressed on the other. An inward roll is where the direction of the 2 keys on the same hand approaches the index, whereas an outward roll approaches the pinky. Since rolls are generally desired, they subtract from the score.

Alternation

Alternates are defined as trigrams where each key in the sequence switches hands. Since alternation is generally desired, it subtracts from the score.

Redirects

Redirects are defined as trigrams where all keys are on the same hand, but they do not all follow the same direction. For example, sfd would be a redirect on QWERTY, because the direction of sf is inward, but the direction of fd is outward. Since redirects are generally undesired, they add to the score.

Onehands

Onehand rolls are defined as trigrams where all keys are on the same, and they all follow the same direction. For example, sdf on QWERTY would be a onehand roll. Since onehands are generally desired, they subtract from the score.

Commands

Load

Usage: ./genkey load FILEPATH

This takes in a text file path, processes it as a corpus, and updates data.json according to the text data that it collects. This bigram and trigram frequency data is used for all other functions of the program.

Rank

Usage: ./genkey r

Outputs a ranked list of layouts next to their scores.

Analyze

Usage: ./genkey a LAYOUT

Outputs detailed analysis of a layout.

Generate

Usage: ./genkey g

Generate simply creates a new layout, and tries to minimize score. How long this takes varies, but calculating trigrams significantly increases the time. Otherwise, how long it takes is probably most dependent on your CPU's multicore efficiency.

Improve

Usage: ./genkey improve LAYOUT

Attempts to optimize the score of the given layout, without moving the pinned keys (see *generate).

Interactive

Usage: ./genkey i LAYOUT

The interactive mode is one of the more powerful parts of genkey. It gives you tools to easily modify a layout and see the effects in real-time. It's a fast and dynamic way to approach layout creation.

Swap

Usage: s key1 key2

Swaps two letters with each other.

Example: s a b

Column Swap

Usage: cs key1 key2 or cs col1 col2

Swaps two columns with each other. If you provide a key, then it targets the column where that key is located. If you provide a number, it targets the column corresponding to that number.

Examples:

  • cs a b
  • cs 0 1

Suggest

Usage: g

Provides a suggestion of what two keys to swap. It does this with a superficial neighbor search. It reports what score it will immediately result in, and what score it can lead to.

Save

Usage: save

Asks you for a layout name, and writes the file. If the name is already taken, you'll be asked if you want to overwrite it.

Quit

Usage: q

Is an explanation for this necessary

Footnotes:

1

When semi came up with the finger speed concept, they coined the term "disjointed bigram". Though a fancy sounding name, skipgram is an already existing term that fits better. Despite this, DSFB ("disjointed same-finger bigram") is still used relatively frequently, which is why it's called that in genkey.

Emacs 29.4 (Org mode 9.6.15)