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
1 parent 44418f3 commit 0b172ef
Show file tree
Hide file tree
Showing 2 changed files with 49 additions and 15 deletions.
38 changes: 35 additions & 3 deletions docs/en/macros.md
Original file line number Diff line number Diff line change
Expand Up @@ -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):
Expand All @@ -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.

```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_PASTE = 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
Expand Down
26 changes: 14 additions & 12 deletions kmk/modules/macros.py
Original file line number Diff line number Diff line change
Expand Up @@ -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:
Expand All @@ -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:]:
Expand All @@ -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):
Expand Down

0 comments on commit 0b172ef

Please sign in to comment.