Layout TOML Reference
The complete accepted format for independent keyboard layout sources, including boards, layers, behaviors, alternate fingerings, contextual rules, and analysis costs.
Document and metadata#
A layout document describes one independent layout.
Schema version#
schema_version = 1
Selects the layout document format. The only accepted value is 1.
Layout name#
name = "Complete name"
The complete public display name.
Author#
author = "Name"
The person or group credited with the layout.
Languages#
languages = ["en-US"]
Lists every language the layout supports. Each language appears once, using a supported canonical tag. The current accepted tag is en-US.
Author link#
author_link = "https://example.com/"
A public page for the author.
Publication year#
year = 2026
The year the independent layout was first published.
Related links#
[[links]]
Adds source pages, articles, or other relevant links.
[[links]]
href = "https://example.com/layout"
text = "Official page"Related link destination#
links.*.href = "https://example.com/layout"
The destination of one related link.
Related link label#
links.*.text = "Official page"
The visible label for one related link.
Boards and key grids#
ANSI board#
board = "ansi"
Uses the built-in four-row ANSI geometry. key_grid.rows must contain rows of exactly 14, 14, 13, and 12 tokens.
board = "ansi"
[key_grid]
rows = '''
skip skip skip skip skip skip skip skip skip skip skip - skip skip
skip q w e r t y u i o p skip skip skip
skip a s d f g h j k l ; skip skip
lsh z x c v b n m , . / rsh
'''
space = "spc"ANSI fingermap#
fingermap = "standard"
Selects ANSI finger and coordinate assignments without changing the authored physical row order.
ANSI Space thumb#
space_thumb = "left"
Assigns the authored Space key to one thumb. It is invalid without the ANSI space key-grid group.
Parameterized ortho board#
[board]
Builds one or two hands around four home-row finger columns. type must be ortho; column stagger is expressed with y_offset, not a separate board type.
[board]
type = "ortho"
rows_above = 1
rows_below = 1
hands = { left = { outer_columns = 0, inner_columns = 1 }, right = { outer_columns = 0, inner_columns = 1 } }
thumbs = { enabled = true, left = { outer_columns = 0, inner_columns = 0 }, right = { outer_columns = 0, inner_columns = 0 } }Rows above home#
board.rows_above = 1
Sets the number of complete main-key rows above the home row. Use 0 when the board has none.
Rows below home#
board.rows_below = 1
Sets the number of complete main-key rows below the home row. Use 0 when the board has none.
Present hands#
board.hands = { left = {...}, right = {...} }Lists the hands present on the board. At least one of left and right is required; a one-handed board may omit the other.
Hand outer columns#
board.hands.*.outer_columns = 0
Adds columns beyond the pinky home column. A main hand is four home-finger columns wide before inner and outer columns are added.
Hand inner columns#
board.hands.*.inner_columns = 1
Adds columns beyond the index-finger home column. The resulting hand width is outer_columns + 4 + inner_columns.
Column overrides#
board.hands.*.column_overrides = [...]
Supplies per-column changes. The array may be shorter than the hand width; omitted trailing entries use the board row counts and zero offset.
Index 0 is the outermost column on the left hand and the innermost column on the right hand. Use {} for a listed column with no changes.
column_overrides = [ { y_offset = 4 }, {}, { y_offset = -1 }, {}, { y_offset = 2 } ]Column rows above home#
board.hands.*.column_overrides.*.rows_above = 0
Shortens this column above home. It cannot exceed board.rows_above.
Column rows below home#
board.hands.*.column_overrides.*.rows_below = 0
Shortens this column below home. It cannot exceed board.rows_below.
Column vertical offset#
board.hands.*.column_overrides.*.y_offset = -1
Moves every key in this column vertically in quarter-key units. 4 is 1u; positive values move down and negative values move up.
Thumb configuration#
board.thumbs = { enabled = true, left = {...}, right = {...} }Configures the thumb row. Enabled thumbs require one dimensions object for each present hand; disabled thumbs must omit both hand objects.
Thumb keys enabled#
board.thumbs.enabled = true
Controls whether the board has physical thumb keys. When true, key_grid.rows ends with one combined thumb row; when false, that row is absent.
Thumb hand dimensions#
board.thumbs.left | board.thumbs.right
Describes one hand’s thumb cluster. Its presence must match the corresponding main hand when thumbs are enabled.
Thumb outer columns#
board.thumbs.*.outer_columns = 0
Adds thumb keys on the pinky side of the home thumb. A thumb cluster has one home key before inner and outer columns are added.
Thumb inner columns#
board.thumbs.*.inner_columns = 0
Adds thumb keys on the index side of the home thumb. The resulting cluster width is outer_columns + 1 + inner_columns.
Key grid#
[key_grid]
Whitespace-delimited tokens assign stable IDs to physical slots. Outer blank lines are ignored. Interior blank rows retain their alignment.
skip removes a slot and every corresponding layer binding. Other IDs must be unique; punctuation, Unicode, and numbers are accepted. Key IDs and chord names share one namespace.
Main key-grid rows#
key_grid.rows
Defines the main physical matrix. Ortho boards use this as their only group: main rows come first and, when thumbs are enabled, one combined thumb row comes last.
ANSI rows contain exactly 14, 14, 13, and 12 tokens.
ANSI Space group#
key_grid.space = "spc"
Defines the separate ANSI Space position.
ANSI right-Alt group#
key_grid.right_alt = "alt"
Defines the separate ANSI right-Alt position.
Layers and lookup#
A base layer is required. It is always first; other layers retain their authored order.
Later authored layers have higher precedence. Lookup starts at the highest active layer. An unmapped transparent entry continues to the next lower active layer; inactive layers are skipped. A mapped transparent entry instead reads its named source, which defaults to base and need not be active. The first explicit output, activation, repeat behavior, contextual behavior, or none entry stops ordinary lookup.
Default-form layer#
layers.*.default
literal makes every unbound key output its stable key ID. none makes it produce nothing. transparent inherits from the case-map source on a mapped layer, or continues through lower active layers otherwise.
The base layer cannot contain transparent physical or combo behavior because there is no lower layer.
[layers.base]
default = "literal"
bindings = { lsh = { type = "momentary", layer = "shift" } }
[layers.shift]
default = "transparent"
case_map = "us-english"Grid-form layer#
layers.*.grid
A single string means the rows group. A grouped object must match every nonempty key-grid group and cannot introduce another group.
After key-grid skip slots and completely empty rows are removed, each layer row must have the same number of tokens. Tokens are literal outputs or aliases local to this layer. Every alias must be used.
[layers.symbol]
grid = '''
none none none
excl at hash
'''
bindings = { excl = "!", at = "@", hash = "#" }Layer bindings#
layers.*.bindings.*
With default, keys are stable key IDs. With grid, keys are aliases used by that grid. See Binding behaviors for accepted values.
Layer combo bindings#
layers.*.combos.*
Assigns behavior to a declared chord on this layer.
An omitted combo is opaque none, not inherited. Author { type = "transparent" } explicitly to continue lookup. On a mapped destination, that transparent combo first consults the configured source layer.
Layer inferred keys#
layers.*.inferred = ["minus"]
Records that these physical key positions are absent from the original source on this layer. Every ID must exist in the physical key grid.
This is layer-local metadata, not a behavior change. It does not propagate through transparent lookup or case mapping.
[layers.base]
default = "literal"
inferred = ["minus"]Binding behaviors#
String output and reserved strings#
key = "text"
A plain string emits itself, except: spc emits one space, none is no behavior, ____ is transparent, and skip is valid only in the key grid.
The string transparent emits that word. Use { type = "transparent" } for transparent behavior. To emit any reserved spelling literally, use an output object.
Explicit output#
{ type = "output", value = "text" }Emits a nonempty literal string. This is also the escape for literal reserved text.
Explicit output value#
value = "text"
The nonempty literal text emitted by an output object.
No behavior#
{ type = "none" }Stops lookup and produces no output. The shorthand plain string is none.
Transparent lookup#
{ type = "transparent" }Continues lookup through lower active layers. The grid shorthand is ____.
Without a case map, ordinary lookup continues through lower active layers. On a mapped destination, transparent behavior consults source_layer instead; explicit destination behavior bypasses the source and map.
Layer activation type#
type = "momentary" | "one_shot" | "lock"
momentary keeps a layer active while held. one_shot applies a layer to the next action. lock toggles a layer until the same key or chord toggles it off.
Activation target layer#
layer = "shift"
Names the layer activated by this binding.
Activation anchors#
anchors = "shift_left" | ["a", "b"]
Constrains entry into a momentary or one-shot layer to a named key set or listed stable keys. It does not constrain release. Omission leaves entry unrestricted. Lock activations do not accept anchors.
Repeat and skip-repeat#
{ type = "repeat" | "skip_repeat" }repeat replays the preceding item; skip_repeat replays the item before it.
Repeat kind#
repeat_kind = "output" | "keystroke"
output repeats the text the earlier action produced. keystroke runs that earlier key or chord behavior again, so contextual behavior can be evaluated again.
Tap-hold#
type = "tap_hold"
Branches must use object syntax. A tap accepts output, repeat, skip-repeat, none, blocked, one-shot, or lock activation. A hold accepts output, repeat, skip-repeat, momentary, or lock activation; it does not accept none, blocked, transparent, another tap-hold, or contextual behavior. A contextual rule selects a tap branch with branch = "tap".
e = { type = "tap_hold", tap = { type = "output", value = "e" }, hold = { type = "momentary", layer = "sym" } }Tap-hold tap branch#
tap = {...}Defines the tap action. It accepts explicit output, repeat, skip-repeat, none, blocked, one-shot, or lock activation object syntax.
Tap-hold hold branch#
hold = {...}Defines the hold action. It accepts explicit output, repeat, skip-repeat, momentary activation, or lock activation object syntax. Contextual rules cannot select this branch.
Chords and key sets#
Chord membership#
[chords]
Each chord contains at least two retained stable key IDs. This table defines physical membership only; layers.*.combos defines behavior separately per layer.
Chord names and physical key IDs share one namespace. A chord name cannot duplicate a retained key ID.
[chords]
qu = ["g", "d"]
[layers.base]
default = "literal"
combos = { qu = "qu" }Explicit key set#
key_sets.* = ["a", "b"]
Lists retained physical keys directly. IDs cannot repeat. An empty literal is allowed inside a compound expression, but every complete named key set must resolve to at least one key.
Hand-derived key set#
key_sets.*.hand = "left" | "right"
Selects retained main and thumb keys assigned to one hand. The optional except field removes named physical keys from that result.
Hand-derived key-set exclusions#
key_sets.*.except = ["spc"]
Removes retained main or thumb keys from a hand-derived set. Every listed key must exist.
Finger-derived key set#
key_sets.*.finger = "left_index"
Selects retained keys assigned to one exact finger. Thumb selectors use left_thumb or right_thumb.
Layer-derived key set#
key_sets.*.layer = "symbols"
Selects physical keys with an authored binding on the named layer other than none or transparent. It does not inherit output from lower layers, apply a case map, or include keys merely because they belong to a combo. A contextual binding is included because that key has behavior on the layer even when the layer default is none.
The layer may appear later in the document, but it must exist.
Referenced key set#
key_sets.*.ref = "letters"
Reuses the resolved members of an earlier key-set declaration. References to the same declaration, a later declaration, or an unknown name are rejected.
Key-set union#
key_sets.*.union = [{ ref = "letters" }, { finger = "left_thumb" }]Combines the members produced by zero or more nested key-set expressions and removes duplicates. An empty union resolves to an empty intermediate result.
Key-set intersection#
key_sets.*.intersect = [{ ref = "letters" }, { hand = "left" }]Keeps keys present in every nested expression. An empty intersection resolves to an empty intermediate result.
Key-set difference#
key_sets.*.diff = [{ ref = "letters" }, ["q", "z"]]Starts with the first expression and removes every key produced by the second. Use difference for exclusions beyond the concise hand form; there is no absolute complement operator.
Compound key-set rules#
[key_sets]
Union, intersection, and difference operands may recursively use any key-set form, including another compound expression. Empty literals and empty compound results are legal while evaluating a larger expression. After the complete expression is resolved, every named key set must contain at least one retained key.
Each expression object chooses exactly one form. Combining fields such as hand and finger in the same object is invalid.
Character classes and output patterns#
Character classes and equivalences#
[character_classes] and [character_equivalences]
A character class names a selected category of characters. Its expression uses ref, union, intersect, and diff, with references to earlier declarations only. Nested expressions may be empty, but every complete named class must contain at least one character. Each array string is one character or grapheme cluster.
An equivalence group lists interchangeable characters. Groups must be disjoint, and every member must also appear in a character class, a layout output, or a literal output-condition slot. Equivalence membership is used only by an explicit { equivalent = "e" } output-pattern slot, which selects the group containing that member; literals do not expand automatically, and matching never rewrites the produced output.
[character_classes]
vowels = ["a", "e", "i", "o", "u"]
accented = ["é", "ê"]
front_vowels = { intersect = [{ ref = "vowels" }, ["e", "i"]] }
[character_equivalences]
e_variants = ["e", "é", "ê"]Character-class expression#
character_classes.* = ["a", "e"] | { ref = "letters" } | { union = [...] } | { intersect = [...] } | { diff = [left, right] }Combines character classes with the same recursive expression forms as key sets. A named class must resolve to a nonempty set after its complete expression is evaluated.
Patterned previous-output context#
after_output = "suffix" | [slot, ...]
An array output context consumes one grapheme cluster per slot. A string slot is literal, { ref = "name" } selects a named character class, and { equivalent = "e" } matches any member of the disjoint equivalence group containing e. A compact string remains a literal multi-grapheme suffix. word_start = true anchors the matched suffix before its first slot at sequence start or immediately after a space; punctuation is not a separator.
Character classes and equivalences affect matching only. They do not normalize, replace, or otherwise alter the output selected by the rule. case_map and case_sensitive keep their existing matching behavior; an explicit equivalence slot still uses the group containing its declared member when case sensitivity is enabled.
rules = [{ after_output = ["q", { ref = "vowels" }, { equivalent = "e" }], word_start = true, set = { magic = "x" } }]Word-start output context#
word_start = false | true
Anchors either form of after_output before its first slot at sequence start or immediately after a space. Punctuation is not a separator. It does not change the matched text or the rule output.
Alternate fingerings#
Alternate fingerings describe native physical event sequences that analysis may choose in addition to the ordinary board fingering.
Alternate fingering declaration#
[[alt_fingerings]]
Adds optional analysis paths for exact physical event fragments. The normal board fingering remains available; path and cost resolution decide whether an alternate is used.
A layout may declare at most 4096 alternate fingerings. Exact duplicate declarations are rejected. Trigger names refer to the shared key-and-chord namespace, not to produced text or a layer-specific binding.
# Fragment: a and b are existing physical key bindings.
[[alt_fingerings]]
events = [
{ press = "a", fingers = { a = "RM" } },
{ press = "b", fingers = { b = "RI" } },
][chords]
th = ["t", "h"]
[layers.base]
default = "literal"
combos = { th = "x" }
[[alt_fingerings]]
events = [
{ press = "th", fingers = { t = "LM" } },
]Alternate event sequence#
events = [{...}, ...]Lists one to eight exact events in order. Each event is exactly one of a press, acquire, or release object.
Declarations are fragments of a complete typing path, so the first event may begin with held triggers and the last may leave triggers held. Between adjacent events, the earlier post-event held set must exactly equal the later pre-event held set.
Alternate press trigger#
press = "key_or_chord"
Presses one existing physical key or chord. Matching uses that trigger’s exact physical identity; it does not match output text or one particular layer behavior.
Every declaration must change the board-assigned finger of at least one physical key in a press event. A declaration containing only defaults, acquire events, or release events is invalid.
Pressed-key finger assignments#
fingers = { physical_key = "LM" }Maps pressed physical key IDs to replacement fingers. Omitted members use their board-assigned finger. For a chord, assignments use constituent physical key IDs rather than chord order or the chord name.
Assignments outside the pressed key or chord are rejected. Several chord members may use the same finger; no additional anatomical restriction is imposed.
Tap-hold branch selection#
hold = true
Selects the text-producing hold branch of an existing tap-hold key or chord. This is distinct from an acquire event, which changes the set of triggers held across later events.
[layers.base]
default = "literal"
bindings = { qu = { type = "tap_hold", tap = { type = "output", value = "qu" }, hold = { type = "output", value = "q" } } }
[[alt_fingerings]]
events = [
{ press = "qu", hold = true, fingers = { qu = "RI" } },
]Acquire held triggers#
acquire = ["trigger", ...]
Adds one or more existing key or chord triggers to the held set. The array is nonempty, unique, and contains at most nine names.
Acquire and release events do not accept finger assignments. Their changing triggers plus sustained triggers may total at most nine.
[layers.base]
default = "literal"
bindings = { lsh = { type = "momentary", layer = "shift" } }
[layers.shift]
default = "transparent"
[[alt_fingerings]]
events = [
{ acquire = ["lsh"] },
{ press = "a", fingers = { a = "RM" }, sustained = ["lsh"] },
{ release = ["lsh"] },
]Release held triggers#
release = ["trigger", ...]
Removes one or more existing key or chord triggers from the held set. The array is nonempty, unique, and contains at most nine names.
The pre-event held set consists of the released triggers plus sustained. When a previous event exists in the fragment, its post-event held set must match this set exactly.
Sustained triggers#
sustained = ["trigger", ...]
Names the exact triggers held unchanged across this event. Omission means the sustained set is empty; it is not a wildcard.
A trigger changed by this event cannot also be sustained. A press event may list up to nine sustained triggers. Acquire and release events apply the combined nine-trigger limit described above.
Case maps#
Case maps are directional grapheme substitutions contributed by an active destination layer. They are normally paired with transparent behavior on a Shift layer.
US-English case map#
layers.*.case_map = "us-english"
Maps a through z to uppercase and applies the punctuation pairs shown below.
source: ` 1 2 3 4 5 6 7 8 9 0 - = [ ] \ ; ' , . /
target: ~ ! @ # $ % ^ & * ( ) _ + { } | : " < > ?Custom case pairs#
layers.*.case_map = ["aA", "2@"]
Each string contains exactly two Unicode grapheme clusters: source then target. Endpoints must differ, and no endpoint may appear in another pair.
Case-map preset#
layers.*.case_map.use = "us-english"
Selects the built-in map used by the preset object form. The only accepted preset is us-english.
US-English exclusions#
layers.*.case_map.except = ["'"]
Removes mappings from the selected preset by source grapheme. Every excluded source must exist in the US-English map.
Case-map source layer#
layers.*.source_layer = "a2"
Names the layer whose authored key or combo behavior supplies transparent entries on this mapped destination. The source may appear before or after the destination and does not need to be active.
The source must exist, differ from the destination, and have no case map of its own. Omission selects base, even when other layers between base and the destination are active.
An explicit destination behavior bypasses the source and this case map. At a transparent destination, an explicit source output or contextual behavior is mapped. A source none or absent combo is opaque. A source transparent entry stays transparent, then ordinary active-layer lookup continues below the destination without applying this destination’s map.
[layers.a2]
default = "literal"
bindings = { a = "x" }
[layers.shift2]
default = "transparent"
case_map = "us-english"
source_layer = "a2"Mapping and layer lookup#
A map transforms text supplied by a mapped destination’s source layer, including contextual defaults and rule outputs. It maps each grapheme rather than treating a multi-grapheme output as one pair.
A held or locked mapped layer maps the complete inherited output. A one-shot mapped layer maps its first grapheme. Explicit behavior on the mapped destination is unchanged.
Contextual rules#
Rules add context-dependent outputs to ordinary binding or combo defaults. Every rule has exactly one context and one operation.
Previous-key context#
after_keys = [reference] | [older, newer]
A bare ID names the direct tap of that key or chord on the containing layer. { press = "a", layer = "shift", hold = true } names an exact key or chord action. { keyset = "left", layer = "base" } matches direct taps from a named key set. Omitted layer means the containing layer, and omitted hold means false.
{} is a wildcard. In a two-item context, values are ordered oldest to newest and both positions are immediately before the target; a context cannot be entirely wildcards. A deletion outcome requires the immediate previous slot to be named; a key set qualifies, but a wildcard there does not.
Previous-action reference#
after_keys = [{ press = "a" }]Names one stable key or chord action in an after_keys reference. A plain string is the compact same-layer, direct-tap form.
Previous-key-set reference#
after_keys = [{ keyset = "left" }]Names one authored key set in an after_keys reference.
Previous-action layer#
after_keys = [{ press = "a", layer = "shift" }]Qualifies a key or key-set reference with an exact layer. Omission means the layer containing the rule.
Previous-action tap-hold branch#
after_keys = [{ press = "qu", hold = true }]Selects the text-producing hold branch of the named tap-hold key or chord. False selects its direct tap identity.
Previous-output context#
after_output = "suffix" | [slot, ...]
Matches a produced-text suffix without removing that text. A compact string is a literal multi-grapheme suffix; an array consumes one grapheme cluster per literal, character-class, or equivalence slot. If exactly one layer declares a case map, it is selected automatically. With several maps, the rule must name one in case_map; otherwise no automatic case equivalence is added, while explicitly requested classes and equivalences still apply.
Output-context case map#
case_map = "shift"
Selects the named layer’s case map when matching after_output. With exactly one authored case map it may be omitted; with several it is required.
Set outputs#
set = { target = "output" | { type = "output", value = "..." } | outcome }Assigns one contextual outcome to each target. A string remains the compact output form. An output object may set delete_previous_output = true to replace the entire output of the immediately preceding ordinary press; its immediate after_keys slot must be named, and it cannot use after_output or a default. A completed deletion cannot be deleted or output-repeated again.
The other outcomes are { type = "repeat", repeat_kind = "output" | "keystroke" }, { type = "skip_repeat", repeat_kind = "output" | "keystroke" }, { type = "none" }, and { type = "blocked" }. none completes a no-output action without advancing completed-output history or consuming a one-shot. blocked refuses execution and cannot be rescued by a miss policy. Targets are keys by default or chord IDs when on = "combos".
Contextual outcome#
set = { target = { type = "output", value = "...", delete_previous_output = true } }An output outcome replaces the entire preceding ordinary press output when delete_previous_output = true; it does not delete one character from a multi-grapheme output. Repeat and skip-repeat may repeat output or rerun the earlier keystroke. A tap-hold target uses branch = "tap" to select its tap branch; a contextual hold branch is invalid. Tap branches may use none or blocked.
rules = [
{ after_keys = ["a"], set = { magic = { type = "output", value = "qu", delete_previous_output = true } } },
{ after_keys = ["t"], set = { again = { type = "repeat", repeat_kind = "keystroke" } } },
{ after_keys = ["x"], set = { magic = { type = "none" } } },
]Swap outputs#
swap = ["a", "b"]
Routes each target to the other target’s original literal output. Both targets must have ordinary literal defaults.
Cycle outputs#
cycle = ["a", "b", "c"]
Routes each target to the next target’s original literal output, and the final target to the first. Every target must have an ordinary literal default.
Rule target namespace#
on = "bindings" | "combos"
Selects physical key targets or per-layer chord targets. Every target must already exist in the selected namespace.
Tap-hold rule branch#
branch = "tap"
Selects the direct tap branch of a tap-hold key or chord for a contextual rule. A contextual hold branch is invalid.
Shadowed default policy#
default_when_shadowed = "blocked" | "miss"
A matching contextual rule takes the normal typing path. miss provides the target’s ordinary default only as a separate miss when the matching winner is not a blocked outcome; default_when_shadowed = "blocked" suppresses that shadowed fallback. Neither setting turns the selected outcome into blocked, and it does not fall through to another layer. Every rule for one target and tap branch must use the same policy.
Context preference#
prefer = "after_output" | "after_keys"
prefer = "after_output" is the default. Set prefer = "after_keys" to choose previous-key contexts before output-suffix contexts. All rules for one target and tap branch must use the same preference.
Context case sensitivity#
case_sensitive = false | true
case_sensitive = false allows automatic case-equivalent context matching without changing the produced output. true requires exact case. Explicit mapped-layer contexts remain exact. All rules for one target and tap branch must use the same case-sensitivity setting.
Allowed rule defaults#
A contextual target must start as an ordinary output, none, blocked, repeat, skip-repeat, or unanchored one-shot default. Momentary, lock, anchored activation, transparent, tap-hold hold, or another contextual behavior cannot be converted into a rule target.
For one target and tap branch, the more-specific valid context wins; rule order is preserved for stable authoring and does not make the first broad match win. All rules in that group must agree on preference, case sensitivity, and shadow policy.
rules = [
{ after_keys = ["t"], set = { magic = "h" } },
{ after_keys = ["x", {}], swap = ["w", "e"] },
{ after_output = "qu", case_map = "shift", on = "combos", set = { again = "e" } },
]Analysis costs#
Each layout supplies the complete typing-path cost model. These expressions run on one candidate n-gram before a path is selected.
Unigram cost#
cost.uni
Prices one keystroke. Every evaluated result must be a positive integer.
Bigram cost#
cost.bi
Prices two adjacent keystrokes. Every evaluated result must be a nonnegative integer; use 0 to disable the contribution.
Trigram cost#
cost.tri
Prices three adjacent keystrokes. Every evaluated result must be a nonnegative integer; use 0 to disable the contribution.
Standard cost model#
akp means active key pairs and ends means trigram endpoints. Costs have no hidden additions or scaling, and corpus frequency and weight are unavailable here.
[cost]
uni = "5"
bi = "akp.sf.count * 5"
tri = "ends.akp.sf.count"