PyMini
Write Python scripts for Clink actions, panels and plugins. Learn the supported language, available modules and script limits.
Clink for iOSWhat it is
PyMini is the Python subset you use to write custom actions, panels and plugins in Clink. An action transforms text, a panel adds an interface to your keyboard, and a plugin adds behaviour to your setup.
# An action: text in, text out
def transform(text):
return text.upper()
# A panel: a button that inserts text
def view(state):
return button("Hello", insert="Hello!")Choose what to make
Start with an action if you want to change text, such as removing extra spaces or changing case. Choose a panel for buttons and controls you open from the keyboard. Choose a plugin for behaviour that responds to keyboard events.
def transform(text):
return " ".join(text.split())Supported Python and limits
PyMini supports a subset of Python, including functions, loops, comprehensions, lambdas, tuples, sets, formatted strings and exception handling. You cannot install arbitrary Python packages. Scripts have no direct filesystem, network or process access; use the documented Clink commands for keyboard features.
Available modules
jsonmathrandomresystime
Changelog
Each version of PyMini, newest first, and what it added.
PyMini 2.0
The first version could uppercase a word and lay out a grid of buttons. The second is a language you can write a small program in, and a panel that answers a tap rather than only carrying a fixed one.
| Example | What changed |
|---|---|
| [word for word in words if word] | Comprehensions, lambdas, tuples, sets, and try / except / finally / raise. |
| f"{total:,.2f}" | f-string conversions and full format specs, shared with str.format and format(). |
| f"""Hello {name}""" | Triple-quoted and raw strings, and f-strings that run over several lines. |
| import math, random, time, json, re | Five namespaces, and nothing else, every one of them pure. |
| re.sub(r"\s+", " ", text) | Regular-expression search and replacement with the re module. |
| on_action(action, value, state) | Panels handle their own taps, keep real state, and have eleven more controls. |
| replace(len(word), word.upper()) | Scripts can ask the keyboard to act, and read what is around the cursor. |
| Current sentence | Actions read any slice of the field, not just the word and what precedes it. |
import re
def initial():
return {"words": []}
def view(state):
top = sorted(set(state["words"]), key=lambda w: -len(w))[:3]
return vstack([text(f"{len(state['words']):,} words", mono=True)]
+ [row(w, detail=f"{len(w)}") for w in top])
def on_open(state):
state["words"] = re.findall(r"\w+", context()["before"])
return statePyMini 1.0
The first version. An action turned one string into another, and a panel was a few controls whose buttons typed a fixed string or set a value.
| Example | What changed |
|---|---|
| def transform(text): | int, float, str, bool, None, list and dict, with if, while, for, and def with default and keyword arguments. |
| f"{n} words" | f-strings without format specs, and indexing and slicing with negative indices. |
| sorted(text.split()) | 24 builtins and the common str, list and dict methods. |
| button("+", set={"count": 1}) | Text, buttons, fields, stacks and a grid. A button could type text or set state, and nothing more. |
| while True: | No imports at all, a step budget on every script, and caps on how far strings and lists can grow. |
Where to go next
Explore the language reference, panel builders and plugin hooks in the following pages.