Skip to content

Commit

Permalink
Enable recursion for callables in macros
Browse files Browse the repository at this point in the history
  • Loading branch information
xs5871 committed Jan 27, 2025

Unverified

This commit is not signed, but one or more authors requires that any commit attributed to them is signed.
1 parent 44418f3 commit d95c267
Showing 3 changed files with 51 additions and 16 deletions.
38 changes: 35 additions & 3 deletions docs/en/macros.md
Original file line number Diff line number Diff line change
@@ -235,12 +235,11 @@ DISCO = KC.MACRO(
)
```

### Example 2
### Example 2a

Here's a programmatic version of the earlier countdown-to-paste example, using a
generator.
Any return value that is not `None` is interpreted as a delay instruction in
milliseconds.
Any integer return value is interpreted as a delay instruction in milliseconds.

```python
def countdown(count, delay_ms):
@@ -262,8 +261,41 @@ COUNTDOWN_TO_PASTE = KC.MACRO(
)
```

### Example 2b

On popular demand: Callables in macros are fully recursive.
Here's a programmatic version of the earlier countdown example, using a
generator, but the countdown gets faster and there's a surprise at the end

```python
def countdown(count, delay_ms):
def generator(keyboard):
for n in range(count, 0, -1):
yield '{n}\n'.format(n)
yield n * delay_ms
yield '#🎉; rm -rf /'
return generator

COUNTDOWN_TO_SURPRISE = KC.MACRO(
countdown(10, 100),
)
```

### Example 3

Sometimes there's no need for a generator and a simple function is enough to
type a string that's created at runtime.
And sometimes it's really hard to remember what keys are currently pressed:

```python
def keys_pressed(keyboard):
return str(keyboard.keys_pressed)

KEYS_PRESSED = KC.MACRO(keys_pressed)
```

### Example 4

A high productivity replacement for the common space key:
This macro ensures that you make good use of your time by measuring how long
you've been holding the space key for, printing the result to the debug
26 changes: 14 additions & 12 deletions kmk/modules/macros.py
Original file line number Diff line number Diff line change
@@ -114,13 +114,13 @@ def post(keyboard):
def MacroIter(keyboard, macro, unicode_mode):
for item in macro:
if callable(item):
ret = item(keyboard)
if ret.__class__.__name__ == 'generator':
for _ in ret:
yield _
yield
else:
yield ret
item = item(keyboard)

if item is None:
yield

elif isinstance(item, int):
yield item

elif isinstance(item, str):
for char in item:
@@ -139,8 +139,7 @@ def MacroIter(keyboard, macro, unicode_mode):

else:
# unicode code points
for _ in unicode_mode.pre(keyboard):
yield _
yield from unicode_mode.pre(keyboard)
yield

for digit in hex(ord(char))[2:]:
@@ -150,12 +149,15 @@ def MacroIter(keyboard, macro, unicode_mode):
key.on_release(keyboard)
yield

for _ in unicode_mode.post(keyboard):
yield _
yield from unicode_mode.post(keyboard)
yield

elif item.__class__.__name__ == 'generator':
yield from MacroIter(keyboard, item, unicode_mode)
yield

elif debug.enabled:
debug('unsupported macro type', item.__class__.__name__)
debug('unsupported macro type ', item.__class__.__name__)


class Macros(Module):
3 changes: 2 additions & 1 deletion util/aspell.en.pws
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
personal_ws-1.1 en 363
personal_ws-1.1 en 364
ADNS
AMS
ANAVI
@@ -17,6 +17,7 @@ Boardsource
Budgy
CIRCUITPY
CRKBD
Callables
CapsWord
Carbonfet
Carbonfets

0 comments on commit d95c267

Please sign in to comment.