Skip to content

xnano.actions

xnano.actions

xnano.actions


Describe keyboard, mouse, focus, clipboard, resize, tick, and request actions.

Classes:

Functions:

Attributes:

KeyboardEventKind module-attribute

KeyboardEventKind: TypeAlias = Literal[
    "press", "release", "repeat"
]

Keyboard event phase.

MouseEventKind module-attribute

MouseEventKind: TypeAlias = Literal[
    "press",
    "release",
    "drag",
    "move",
    "scroll_up",
    "scroll_down",
    "scroll_left",
    "scroll_right",
]

Mouse event phase.

FocusEventKind module-attribute

FocusEventKind: TypeAlias = Literal[
    "gained", "lost", "field_gained", "field_lost"
]

Focus transition.

NormalizedBinding module-attribute

NormalizedBinding: TypeAlias = tuple[frozenset[str], str]

Normalized keyboard binding as (modifiers, key).

Action dataclass

Action()

Bases: ABC

Declarative event trigger.

Examples:

save = Action.keyboard("ctrl+s")

@on_action(save)
def save_document(self) -> None:
    ...

terminal.actions.perform(save)

Methods:

  • keyboard

    Match one or more keyboard bindings.

  • mouse

    Match a mouse event.

  • click

    Match a button press on a field.

  • focus

    Match a focus transition.

  • clipboard

    Match pasted text.

  • tick

    Match a clock tick.

  • resize

    Match a resize event.

  • request

    Match an HTTP request.

  • matches

    Return whether event satisfies this action.

keyboard classmethod

keyboard(
    *bindings: KeyboardBinding,
    kind: KeyboardEventKind | None = None
) -> "KeyboardAction"

Match one or more keyboard bindings.

Source code in xnano/actions.py
@classmethod
def keyboard(
    cls,
    *bindings: KeyboardBinding,
    kind: KeyboardEventKind | None = None,
) -> "KeyboardAction":
    """Match one or more keyboard bindings."""
    return KeyboardAction(bindings=bindings, kind=kind)

mouse classmethod

mouse(
    *buttons: MouseButton,
    kind: MouseEventKind | None = None
) -> "MouseAction"

Match a mouse event.

Source code in xnano/actions.py
@classmethod
def mouse(
    cls,
    *buttons: MouseButton,
    kind: MouseEventKind | None = None,
) -> "MouseAction":
    """Match a mouse event."""
    return MouseAction(buttons=buttons, kind=kind)

click classmethod

click(
    field: str | None = None, button: MouseButton = "left"
) -> "ClickAction"

Match a button press on a field.

Source code in xnano/actions.py
@classmethod
def click(
    cls,
    field: str | None = None,
    button: MouseButton = "left",
) -> "ClickAction":
    """Match a button press on a field."""
    return ClickAction(field=field, button=button)

focus classmethod

focus(
    field: str | None = None,
    kind: FocusEventKind | None = None,
) -> "FocusAction"

Match a focus transition.

Source code in xnano/actions.py
@classmethod
def focus(
    cls,
    field: str | None = None,
    kind: FocusEventKind | None = None,
) -> "FocusAction":
    """Match a focus transition."""
    return FocusAction(field=field, kind=kind)

clipboard classmethod

clipboard(text: str | None = None) -> 'ClipboardAction'

Match pasted text.

Source code in xnano/actions.py
@classmethod
def clipboard(cls, text: str | None = None) -> "ClipboardAction":
    """Match pasted text."""
    return ClipboardAction(text=text)

tick classmethod

tick(interval_ms: int = 0) -> 'TickAction'

Match a clock tick.

Source code in xnano/actions.py
@classmethod
def tick(cls, interval_ms: int = 0) -> "TickAction":
    """Match a clock tick."""
    return TickAction(interval_ms=interval_ms)

resize classmethod

resize(
    width: int | None = None, height: int | None = None
) -> "ResizeAction"

Match a resize event.

Source code in xnano/actions.py
@classmethod
def resize(
    cls,
    width: int | None = None,
    height: int | None = None,
) -> "ResizeAction":
    """Match a resize event."""
    return ResizeAction(width=width, height=height)

request classmethod

request(method: str, path: str = '/') -> 'RequestAction'

Match an HTTP request.

Source code in xnano/actions.py
@classmethod
def request(cls, method: str, path: str = "/") -> "RequestAction":
    """Match an HTTP request."""
    return RequestAction(method=method.upper(), path=path)

matches abstractmethod

matches(event: Any) -> bool

Return whether event satisfies this action.

Source code in xnano/actions.py
@abc.abstractmethod
def matches(self, event: Any) -> bool:
    """Return whether ``event`` satisfies this action."""

KeyboardAction dataclass

KeyboardAction(
    bindings: tuple[KeyboardBinding, ...] = (),
    kind: KeyboardEventKind | None = None,
)

Bases: Action

Match keyboard bindings and an optional transition.

Attributes:

Methods:

  • matches

    Return whether an event matches this keyboard action.

  • keyboard

    Match one or more keyboard bindings.

  • mouse

    Match a mouse event.

  • click

    Match a button press on a field.

  • focus

    Match a focus transition.

  • clipboard

    Match pasted text.

  • tick

    Match a clock tick.

  • resize

    Match a resize event.

  • request

    Match an HTTP request.

bindings class-attribute instance-attribute

bindings: tuple[KeyboardBinding, ...] = ()

Accepted keyboard bindings.

kind class-attribute instance-attribute

kind: KeyboardEventKind | None = None

Required keyboard transition.

matches

matches(event: Any) -> bool

Return whether an event matches this keyboard action.

Source code in xnano/actions.py
def matches(self, event: Any) -> bool:
    """Return whether an event matches this keyboard action."""
    keyboard = getattr(event, "keyboard_event", event)
    if keyboard is None:
        return False
    if (
        self.kind is not None
        and getattr(keyboard, "kind", None) != self.kind
    ):
        return False
    actual = _keyboard_binding(keyboard)
    return not self.bindings or any(
        normalize_binding(str(binding)) == actual
        for binding in self.bindings
    )

keyboard classmethod

keyboard(
    *bindings: KeyboardBinding,
    kind: KeyboardEventKind | None = None
) -> "KeyboardAction"

Match one or more keyboard bindings.

Source code in xnano/actions.py
@classmethod
def keyboard(
    cls,
    *bindings: KeyboardBinding,
    kind: KeyboardEventKind | None = None,
) -> "KeyboardAction":
    """Match one or more keyboard bindings."""
    return KeyboardAction(bindings=bindings, kind=kind)

mouse classmethod

mouse(
    *buttons: MouseButton,
    kind: MouseEventKind | None = None
) -> "MouseAction"

Match a mouse event.

Source code in xnano/actions.py
@classmethod
def mouse(
    cls,
    *buttons: MouseButton,
    kind: MouseEventKind | None = None,
) -> "MouseAction":
    """Match a mouse event."""
    return MouseAction(buttons=buttons, kind=kind)

click classmethod

click(
    field: str | None = None, button: MouseButton = "left"
) -> "ClickAction"

Match a button press on a field.

Source code in xnano/actions.py
@classmethod
def click(
    cls,
    field: str | None = None,
    button: MouseButton = "left",
) -> "ClickAction":
    """Match a button press on a field."""
    return ClickAction(field=field, button=button)

focus classmethod

focus(
    field: str | None = None,
    kind: FocusEventKind | None = None,
) -> "FocusAction"

Match a focus transition.

Source code in xnano/actions.py
@classmethod
def focus(
    cls,
    field: str | None = None,
    kind: FocusEventKind | None = None,
) -> "FocusAction":
    """Match a focus transition."""
    return FocusAction(field=field, kind=kind)

clipboard classmethod

clipboard(text: str | None = None) -> 'ClipboardAction'

Match pasted text.

Source code in xnano/actions.py
@classmethod
def clipboard(cls, text: str | None = None) -> "ClipboardAction":
    """Match pasted text."""
    return ClipboardAction(text=text)

tick classmethod

tick(interval_ms: int = 0) -> 'TickAction'

Match a clock tick.

Source code in xnano/actions.py
@classmethod
def tick(cls, interval_ms: int = 0) -> "TickAction":
    """Match a clock tick."""
    return TickAction(interval_ms=interval_ms)

resize classmethod

resize(
    width: int | None = None, height: int | None = None
) -> "ResizeAction"

Match a resize event.

Source code in xnano/actions.py
@classmethod
def resize(
    cls,
    width: int | None = None,
    height: int | None = None,
) -> "ResizeAction":
    """Match a resize event."""
    return ResizeAction(width=width, height=height)

request classmethod

request(method: str, path: str = '/') -> 'RequestAction'

Match an HTTP request.

Source code in xnano/actions.py
@classmethod
def request(cls, method: str, path: str = "/") -> "RequestAction":
    """Match an HTTP request."""
    return RequestAction(method=method.upper(), path=path)

MouseAction dataclass

MouseAction(
    buttons: tuple[MouseButton, ...] = (),
    kind: MouseEventKind | None = None,
)

Bases: Action

Match mouse buttons and an optional transition.

Attributes:

Methods:

  • matches

    Return whether an event matches this mouse action.

  • keyboard

    Match one or more keyboard bindings.

  • mouse

    Match a mouse event.

  • click

    Match a button press on a field.

  • focus

    Match a focus transition.

  • clipboard

    Match pasted text.

  • tick

    Match a clock tick.

  • resize

    Match a resize event.

  • request

    Match an HTTP request.

buttons class-attribute instance-attribute

buttons: tuple[MouseButton, ...] = ()

Accepted mouse buttons.

kind class-attribute instance-attribute

kind: MouseEventKind | None = None

Required mouse transition.

matches

matches(event: Any) -> bool

Return whether an event matches this mouse action.

Source code in xnano/actions.py
def matches(self, event: Any) -> bool:
    """Return whether an event matches this mouse action."""
    mouse = getattr(event, "mouse_event", event)
    if mouse is None:
        return False
    return (
        self.kind is None or getattr(mouse, "kind", None) == self.kind
    ) and (
        not self.buttons or getattr(mouse, "button", None) in self.buttons
    )

keyboard classmethod

keyboard(
    *bindings: KeyboardBinding,
    kind: KeyboardEventKind | None = None
) -> "KeyboardAction"

Match one or more keyboard bindings.

Source code in xnano/actions.py
@classmethod
def keyboard(
    cls,
    *bindings: KeyboardBinding,
    kind: KeyboardEventKind | None = None,
) -> "KeyboardAction":
    """Match one or more keyboard bindings."""
    return KeyboardAction(bindings=bindings, kind=kind)

mouse classmethod

mouse(
    *buttons: MouseButton,
    kind: MouseEventKind | None = None
) -> "MouseAction"

Match a mouse event.

Source code in xnano/actions.py
@classmethod
def mouse(
    cls,
    *buttons: MouseButton,
    kind: MouseEventKind | None = None,
) -> "MouseAction":
    """Match a mouse event."""
    return MouseAction(buttons=buttons, kind=kind)

click classmethod

click(
    field: str | None = None, button: MouseButton = "left"
) -> "ClickAction"

Match a button press on a field.

Source code in xnano/actions.py
@classmethod
def click(
    cls,
    field: str | None = None,
    button: MouseButton = "left",
) -> "ClickAction":
    """Match a button press on a field."""
    return ClickAction(field=field, button=button)

focus classmethod

focus(
    field: str | None = None,
    kind: FocusEventKind | None = None,
) -> "FocusAction"

Match a focus transition.

Source code in xnano/actions.py
@classmethod
def focus(
    cls,
    field: str | None = None,
    kind: FocusEventKind | None = None,
) -> "FocusAction":
    """Match a focus transition."""
    return FocusAction(field=field, kind=kind)

clipboard classmethod

clipboard(text: str | None = None) -> 'ClipboardAction'

Match pasted text.

Source code in xnano/actions.py
@classmethod
def clipboard(cls, text: str | None = None) -> "ClipboardAction":
    """Match pasted text."""
    return ClipboardAction(text=text)

tick classmethod

tick(interval_ms: int = 0) -> 'TickAction'

Match a clock tick.

Source code in xnano/actions.py
@classmethod
def tick(cls, interval_ms: int = 0) -> "TickAction":
    """Match a clock tick."""
    return TickAction(interval_ms=interval_ms)

resize classmethod

resize(
    width: int | None = None, height: int | None = None
) -> "ResizeAction"

Match a resize event.

Source code in xnano/actions.py
@classmethod
def resize(
    cls,
    width: int | None = None,
    height: int | None = None,
) -> "ResizeAction":
    """Match a resize event."""
    return ResizeAction(width=width, height=height)

request classmethod

request(method: str, path: str = '/') -> 'RequestAction'

Match an HTTP request.

Source code in xnano/actions.py
@classmethod
def request(cls, method: str, path: str = "/") -> "RequestAction":
    """Match an HTTP request."""
    return RequestAction(method=method.upper(), path=path)

ClickAction dataclass

ClickAction(
    field: str | None = None, button: MouseButton = "left"
)

Bases: Action

Match a field click.

Attributes:

Methods:

  • matches

    Return whether an event matches this click action.

  • keyboard

    Match one or more keyboard bindings.

  • mouse

    Match a mouse event.

  • click

    Match a button press on a field.

  • focus

    Match a focus transition.

  • clipboard

    Match pasted text.

  • tick

    Match a clock tick.

  • resize

    Match a resize event.

  • request

    Match an HTTP request.

field class-attribute instance-attribute

field: str | None = None

Required field name.

button class-attribute instance-attribute

button: MouseButton = 'left'

Required mouse button.

matches

matches(event: Any) -> bool

Return whether an event matches this click action.

Source code in xnano/actions.py
def matches(self, event: Any) -> bool:
    """Return whether an event matches this click action."""
    mouse = getattr(event, "mouse_event", event)
    return bool(
        mouse is not None
        and getattr(mouse, "kind", None) == "press"
        and getattr(mouse, "button", None) == self.button
        and (
            self.field is None
            or getattr(event, "field", getattr(mouse, "field", None))
            == self.field
        )
    )

keyboard classmethod

keyboard(
    *bindings: KeyboardBinding,
    kind: KeyboardEventKind | None = None
) -> "KeyboardAction"

Match one or more keyboard bindings.

Source code in xnano/actions.py
@classmethod
def keyboard(
    cls,
    *bindings: KeyboardBinding,
    kind: KeyboardEventKind | None = None,
) -> "KeyboardAction":
    """Match one or more keyboard bindings."""
    return KeyboardAction(bindings=bindings, kind=kind)

mouse classmethod

mouse(
    *buttons: MouseButton,
    kind: MouseEventKind | None = None
) -> "MouseAction"

Match a mouse event.

Source code in xnano/actions.py
@classmethod
def mouse(
    cls,
    *buttons: MouseButton,
    kind: MouseEventKind | None = None,
) -> "MouseAction":
    """Match a mouse event."""
    return MouseAction(buttons=buttons, kind=kind)

click classmethod

click(
    field: str | None = None, button: MouseButton = "left"
) -> "ClickAction"

Match a button press on a field.

Source code in xnano/actions.py
@classmethod
def click(
    cls,
    field: str | None = None,
    button: MouseButton = "left",
) -> "ClickAction":
    """Match a button press on a field."""
    return ClickAction(field=field, button=button)

focus classmethod

focus(
    field: str | None = None,
    kind: FocusEventKind | None = None,
) -> "FocusAction"

Match a focus transition.

Source code in xnano/actions.py
@classmethod
def focus(
    cls,
    field: str | None = None,
    kind: FocusEventKind | None = None,
) -> "FocusAction":
    """Match a focus transition."""
    return FocusAction(field=field, kind=kind)

clipboard classmethod

clipboard(text: str | None = None) -> 'ClipboardAction'

Match pasted text.

Source code in xnano/actions.py
@classmethod
def clipboard(cls, text: str | None = None) -> "ClipboardAction":
    """Match pasted text."""
    return ClipboardAction(text=text)

tick classmethod

tick(interval_ms: int = 0) -> 'TickAction'

Match a clock tick.

Source code in xnano/actions.py
@classmethod
def tick(cls, interval_ms: int = 0) -> "TickAction":
    """Match a clock tick."""
    return TickAction(interval_ms=interval_ms)

resize classmethod

resize(
    width: int | None = None, height: int | None = None
) -> "ResizeAction"

Match a resize event.

Source code in xnano/actions.py
@classmethod
def resize(
    cls,
    width: int | None = None,
    height: int | None = None,
) -> "ResizeAction":
    """Match a resize event."""
    return ResizeAction(width=width, height=height)

request classmethod

request(method: str, path: str = '/') -> 'RequestAction'

Match an HTTP request.

Source code in xnano/actions.py
@classmethod
def request(cls, method: str, path: str = "/") -> "RequestAction":
    """Match an HTTP request."""
    return RequestAction(method=method.upper(), path=path)

FocusAction dataclass

FocusAction(
    field: str | None = None,
    kind: FocusEventKind | None = None,
)

Bases: Action

Match a focus transition.

Attributes:

  • field (str | None) –

    Required field name, or any field.

  • kind (FocusEventKind | None) –

    Required focus transition, or any transition.

Methods:

  • matches

    Return whether an event matches this focus action.

  • keyboard

    Match one or more keyboard bindings.

  • mouse

    Match a mouse event.

  • click

    Match a button press on a field.

  • focus

    Match a focus transition.

  • clipboard

    Match pasted text.

  • tick

    Match a clock tick.

  • resize

    Match a resize event.

  • request

    Match an HTTP request.

field class-attribute instance-attribute

field: str | None = None

Required field name.

kind class-attribute instance-attribute

kind: FocusEventKind | None = None

Required focus transition.

matches

matches(event: Any) -> bool

Return whether an event matches this focus action.

Source code in xnano/actions.py
def matches(self, event: Any) -> bool:
    """Return whether an event matches this focus action."""
    focus = getattr(event, "focus_event", event)
    return bool(
        focus is not None
        and (
            self.kind is None or getattr(focus, "kind", None) == self.kind
        )
        and (
            self.field is None
            or getattr(focus, "field", None) == self.field
        )
    )

keyboard classmethod

keyboard(
    *bindings: KeyboardBinding,
    kind: KeyboardEventKind | None = None
) -> "KeyboardAction"

Match one or more keyboard bindings.

Source code in xnano/actions.py
@classmethod
def keyboard(
    cls,
    *bindings: KeyboardBinding,
    kind: KeyboardEventKind | None = None,
) -> "KeyboardAction":
    """Match one or more keyboard bindings."""
    return KeyboardAction(bindings=bindings, kind=kind)

mouse classmethod

mouse(
    *buttons: MouseButton,
    kind: MouseEventKind | None = None
) -> "MouseAction"

Match a mouse event.

Source code in xnano/actions.py
@classmethod
def mouse(
    cls,
    *buttons: MouseButton,
    kind: MouseEventKind | None = None,
) -> "MouseAction":
    """Match a mouse event."""
    return MouseAction(buttons=buttons, kind=kind)

click classmethod

click(
    field: str | None = None, button: MouseButton = "left"
) -> "ClickAction"

Match a button press on a field.

Source code in xnano/actions.py
@classmethod
def click(
    cls,
    field: str | None = None,
    button: MouseButton = "left",
) -> "ClickAction":
    """Match a button press on a field."""
    return ClickAction(field=field, button=button)

focus classmethod

focus(
    field: str | None = None,
    kind: FocusEventKind | None = None,
) -> "FocusAction"

Match a focus transition.

Source code in xnano/actions.py
@classmethod
def focus(
    cls,
    field: str | None = None,
    kind: FocusEventKind | None = None,
) -> "FocusAction":
    """Match a focus transition."""
    return FocusAction(field=field, kind=kind)

clipboard classmethod

clipboard(text: str | None = None) -> 'ClipboardAction'

Match pasted text.

Source code in xnano/actions.py
@classmethod
def clipboard(cls, text: str | None = None) -> "ClipboardAction":
    """Match pasted text."""
    return ClipboardAction(text=text)

tick classmethod

tick(interval_ms: int = 0) -> 'TickAction'

Match a clock tick.

Source code in xnano/actions.py
@classmethod
def tick(cls, interval_ms: int = 0) -> "TickAction":
    """Match a clock tick."""
    return TickAction(interval_ms=interval_ms)

resize classmethod

resize(
    width: int | None = None, height: int | None = None
) -> "ResizeAction"

Match a resize event.

Source code in xnano/actions.py
@classmethod
def resize(
    cls,
    width: int | None = None,
    height: int | None = None,
) -> "ResizeAction":
    """Match a resize event."""
    return ResizeAction(width=width, height=height)

request classmethod

request(method: str, path: str = '/') -> 'RequestAction'

Match an HTTP request.

Source code in xnano/actions.py
@classmethod
def request(cls, method: str, path: str = "/") -> "RequestAction":
    """Match an HTTP request."""
    return RequestAction(method=method.upper(), path=path)

ClipboardAction dataclass

ClipboardAction(text: str | None = None)

Bases: Action

Match clipboard text.

Attributes:

  • text (str | None) –

    Required clipboard text, or any text.

Methods:

  • matches

    Return whether an event matches this clipboard action.

  • keyboard

    Match one or more keyboard bindings.

  • mouse

    Match a mouse event.

  • click

    Match a button press on a field.

  • focus

    Match a focus transition.

  • clipboard

    Match pasted text.

  • tick

    Match a clock tick.

  • resize

    Match a resize event.

  • request

    Match an HTTP request.

text class-attribute instance-attribute

text: str | None = None

Required clipboard text.

matches

matches(event: Any) -> bool

Return whether an event matches this clipboard action.

Source code in xnano/actions.py
def matches(self, event: Any) -> bool:
    """Return whether an event matches this clipboard action."""
    clipboard = getattr(event, "clipboard_event", event)
    return bool(
        clipboard is not None
        and (
            self.text is None
            or getattr(clipboard, "text", None) == self.text
        )
    )

keyboard classmethod

keyboard(
    *bindings: KeyboardBinding,
    kind: KeyboardEventKind | None = None
) -> "KeyboardAction"

Match one or more keyboard bindings.

Source code in xnano/actions.py
@classmethod
def keyboard(
    cls,
    *bindings: KeyboardBinding,
    kind: KeyboardEventKind | None = None,
) -> "KeyboardAction":
    """Match one or more keyboard bindings."""
    return KeyboardAction(bindings=bindings, kind=kind)

mouse classmethod

mouse(
    *buttons: MouseButton,
    kind: MouseEventKind | None = None
) -> "MouseAction"

Match a mouse event.

Source code in xnano/actions.py
@classmethod
def mouse(
    cls,
    *buttons: MouseButton,
    kind: MouseEventKind | None = None,
) -> "MouseAction":
    """Match a mouse event."""
    return MouseAction(buttons=buttons, kind=kind)

click classmethod

click(
    field: str | None = None, button: MouseButton = "left"
) -> "ClickAction"

Match a button press on a field.

Source code in xnano/actions.py
@classmethod
def click(
    cls,
    field: str | None = None,
    button: MouseButton = "left",
) -> "ClickAction":
    """Match a button press on a field."""
    return ClickAction(field=field, button=button)

focus classmethod

focus(
    field: str | None = None,
    kind: FocusEventKind | None = None,
) -> "FocusAction"

Match a focus transition.

Source code in xnano/actions.py
@classmethod
def focus(
    cls,
    field: str | None = None,
    kind: FocusEventKind | None = None,
) -> "FocusAction":
    """Match a focus transition."""
    return FocusAction(field=field, kind=kind)

clipboard classmethod

clipboard(text: str | None = None) -> 'ClipboardAction'

Match pasted text.

Source code in xnano/actions.py
@classmethod
def clipboard(cls, text: str | None = None) -> "ClipboardAction":
    """Match pasted text."""
    return ClipboardAction(text=text)

tick classmethod

tick(interval_ms: int = 0) -> 'TickAction'

Match a clock tick.

Source code in xnano/actions.py
@classmethod
def tick(cls, interval_ms: int = 0) -> "TickAction":
    """Match a clock tick."""
    return TickAction(interval_ms=interval_ms)

resize classmethod

resize(
    width: int | None = None, height: int | None = None
) -> "ResizeAction"

Match a resize event.

Source code in xnano/actions.py
@classmethod
def resize(
    cls,
    width: int | None = None,
    height: int | None = None,
) -> "ResizeAction":
    """Match a resize event."""
    return ResizeAction(width=width, height=height)

request classmethod

request(method: str, path: str = '/') -> 'RequestAction'

Match an HTTP request.

Source code in xnano/actions.py
@classmethod
def request(cls, method: str, path: str = "/") -> "RequestAction":
    """Match an HTTP request."""
    return RequestAction(method=method.upper(), path=path)

TickAction dataclass

TickAction(interval_ms: int = 0)

Bases: Action

Match a runtime tick.

Attributes:

Methods:

  • matches

    Return whether an event is a runtime tick.

  • keyboard

    Match one or more keyboard bindings.

  • mouse

    Match a mouse event.

  • click

    Match a button press on a field.

  • focus

    Match a focus transition.

  • clipboard

    Match pasted text.

  • tick

    Match a clock tick.

  • resize

    Match a resize event.

  • request

    Match an HTTP request.

interval_ms class-attribute instance-attribute

interval_ms: int = 0

Requested tick interval in milliseconds.

matches

matches(event: Any) -> bool

Return whether an event is a runtime tick.

Source code in xnano/actions.py
def matches(self, event: Any) -> bool:
    """Return whether an event is a runtime tick."""
    tick = getattr(event, "tick_event", event)
    return tick is not None and getattr(tick, "type", None) == "tick"

keyboard classmethod

keyboard(
    *bindings: KeyboardBinding,
    kind: KeyboardEventKind | None = None
) -> "KeyboardAction"

Match one or more keyboard bindings.

Source code in xnano/actions.py
@classmethod
def keyboard(
    cls,
    *bindings: KeyboardBinding,
    kind: KeyboardEventKind | None = None,
) -> "KeyboardAction":
    """Match one or more keyboard bindings."""
    return KeyboardAction(bindings=bindings, kind=kind)

mouse classmethod

mouse(
    *buttons: MouseButton,
    kind: MouseEventKind | None = None
) -> "MouseAction"

Match a mouse event.

Source code in xnano/actions.py
@classmethod
def mouse(
    cls,
    *buttons: MouseButton,
    kind: MouseEventKind | None = None,
) -> "MouseAction":
    """Match a mouse event."""
    return MouseAction(buttons=buttons, kind=kind)

click classmethod

click(
    field: str | None = None, button: MouseButton = "left"
) -> "ClickAction"

Match a button press on a field.

Source code in xnano/actions.py
@classmethod
def click(
    cls,
    field: str | None = None,
    button: MouseButton = "left",
) -> "ClickAction":
    """Match a button press on a field."""
    return ClickAction(field=field, button=button)

focus classmethod

focus(
    field: str | None = None,
    kind: FocusEventKind | None = None,
) -> "FocusAction"

Match a focus transition.

Source code in xnano/actions.py
@classmethod
def focus(
    cls,
    field: str | None = None,
    kind: FocusEventKind | None = None,
) -> "FocusAction":
    """Match a focus transition."""
    return FocusAction(field=field, kind=kind)

clipboard classmethod

clipboard(text: str | None = None) -> 'ClipboardAction'

Match pasted text.

Source code in xnano/actions.py
@classmethod
def clipboard(cls, text: str | None = None) -> "ClipboardAction":
    """Match pasted text."""
    return ClipboardAction(text=text)

tick classmethod

tick(interval_ms: int = 0) -> 'TickAction'

Match a clock tick.

Source code in xnano/actions.py
@classmethod
def tick(cls, interval_ms: int = 0) -> "TickAction":
    """Match a clock tick."""
    return TickAction(interval_ms=interval_ms)

resize classmethod

resize(
    width: int | None = None, height: int | None = None
) -> "ResizeAction"

Match a resize event.

Source code in xnano/actions.py
@classmethod
def resize(
    cls,
    width: int | None = None,
    height: int | None = None,
) -> "ResizeAction":
    """Match a resize event."""
    return ResizeAction(width=width, height=height)

request classmethod

request(method: str, path: str = '/') -> 'RequestAction'

Match an HTTP request.

Source code in xnano/actions.py
@classmethod
def request(cls, method: str, path: str = "/") -> "RequestAction":
    """Match an HTTP request."""
    return RequestAction(method=method.upper(), path=path)

ResizeAction dataclass

ResizeAction(
    width: int | None = None, height: int | None = None
)

Bases: Action

Match viewport dimensions.

Attributes:

  • width (int | None) –

    Required viewport width, or any width.

  • height (int | None) –

    Required viewport height, or any height.

Methods:

  • matches

    Return whether an event matches these viewport dimensions.

  • keyboard

    Match one or more keyboard bindings.

  • mouse

    Match a mouse event.

  • click

    Match a button press on a field.

  • focus

    Match a focus transition.

  • clipboard

    Match pasted text.

  • tick

    Match a clock tick.

  • resize

    Match a resize event.

  • request

    Match an HTTP request.

width class-attribute instance-attribute

width: int | None = None

Required viewport width.

height class-attribute instance-attribute

height: int | None = None

Required viewport height.

matches

matches(event: Any) -> bool

Return whether an event matches these viewport dimensions.

Source code in xnano/actions.py
def matches(self, event: Any) -> bool:
    """Return whether an event matches these viewport dimensions."""
    resize = getattr(event, "resize_event", event)
    return bool(
        resize is not None
        and (
            self.width is None
            or getattr(resize, "width", None) == self.width
        )
        and (
            self.height is None
            or getattr(resize, "height", None) == self.height
        )
    )

keyboard classmethod

keyboard(
    *bindings: KeyboardBinding,
    kind: KeyboardEventKind | None = None
) -> "KeyboardAction"

Match one or more keyboard bindings.

Source code in xnano/actions.py
@classmethod
def keyboard(
    cls,
    *bindings: KeyboardBinding,
    kind: KeyboardEventKind | None = None,
) -> "KeyboardAction":
    """Match one or more keyboard bindings."""
    return KeyboardAction(bindings=bindings, kind=kind)

mouse classmethod

mouse(
    *buttons: MouseButton,
    kind: MouseEventKind | None = None
) -> "MouseAction"

Match a mouse event.

Source code in xnano/actions.py
@classmethod
def mouse(
    cls,
    *buttons: MouseButton,
    kind: MouseEventKind | None = None,
) -> "MouseAction":
    """Match a mouse event."""
    return MouseAction(buttons=buttons, kind=kind)

click classmethod

click(
    field: str | None = None, button: MouseButton = "left"
) -> "ClickAction"

Match a button press on a field.

Source code in xnano/actions.py
@classmethod
def click(
    cls,
    field: str | None = None,
    button: MouseButton = "left",
) -> "ClickAction":
    """Match a button press on a field."""
    return ClickAction(field=field, button=button)

focus classmethod

focus(
    field: str | None = None,
    kind: FocusEventKind | None = None,
) -> "FocusAction"

Match a focus transition.

Source code in xnano/actions.py
@classmethod
def focus(
    cls,
    field: str | None = None,
    kind: FocusEventKind | None = None,
) -> "FocusAction":
    """Match a focus transition."""
    return FocusAction(field=field, kind=kind)

clipboard classmethod

clipboard(text: str | None = None) -> 'ClipboardAction'

Match pasted text.

Source code in xnano/actions.py
@classmethod
def clipboard(cls, text: str | None = None) -> "ClipboardAction":
    """Match pasted text."""
    return ClipboardAction(text=text)

tick classmethod

tick(interval_ms: int = 0) -> 'TickAction'

Match a clock tick.

Source code in xnano/actions.py
@classmethod
def tick(cls, interval_ms: int = 0) -> "TickAction":
    """Match a clock tick."""
    return TickAction(interval_ms=interval_ms)

resize classmethod

resize(
    width: int | None = None, height: int | None = None
) -> "ResizeAction"

Match a resize event.

Source code in xnano/actions.py
@classmethod
def resize(
    cls,
    width: int | None = None,
    height: int | None = None,
) -> "ResizeAction":
    """Match a resize event."""
    return ResizeAction(width=width, height=height)

request classmethod

request(method: str, path: str = '/') -> 'RequestAction'

Match an HTTP request.

Source code in xnano/actions.py
@classmethod
def request(cls, method: str, path: str = "/") -> "RequestAction":
    """Match an HTTP request."""
    return RequestAction(method=method.upper(), path=path)

RequestAction dataclass

RequestAction(method: str, path: str = '/')

Bases: Action

Match an HTTP method and path.

Attributes:

  • method (str) –

    Required uppercase HTTP method.

  • path (str) –

    Required normalized request path.

Methods:

  • matches

    Return whether an event matches this request route.

  • keyboard

    Match one or more keyboard bindings.

  • mouse

    Match a mouse event.

  • click

    Match a button press on a field.

  • focus

    Match a focus transition.

  • clipboard

    Match pasted text.

  • tick

    Match a clock tick.

  • resize

    Match a resize event.

  • request

    Match an HTTP request.

method instance-attribute

method: str

Required uppercase HTTP method.

path class-attribute instance-attribute

path: str = '/'

Required normalized request path.

matches

matches(event: Any) -> bool

Return whether an event matches this request route.

Source code in xnano/actions.py
def matches(self, event: Any) -> bool:
    """Return whether an event matches this request route."""
    request = getattr(event, "request", event)
    return bool(
        request is not None
        and str(getattr(request, "method", "")).upper() == self.method
        and getattr(request, "path", None) == self.path
    )

keyboard classmethod

keyboard(
    *bindings: KeyboardBinding,
    kind: KeyboardEventKind | None = None
) -> "KeyboardAction"

Match one or more keyboard bindings.

Source code in xnano/actions.py
@classmethod
def keyboard(
    cls,
    *bindings: KeyboardBinding,
    kind: KeyboardEventKind | None = None,
) -> "KeyboardAction":
    """Match one or more keyboard bindings."""
    return KeyboardAction(bindings=bindings, kind=kind)

mouse classmethod

mouse(
    *buttons: MouseButton,
    kind: MouseEventKind | None = None
) -> "MouseAction"

Match a mouse event.

Source code in xnano/actions.py
@classmethod
def mouse(
    cls,
    *buttons: MouseButton,
    kind: MouseEventKind | None = None,
) -> "MouseAction":
    """Match a mouse event."""
    return MouseAction(buttons=buttons, kind=kind)

click classmethod

click(
    field: str | None = None, button: MouseButton = "left"
) -> "ClickAction"

Match a button press on a field.

Source code in xnano/actions.py
@classmethod
def click(
    cls,
    field: str | None = None,
    button: MouseButton = "left",
) -> "ClickAction":
    """Match a button press on a field."""
    return ClickAction(field=field, button=button)

focus classmethod

focus(
    field: str | None = None,
    kind: FocusEventKind | None = None,
) -> "FocusAction"

Match a focus transition.

Source code in xnano/actions.py
@classmethod
def focus(
    cls,
    field: str | None = None,
    kind: FocusEventKind | None = None,
) -> "FocusAction":
    """Match a focus transition."""
    return FocusAction(field=field, kind=kind)

clipboard classmethod

clipboard(text: str | None = None) -> 'ClipboardAction'

Match pasted text.

Source code in xnano/actions.py
@classmethod
def clipboard(cls, text: str | None = None) -> "ClipboardAction":
    """Match pasted text."""
    return ClipboardAction(text=text)

tick classmethod

tick(interval_ms: int = 0) -> 'TickAction'

Match a clock tick.

Source code in xnano/actions.py
@classmethod
def tick(cls, interval_ms: int = 0) -> "TickAction":
    """Match a clock tick."""
    return TickAction(interval_ms=interval_ms)

resize classmethod

resize(
    width: int | None = None, height: int | None = None
) -> "ResizeAction"

Match a resize event.

Source code in xnano/actions.py
@classmethod
def resize(
    cls,
    width: int | None = None,
    height: int | None = None,
) -> "ResizeAction":
    """Match a resize event."""
    return ResizeAction(width=width, height=height)

request classmethod

request(method: str, path: str = '/') -> 'RequestAction'

Match an HTTP request.

Source code in xnano/actions.py
@classmethod
def request(cls, method: str, path: str = "/") -> "RequestAction":
    """Match an HTTP request."""
    return RequestAction(method=method.upper(), path=path)

Actions

Actions(runtime: Any)

Perform actions through a runtime.

Attributes:

  • runtime

    Runtime that receives performed actions.

Examples:

terminal.actions.keyboard("ctrl+s")
terminal.actions.click("submit")

Methods:

  • perform

    Queue or dispatch an action.

  • keyboard

    Perform keyboard actions.

  • click

    Perform a click action.

  • request

    Perform an HTTP request action.

Source code in xnano/actions.py
def __init__(self, runtime: Any) -> None:
    self._runtime = runtime

perform

perform(action: Action) -> None

Queue or dispatch an action.

Source code in xnano/actions.py
def perform(self, action: Action) -> None:
    """Queue or dispatch an action."""
    self._runtime.perform(action)

keyboard

keyboard(
    *bindings: KeyboardBinding,
    kind: KeyboardEventKind = "press"
) -> None

Perform keyboard actions.

Source code in xnano/actions.py
def keyboard(
    self,
    *bindings: KeyboardBinding,
    kind: KeyboardEventKind = "press",
) -> None:
    """Perform keyboard actions."""
    for binding in bindings:
        self.perform(Action.keyboard(binding, kind=kind))

click

click(
    field: str | None = None, button: MouseButton = "left"
) -> None

Perform a click action.

Source code in xnano/actions.py
def click(
    self,
    field: str | None = None,
    button: MouseButton = "left",
) -> None:
    """Perform a click action."""
    self.perform(Action.click(field, button))

request

request(method: str, path: str = '/') -> None

Perform an HTTP request action.

Source code in xnano/actions.py
def request(self, method: str, path: str = "/") -> None:
    """Perform an HTTP request action."""
    self.perform(Action.request(method, path))

normalize_binding cached

normalize_binding(binding: str) -> NormalizedBinding | None

Normalize a ctrl+shift+k style binding.

Source code in xnano/actions.py
@functools.lru_cache(maxsize=512)
def normalize_binding(binding: str) -> NormalizedBinding | None:
    """Normalize a ``ctrl+shift+k`` style binding."""
    parts = [
        part.strip().lower() for part in binding.split("+") if part.strip()
    ]
    if not parts:
        return None
    return (
        frozenset(
            part for part in parts[:-1] if part in ("ctrl", "alt", "shift")
        ),
        _KEY_ALIASES.get(parts[-1], parts[-1]),
    )