chordgen 0.1.0__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,277 @@
1
+ Metadata-Version: 2.3
2
+ Name: chordgen
3
+ Version: 0.1.0
4
+ Summary: Add your description here
5
+ Author: Dane Lipscombe
6
+ Author-email: Dane Lipscombe <danelipscombe@gmail.com>
7
+ Requires-Dist: patternlite>=3.6
8
+ Requires-Dist: pydantic>=2.12.5
9
+ Requires-Dist: pyyaml>=6.0.3
10
+ Requires-Dist: tqdm>=4.67.3
11
+ Requires-Dist: typer>=0.24.1
12
+ Requires-Python: >=3.11
13
+ Description-Content-Type: text/markdown
14
+
15
+ # chordgen
16
+
17
+ Abbreviation generator for chording and text expansion
18
+
19
+ Every day, we find ourselves typing commonly used words repetitively, consuming time and effort. Text expansion offers a solution by allowing us to replace these frequently used words with unique abbreviations, thereby saving keystrokes. For instance, typing 't' with a trigger key could automatically generate 'the '. The objective isn't to abbreviate every word, but rather to focus on those that offer significant savings for the effort invested in memorization. Ideally you also want the abbreviations to be the most comfortable effort wise for your particular keyboard layout (qwerty, colemak, canary etc).
20
+
21
+ However, compiling such a list manually can be a daunting task. This is where chordgen comes in handy, it helps by automating the generation of the initial list and streamlines the process of importing them into different tools, so you can enhance and customize them over time.
22
+
23
+ Given a list of common words it can generate a list like the following, the way you input each word and alternate word depends on if you are using chording or text expansion
24
+
25
+ | Word | Abbreviation | Alt1 | Alt2 | Alt3 |
26
+ | ---- | ------------ | ----- | ------ | ------- |
27
+ | look | l | looks | looked | looking |
28
+ | give | ge | gives | gave | giving |
29
+
30
+ ## Chording vs text expansion
31
+
32
+ Chording involves pressing multiple keys at the same time, while text expansion is typing as usual followed by a trigger key. There are pros and cons of each approach to consider:
33
+
34
+ ### Chording Pros and Cons
35
+
36
+ - Quicker since the time taken is about the same as a single key press
37
+ - Can take time to get used to pressing multiple keys together
38
+ - Heavier on the fingers especially if you have heavy key switches
39
+
40
+ ### Text Expansion Pros and Cons
41
+
42
+ - More possible combinations since you can use abbreviations that reverse and repeat letters
43
+ - Easier to set up with a standard keyboard
44
+ - Can be buggy with some programs due to the way it replaces text
45
+ - Can be a security issue at work since it captures key presses and might need administrator privilages to install
46
+
47
+ ### Chording
48
+
49
+ The approach it takes with combos is to define combo, shift, and alt1/2 keys that are pressed in combination with the abbreviation to get the desired output. These keys work well on the thumbs to ensure all the abbreviations are possible to press with them. There are some extra combos to help with punctuation.
50
+
51
+ | Input | Output |
52
+ | ------------------------------- | ----------------------- |
53
+ | l + combo | look`<space>` |
54
+ | l + combo + shift | Look`<space>` |
55
+ | l + combo + alt1 | looked`<space>` |
56
+ | l + combo + alt2 | looking`<space>` |
57
+ | l + combo + alt1 + alt2 | looks`<space>` |
58
+ | l + combo + shift + alt1 + alt2 | Looks`<space>` |
59
+ | . + combo | `<backspace>`.`<space>` |
60
+ | , + combo | `<backspace>`,`<space>` |
61
+ | ; + combo | `<backspace>`;`<space>` |
62
+
63
+ This is how I have set up my 4 key thumb cluster from left to right:
64
+
65
+ - alt1 (normally tab on tap or my navigation/number/symbol layer on hold, with hold preferred setting)
66
+ - alt2 (normally space on tap or my media/function layer on hold, with tap preferred setting)
67
+ - shift (normally backspace on tap or shift on hold, with hold preferred setting)
68
+ - combo (normally delete word, this is great when making mistakes while learning)
69
+
70
+ ### Text Expansion
71
+
72
+ The approach it takes with text expansion is to define a trigger which you type after the abbreviation. The default trigger is `,;`. Read below about setting up a trigger key so you can automate typing this on one key. Alternate versions and punctuation is accessed by adding an extra suffix after the abbreviation.
73
+
74
+ | Input | Output |
75
+ | ------------- | ---------------- |
76
+ | l`<trigger>` | look`<space>` |
77
+ | lq`<trigger>` | looked`<space>` |
78
+ | lj`<trigger>` | looking`<space>` |
79
+ | lz`<trigger>` | looks`<space>` |
80
+ | L`<trigger>` | Look`<space>` |
81
+ | L.`<trigger>` | Look.`<space>` |
82
+ | L,`<trigger>` | Look,`<space>` |
83
+ | L;`<trigger>` | Look;`<space>` |
84
+
85
+ ## Setup
86
+
87
+ Clone the repo `git clone https://github.com/dlip/chordgen.git` and change to the directory with `cd chordgen`
88
+
89
+ ### Python
90
+
91
+ - Install [Python 3.11+](https://www.python.org/downloads/)
92
+ - Run `pip install -r requirements.txt`
93
+
94
+ ### Nix (Alternative to Python setup)
95
+
96
+ If you have [Nix](https://nixos.org/download) you can run `nix develop` to get into a shell with Python and the required dependencies. If you have [direnv](https://direnv.net/docs/installation.html) also, you can run `direnv allow` instead to have the dependencies available as soon as you change to the directory.
97
+
98
+ ### Running
99
+
100
+ To run the commands use `python <file.py>`
101
+
102
+ ## Commands
103
+
104
+ ### chordgen.py
105
+
106
+ This reads `words.tsv` and outputs abbreviations in tsv format to `abbr.tsv`:
107
+
108
+ The approach it uses is:
109
+
110
+ - Generate all combinations of the letters in the word which start with the first letter and keep the order from left to right
111
+ - Reject abbreviations it has already used
112
+ - Reject abbreviations that are shorter than a minimum amount of characters or don't provide a minimum percentage improvement over typing the full word
113
+ - Score remaining abbreviations by effort and select the best option depending on your particular keyboard layout and if you are using chorded mode
114
+ - Add alt versions
115
+ - Use [alt.tsv](./alt.tsv) if available, else:
116
+ - Add verb tenses and plurals using [pattern](https://github.com/clips/pattern)
117
+
118
+ There are some options that you might want to change near the top of [chordgen.py](chordgen.py). In particular set `chorded_mode` to `True` or `False` depending on what method you are using.
119
+
120
+ ### training.py
121
+
122
+ This generates a [training.txt](training.txt) file from `abbr.tsv` for you to copy a line of 10 words at a time into a typing practice tool like [Monkeytype](https://monkeytype.com/) custom mode to help learn the abbreviations:
123
+
124
+ ```
125
+ the and you have that for with this not but
126
+ t a y h th f w ti n b
127
+ ```
128
+
129
+ ### qmk-chorded.py
130
+
131
+ This is a chorded importer for [QMK](https://qmk.fm) which is a firmware for custom keyboards.
132
+
133
+ You can check my config [here](https://github.com/dlip/qmk_firmware/tree/dlip/keyboards/mushi/keymaps/dlip) for reference
134
+
135
+ - Setup combos as per this [gboards guide](https://combos.gboards.ca/docs/install/)
136
+ - Add definitions for KC_COMBO, KC_COMBO_SFT, KC_COMBO_ALT1, KC_COMBO_ALT2 thumb keys to your `keymap.c`. Feel free to change the actions here to whatever works for you. If you have other special keys on your letters eg. home row mods, add definitions for these also so they can be referred to in the script. Use these in your keymap.
137
+ - Move the `#include "g/keymap_combo.h"` line below all your definitions
138
+
139
+ ```
140
+ // Other definitions
141
+
142
+ #define KC_COMBO_ALT1 LT(1, KC_TAB)
143
+ #define KC_COMBO_ALT2 LT(2, KC_SPC)
144
+ #define KC_COMBO_SFT MT(MOD_LSFT, KC_BSPC)
145
+ #define KC_COMBO C(KC_BSPC)
146
+
147
+ #include "g/keymap_combo.h"
148
+ ```
149
+
150
+ - Open [qmk-chorded.py](qmk-chorded.py) and ensure `key_map` matches any other custom definitions you may have
151
+ - Run `python qmk-chorded.py`
152
+ - It will generate `abbr.def` which you need to copy to your QMK keymap directory
153
+ - Add `#include "abbr.def"` to the top of your QMK `combos.def` file
154
+ - Flash your keyboard
155
+
156
+ ### zmk-chorded.py
157
+
158
+ This is a chorded importer for [ZMK](https://zmk.dev/) which is a firmware for custom keyboards.
159
+
160
+ You can check my config [here](https://github.com/dlip/zmk-sweep/blob/main/config/cradio.keymap) for reference
161
+
162
+ - Open [zmk-chorded.py](zmk-chorded.py) and ensure `key_positions` matches all the key positions on your keyboard
163
+ - Run `python zmk-chorded.py`
164
+ - It will generate `macros.dtsi` and `combos.dtsi` which you can then copy to your zmk keymap directory
165
+ - Include these lines in your zmk keymap keymap file
166
+
167
+ ```
168
+ macros {
169
+ #include "macros.dtsi"
170
+ };
171
+
172
+ combos {
173
+ compatible = "zmk,combos";
174
+ #include "combos.dtsi"
175
+ };
176
+ ```
177
+
178
+ - Include these lines in your zmk keymap conf file, you may have to increase `CONFIG_ZMK_COMBO_MAX_COMBOS_PER_KEY` if you are able to fit more combos on your controller
179
+
180
+ ```
181
+ CONFIG_ZMK_COMBO_MAX_COMBOS_PER_KEY=512
182
+ CONFIG_ZMK_COMBO_MAX_KEYS_PER_COMBO=10
183
+ CONFIG_ZMK_COMBO_MAX_PRESSED_COMBOS=10
184
+ ```
185
+
186
+ - Flash your keyboard
187
+
188
+ ### kanata-chorded.py
189
+
190
+ This is a chorded importer for [Kanata](https://github.com/jtroo/kanata) which is a software keyboard remapper. It uses the experimental chords v2 feature which requires at least Kanata v1.6.1.
191
+
192
+ Be aware that many keyboards, especially laptop ones do not support having many keys held at the same time. You can check what combinations work for your one [here](https://www.mechanical-keyboard.org/key-rollover-test/)
193
+
194
+ - Open [kanata-chorded.py](kanata-chorded.py) and customize the `mapping` dictionary with your base mappings and the combo etc. keys
195
+ - Run `python kanata-chorded.py` and copy [abbr.kbd](./abbr.kbd) to your keymap directory
196
+ - Follow the example in [engram-chorded.kbd](./engram-chorded.kbd) and update your keymap
197
+ - Add `concurrent-tap-hold yes` to the `defcfg` section
198
+ - Add `(include abbr.kbd)`
199
+ - Run `sudo kanata -c <keymap.kbd>`
200
+
201
+ ### espanso-text-expansion.py
202
+
203
+ This is a text expansion importer for [Espanso](https://espanso.org)
204
+
205
+ It reads `abbr.tsv` and generates `abbr.yml` which you can then copy to `~/.config/espanso/match/`. The yaml file is quite verbose since it adds multiple matches for all the possible suffixes, so you'll probably want to make any changes to `abbr.tsv` then run this command again.
206
+
207
+ Here are some settings you might want to change:
208
+
209
+ ```python
210
+ # suffix to add to the end of an abbreviation to trigger the expansion
211
+ expand_trigger = ",;"
212
+ # suffix to add before the trigger to use the alternate forms in `abbr.tsv`
213
+ alt_suffix_1 = "q"
214
+ alt_suffix_2 = "j"
215
+ alt_suffix_3 = "z"
216
+ ```
217
+
218
+ It might be preferable to disable `undo_backspace` in `~/.config/espanso/config/default.yml` in case you want to backspace without loosing the whole word
219
+
220
+ ```
221
+ undo_backspace: false
222
+ ```
223
+
224
+ The `abbr.yml` file is very verbose, so if you want to add/update words I recommend reading on so you can edit `abbr.tsv` then generate the file again from that.
225
+
226
+ ### Setting up a trigger key for text expansion
227
+
228
+ Having to type 2 characters eg. ',;' reduces the improvement gain considerably, especially for shorter words. You can bind a key on your keyboard that you don't usually use eg. right alt, caps lock via softwarwe or programmable keyboard firmware
229
+
230
+ #### Kanata (software)
231
+
232
+ Install [Kanata](https://github.com/jtroo/kanata) and add this alias to your config. You and then bind `@tgr` to a key of your choosing.
233
+
234
+ ```
235
+ (defalias
236
+ tgr (macro , ;)
237
+ )
238
+ ```
239
+
240
+ #### ZMK (firmware)
241
+
242
+ Add this macro to your config, then you can bind `&tgr` to a key
243
+
244
+ ```
245
+ macros {
246
+ ZMK_MACRO (tgr,
247
+ wait-ms = <30>;
248
+ tap-ms = <40>;
249
+ bindings = <&kp COMMA &kp SEMI>;
250
+ )
251
+ };
252
+ ```
253
+
254
+ #### QMK (firmware)
255
+
256
+ Add this custom keycode to your config, then you can bind `TGR` to a key
257
+
258
+ ```
259
+ enum custom_keycodes {
260
+ TGR = SAFE_RANGE,
261
+ };
262
+
263
+ bool process_record_user(uint16_t keycode, keyrecord_t *record) {
264
+ switch (keycode) {
265
+ case TGR:
266
+ if (record->event.pressed) {
267
+ SEND_STRING(",;");
268
+ }
269
+ break;
270
+ }
271
+ return true;
272
+ };
273
+ ```
274
+
275
+ ## Credits
276
+
277
+ - [English frequency list](https://tmh.conlang.org/word-frequency/)
@@ -0,0 +1,263 @@
1
+ # chordgen
2
+
3
+ Abbreviation generator for chording and text expansion
4
+
5
+ Every day, we find ourselves typing commonly used words repetitively, consuming time and effort. Text expansion offers a solution by allowing us to replace these frequently used words with unique abbreviations, thereby saving keystrokes. For instance, typing 't' with a trigger key could automatically generate 'the '. The objective isn't to abbreviate every word, but rather to focus on those that offer significant savings for the effort invested in memorization. Ideally you also want the abbreviations to be the most comfortable effort wise for your particular keyboard layout (qwerty, colemak, canary etc).
6
+
7
+ However, compiling such a list manually can be a daunting task. This is where chordgen comes in handy, it helps by automating the generation of the initial list and streamlines the process of importing them into different tools, so you can enhance and customize them over time.
8
+
9
+ Given a list of common words it can generate a list like the following, the way you input each word and alternate word depends on if you are using chording or text expansion
10
+
11
+ | Word | Abbreviation | Alt1 | Alt2 | Alt3 |
12
+ | ---- | ------------ | ----- | ------ | ------- |
13
+ | look | l | looks | looked | looking |
14
+ | give | ge | gives | gave | giving |
15
+
16
+ ## Chording vs text expansion
17
+
18
+ Chording involves pressing multiple keys at the same time, while text expansion is typing as usual followed by a trigger key. There are pros and cons of each approach to consider:
19
+
20
+ ### Chording Pros and Cons
21
+
22
+ - Quicker since the time taken is about the same as a single key press
23
+ - Can take time to get used to pressing multiple keys together
24
+ - Heavier on the fingers especially if you have heavy key switches
25
+
26
+ ### Text Expansion Pros and Cons
27
+
28
+ - More possible combinations since you can use abbreviations that reverse and repeat letters
29
+ - Easier to set up with a standard keyboard
30
+ - Can be buggy with some programs due to the way it replaces text
31
+ - Can be a security issue at work since it captures key presses and might need administrator privilages to install
32
+
33
+ ### Chording
34
+
35
+ The approach it takes with combos is to define combo, shift, and alt1/2 keys that are pressed in combination with the abbreviation to get the desired output. These keys work well on the thumbs to ensure all the abbreviations are possible to press with them. There are some extra combos to help with punctuation.
36
+
37
+ | Input | Output |
38
+ | ------------------------------- | ----------------------- |
39
+ | l + combo | look`<space>` |
40
+ | l + combo + shift | Look`<space>` |
41
+ | l + combo + alt1 | looked`<space>` |
42
+ | l + combo + alt2 | looking`<space>` |
43
+ | l + combo + alt1 + alt2 | looks`<space>` |
44
+ | l + combo + shift + alt1 + alt2 | Looks`<space>` |
45
+ | . + combo | `<backspace>`.`<space>` |
46
+ | , + combo | `<backspace>`,`<space>` |
47
+ | ; + combo | `<backspace>`;`<space>` |
48
+
49
+ This is how I have set up my 4 key thumb cluster from left to right:
50
+
51
+ - alt1 (normally tab on tap or my navigation/number/symbol layer on hold, with hold preferred setting)
52
+ - alt2 (normally space on tap or my media/function layer on hold, with tap preferred setting)
53
+ - shift (normally backspace on tap or shift on hold, with hold preferred setting)
54
+ - combo (normally delete word, this is great when making mistakes while learning)
55
+
56
+ ### Text Expansion
57
+
58
+ The approach it takes with text expansion is to define a trigger which you type after the abbreviation. The default trigger is `,;`. Read below about setting up a trigger key so you can automate typing this on one key. Alternate versions and punctuation is accessed by adding an extra suffix after the abbreviation.
59
+
60
+ | Input | Output |
61
+ | ------------- | ---------------- |
62
+ | l`<trigger>` | look`<space>` |
63
+ | lq`<trigger>` | looked`<space>` |
64
+ | lj`<trigger>` | looking`<space>` |
65
+ | lz`<trigger>` | looks`<space>` |
66
+ | L`<trigger>` | Look`<space>` |
67
+ | L.`<trigger>` | Look.`<space>` |
68
+ | L,`<trigger>` | Look,`<space>` |
69
+ | L;`<trigger>` | Look;`<space>` |
70
+
71
+ ## Setup
72
+
73
+ Clone the repo `git clone https://github.com/dlip/chordgen.git` and change to the directory with `cd chordgen`
74
+
75
+ ### Python
76
+
77
+ - Install [Python 3.11+](https://www.python.org/downloads/)
78
+ - Run `pip install -r requirements.txt`
79
+
80
+ ### Nix (Alternative to Python setup)
81
+
82
+ If you have [Nix](https://nixos.org/download) you can run `nix develop` to get into a shell with Python and the required dependencies. If you have [direnv](https://direnv.net/docs/installation.html) also, you can run `direnv allow` instead to have the dependencies available as soon as you change to the directory.
83
+
84
+ ### Running
85
+
86
+ To run the commands use `python <file.py>`
87
+
88
+ ## Commands
89
+
90
+ ### chordgen.py
91
+
92
+ This reads `words.tsv` and outputs abbreviations in tsv format to `abbr.tsv`:
93
+
94
+ The approach it uses is:
95
+
96
+ - Generate all combinations of the letters in the word which start with the first letter and keep the order from left to right
97
+ - Reject abbreviations it has already used
98
+ - Reject abbreviations that are shorter than a minimum amount of characters or don't provide a minimum percentage improvement over typing the full word
99
+ - Score remaining abbreviations by effort and select the best option depending on your particular keyboard layout and if you are using chorded mode
100
+ - Add alt versions
101
+ - Use [alt.tsv](./alt.tsv) if available, else:
102
+ - Add verb tenses and plurals using [pattern](https://github.com/clips/pattern)
103
+
104
+ There are some options that you might want to change near the top of [chordgen.py](chordgen.py). In particular set `chorded_mode` to `True` or `False` depending on what method you are using.
105
+
106
+ ### training.py
107
+
108
+ This generates a [training.txt](training.txt) file from `abbr.tsv` for you to copy a line of 10 words at a time into a typing practice tool like [Monkeytype](https://monkeytype.com/) custom mode to help learn the abbreviations:
109
+
110
+ ```
111
+ the and you have that for with this not but
112
+ t a y h th f w ti n b
113
+ ```
114
+
115
+ ### qmk-chorded.py
116
+
117
+ This is a chorded importer for [QMK](https://qmk.fm) which is a firmware for custom keyboards.
118
+
119
+ You can check my config [here](https://github.com/dlip/qmk_firmware/tree/dlip/keyboards/mushi/keymaps/dlip) for reference
120
+
121
+ - Setup combos as per this [gboards guide](https://combos.gboards.ca/docs/install/)
122
+ - Add definitions for KC_COMBO, KC_COMBO_SFT, KC_COMBO_ALT1, KC_COMBO_ALT2 thumb keys to your `keymap.c`. Feel free to change the actions here to whatever works for you. If you have other special keys on your letters eg. home row mods, add definitions for these also so they can be referred to in the script. Use these in your keymap.
123
+ - Move the `#include "g/keymap_combo.h"` line below all your definitions
124
+
125
+ ```
126
+ // Other definitions
127
+
128
+ #define KC_COMBO_ALT1 LT(1, KC_TAB)
129
+ #define KC_COMBO_ALT2 LT(2, KC_SPC)
130
+ #define KC_COMBO_SFT MT(MOD_LSFT, KC_BSPC)
131
+ #define KC_COMBO C(KC_BSPC)
132
+
133
+ #include "g/keymap_combo.h"
134
+ ```
135
+
136
+ - Open [qmk-chorded.py](qmk-chorded.py) and ensure `key_map` matches any other custom definitions you may have
137
+ - Run `python qmk-chorded.py`
138
+ - It will generate `abbr.def` which you need to copy to your QMK keymap directory
139
+ - Add `#include "abbr.def"` to the top of your QMK `combos.def` file
140
+ - Flash your keyboard
141
+
142
+ ### zmk-chorded.py
143
+
144
+ This is a chorded importer for [ZMK](https://zmk.dev/) which is a firmware for custom keyboards.
145
+
146
+ You can check my config [here](https://github.com/dlip/zmk-sweep/blob/main/config/cradio.keymap) for reference
147
+
148
+ - Open [zmk-chorded.py](zmk-chorded.py) and ensure `key_positions` matches all the key positions on your keyboard
149
+ - Run `python zmk-chorded.py`
150
+ - It will generate `macros.dtsi` and `combos.dtsi` which you can then copy to your zmk keymap directory
151
+ - Include these lines in your zmk keymap keymap file
152
+
153
+ ```
154
+ macros {
155
+ #include "macros.dtsi"
156
+ };
157
+
158
+ combos {
159
+ compatible = "zmk,combos";
160
+ #include "combos.dtsi"
161
+ };
162
+ ```
163
+
164
+ - Include these lines in your zmk keymap conf file, you may have to increase `CONFIG_ZMK_COMBO_MAX_COMBOS_PER_KEY` if you are able to fit more combos on your controller
165
+
166
+ ```
167
+ CONFIG_ZMK_COMBO_MAX_COMBOS_PER_KEY=512
168
+ CONFIG_ZMK_COMBO_MAX_KEYS_PER_COMBO=10
169
+ CONFIG_ZMK_COMBO_MAX_PRESSED_COMBOS=10
170
+ ```
171
+
172
+ - Flash your keyboard
173
+
174
+ ### kanata-chorded.py
175
+
176
+ This is a chorded importer for [Kanata](https://github.com/jtroo/kanata) which is a software keyboard remapper. It uses the experimental chords v2 feature which requires at least Kanata v1.6.1.
177
+
178
+ Be aware that many keyboards, especially laptop ones do not support having many keys held at the same time. You can check what combinations work for your one [here](https://www.mechanical-keyboard.org/key-rollover-test/)
179
+
180
+ - Open [kanata-chorded.py](kanata-chorded.py) and customize the `mapping` dictionary with your base mappings and the combo etc. keys
181
+ - Run `python kanata-chorded.py` and copy [abbr.kbd](./abbr.kbd) to your keymap directory
182
+ - Follow the example in [engram-chorded.kbd](./engram-chorded.kbd) and update your keymap
183
+ - Add `concurrent-tap-hold yes` to the `defcfg` section
184
+ - Add `(include abbr.kbd)`
185
+ - Run `sudo kanata -c <keymap.kbd>`
186
+
187
+ ### espanso-text-expansion.py
188
+
189
+ This is a text expansion importer for [Espanso](https://espanso.org)
190
+
191
+ It reads `abbr.tsv` and generates `abbr.yml` which you can then copy to `~/.config/espanso/match/`. The yaml file is quite verbose since it adds multiple matches for all the possible suffixes, so you'll probably want to make any changes to `abbr.tsv` then run this command again.
192
+
193
+ Here are some settings you might want to change:
194
+
195
+ ```python
196
+ # suffix to add to the end of an abbreviation to trigger the expansion
197
+ expand_trigger = ",;"
198
+ # suffix to add before the trigger to use the alternate forms in `abbr.tsv`
199
+ alt_suffix_1 = "q"
200
+ alt_suffix_2 = "j"
201
+ alt_suffix_3 = "z"
202
+ ```
203
+
204
+ It might be preferable to disable `undo_backspace` in `~/.config/espanso/config/default.yml` in case you want to backspace without loosing the whole word
205
+
206
+ ```
207
+ undo_backspace: false
208
+ ```
209
+
210
+ The `abbr.yml` file is very verbose, so if you want to add/update words I recommend reading on so you can edit `abbr.tsv` then generate the file again from that.
211
+
212
+ ### Setting up a trigger key for text expansion
213
+
214
+ Having to type 2 characters eg. ',;' reduces the improvement gain considerably, especially for shorter words. You can bind a key on your keyboard that you don't usually use eg. right alt, caps lock via softwarwe or programmable keyboard firmware
215
+
216
+ #### Kanata (software)
217
+
218
+ Install [Kanata](https://github.com/jtroo/kanata) and add this alias to your config. You and then bind `@tgr` to a key of your choosing.
219
+
220
+ ```
221
+ (defalias
222
+ tgr (macro , ;)
223
+ )
224
+ ```
225
+
226
+ #### ZMK (firmware)
227
+
228
+ Add this macro to your config, then you can bind `&tgr` to a key
229
+
230
+ ```
231
+ macros {
232
+ ZMK_MACRO (tgr,
233
+ wait-ms = <30>;
234
+ tap-ms = <40>;
235
+ bindings = <&kp COMMA &kp SEMI>;
236
+ )
237
+ };
238
+ ```
239
+
240
+ #### QMK (firmware)
241
+
242
+ Add this custom keycode to your config, then you can bind `TGR` to a key
243
+
244
+ ```
245
+ enum custom_keycodes {
246
+ TGR = SAFE_RANGE,
247
+ };
248
+
249
+ bool process_record_user(uint16_t keycode, keyrecord_t *record) {
250
+ switch (keycode) {
251
+ case TGR:
252
+ if (record->event.pressed) {
253
+ SEND_STRING(",;");
254
+ }
255
+ break;
256
+ }
257
+ return true;
258
+ };
259
+ ```
260
+
261
+ ## Credits
262
+
263
+ - [English frequency list](https://tmh.conlang.org/word-frequency/)
@@ -0,0 +1,23 @@
1
+ [project]
2
+ name = "chordgen"
3
+ version = "0.1.0"
4
+ description = "Add your description here"
5
+ readme = "README.md"
6
+ authors = [
7
+ { name = "Dane Lipscombe", email = "danelipscombe@gmail.com" }
8
+ ]
9
+ requires-python = ">=3.11"
10
+ dependencies = [
11
+ "patternlite>=3.6",
12
+ "pydantic>=2.12.5",
13
+ "pyyaml>=6.0.3",
14
+ "tqdm>=4.67.3",
15
+ "typer>=0.24.1",
16
+ ]
17
+
18
+ [project.scripts]
19
+ chordgen = "chordgen.cli:app"
20
+
21
+ [build-system]
22
+ requires = ["uv_build>=0.10.2,<0.11.0"]
23
+ build-backend = "uv_build"
File without changes
@@ -0,0 +1,33 @@
1
+ import logging
2
+ from chordgen.chord import Chord
3
+ from chordgen.config import Config
4
+
5
+ from pattern import en
6
+
7
+
8
+ class AltGenerator:
9
+ def __init__(self, config: Config) -> None:
10
+ self.config = config
11
+
12
+ def add_alt(self, chord: Chord) -> Chord:
13
+ word = chord["word"]
14
+ type = chord["type"]
15
+ if self.config.overwrite_alts:
16
+ chord["alt1"] = ""
17
+ chord["alt2"] = ""
18
+ chord["alt3"] = ""
19
+
20
+ if type == "VERB":
21
+ if not chord["alt1"]:
22
+ chord["alt1"] = en.conjugate(word, "3sg")
23
+ if not chord["alt2"]:
24
+ chord["alt2"] = en.conjugate(word, "1sgp")
25
+ if not chord["alt3"]:
26
+ chord["alt3"] = en.conjugate(word, "part")
27
+ elif type == "NOUN":
28
+ if not chord["alt1"]:
29
+ chord["alt1"] = en.pluralize(word, pos=en.NOUN)
30
+ logging.debug(
31
+ f"Alts for word {word}: {chord['alt1']}, {chord['alt2']}, {chord['alt3']}"
32
+ )
33
+ return chord