Files
t-deckard/deck/chat.py
T

60 lines
2.1 KiB
Python

# deck.chat: T-Deck generic chat UI helper library for CircuitPython
# Depends on tdeck_repl for providing working input on T-Decks
#
# Created by Luxferre in 2025, released into public domain
from deck.input import input
from deck.pager import print_paged
class DeckChat:
def __init__(self, start_state={}, chat_prefix='> ', command_prefix='/'):
"""Init the chat class"""
self.command_prefix = command_prefix # prefix that commands start with
self.chat_prefix = chat_prefix # prefix to write before input
self.command_handlers = { # command handler storage
'default': lambda m,s: (m,s) # echo handler by default
}
self.state = start_state # internal state object (impl-specific)
def command(self, command, handler):
"""
Register a new handler inside the chat instance.
The handler accepts two parameters: a message and a state object,
and returns the response and the new state object.
If the returned state object is None, then the chat loop exits.
Non-command handler is registered under the 'default' command.
"""
cmd = command.strip().lower()
if cmd.startswith(self.command_prefix):
cmd = cmd[1:]
self.command_handlers[cmd] = handler
def _detect_command(self, msg):
"""
Split a chat line into the command (or 'default' if none detected)
and the rest of the message.
"""
res = ('default', msg)
if msg.startswith(self.command_prefix):
parts = msg.split(' ')
cmd = parts[0].lower().strip()[1:]
arg = ' '.join(parts[1:]).strip() if len(parts) > 1 else None
if cmd in self.command_handlers:
res = (cmd, arg)
return res
def start(self):
"""Start the chat loop"""
while True:
try:
input_msg = input(self.chat_prefix).strip()
if len(input_msg) == 0: continue
cmd, msg = self._detect_command(input_msg)
output, self.state = self.command_handlers[cmd](msg, self.state)
print_paged(output.strip())
if self.state is None:
break
except (KeyboardInterrupt, EOFError):
print()
break