Generate compose files from portable mappings.
poco takes a simple YAML mapping of trigger sequences to replacement text and
turns it into a native compose file for a target platform. It is written in
Haskell and is currently a work in progress.
poco [-t|--target TARGET] <input.yaml>
Example input file (see also: example.yaml):
"ae": "ä"
"oe": "ö"
"ue": "ü"
"hug": "🫂"
"..": "…"Run poco on the bundled example and compare with the expected output:
stack build
stack exec poco-exe -- example.yaml
diff example.dict <(stack exec poco-exe -- example.yaml)
diff example.compose <(stack exec poco-exe -- -t XComp example.yaml)
XCompose output can be validated with libxkbcommon:
xkbcli compile-compose <(stack exec poco-exe -- -t XComp example.yaml)
TARGET |
Output | Status |
|---|---|---|
Cocoa |
DefaultKeyBinding.dict for macOS (default) |
implemented |
XComp |
XCompose file for X11 |
implemented |
Cocoa output deliberately mimics the Python tool
gen-compose. For example,
"hug": "🫂" becomes:
{"§" = {
"h" = {
"u" = {
"g" = ("insertText:", "🫂");
};
};
};}
example.dict shows the full gen-compose output for example.yaml.
It currently differs from poco -t Cocoa output in sorting.
- No trigger sequence may be a prefix of another. Both targets reject inputs
such as
"a"and"ab", but allow shared prefixes such as"abc"and"abd". - XCompose sequences match keysyms produced by the active keyboard layout.
They do not require US key positions, but the layout must provide the expected
symbols. Dead keys such as
dead_gravedo not matchgrave, and generated Unicode keysyms may differ from the layout's legacy keysyms. See Compose(5), XkbKeycodeToKeysym(3), and the X11 keysym definitions. - XCompose results contain only strings, without an accompanying keysym.
Applications that require a result keysym may fail to handle this input.
For single-character results, emitting both, such as
"ä" adiaeresis, could improve compatibility. Multi-character results generally have no corresponding single keysym. See Compose(5) for the result syntax and XmbLookupString(3) for the distinction betweenXLookupCharsandXLookupBoth.