Initial ai typewriter implementation

This commit is contained in:
Edern Deneuville
2026-09-11 12:00:05 +02:00
parent 3073beb5e7
commit c6b49af74d
+59
View File
@@ -0,0 +1,59 @@
from __future__ import annotations
from dataclasses import dataclass, field
from threading import Lock
from typing import Optional
import keyboard
@dataclass
class KeyStepper:
text: str
delay: float = 0.0
_index: int = 0
_hook: Optional[object] = None
_lock: Lock = field(default_factory=Lock)
_injecting: bool = False
def start(self) -> None:
if not self.text:
return
if self._hook is not None:
return
# suppress=True blocks the physical key while the callback types the next AI character.
self._hook = keyboard.hook(self._on_event, suppress=True)
def stop(self) -> None:
hook = self._hook
self._hook = None
if hook is not None:
keyboard.unhook(hook)
def _on_event(self, event: keyboard.KeyboardEvent) -> None:
if self._injecting or event.event_type != keyboard.KEY_DOWN:
return
with self._lock:
if self._index >= len(self.text):
self.stop()
return
char = self.text[self._index]
self._index += 1
self._injecting = True
try:
self._type_char(char)
finally:
self._injecting = False
if self._index >= len(self.text):
self.stop()
def _type_char(self, char: str) -> None:
if char == "\n":
keyboard.send("enter")
elif char == "\t":
keyboard.send("tab")
else:
keyboard.write(char, delay=self.delay, exact=True)