Source code for conntextual.ui.channel.log
"""
A module impementing a channel-environment log widget.
"""
# built-in
from logging import ERROR, INFO, Formatter, Logger
from typing import Optional
# third-party
from textual import on
from textual.app import ComposeResult
from textual.binding import Binding
from textual.widgets import Input, Log, Static
from vcorelib.logging import (
DEFAULT_TIME_FORMAT,
LoggerType,
LogRecordQueue,
queue_handler,
)
# internal
from conntextual.ui.channel.suggester import CommandSuggester
from conntextual.util import css_name
MAX_LINES = 1000
[docs]
class InputWithHistory(Input):
"""An input with last-command history."""
BINDINGS = [Binding("up", "previous_command", "previous command")]
previous: str
[docs]
def action_previous_command(self) -> None:
"""Go back to the previous command."""
if self.previous:
self.value = self.previous
self.action_end()
self.refresh()
[docs]
class ChannelEnvironmentLog(Static):
"""A channel-environment log widget."""
parent_name: str
logger: LoggerType
queue: LogRecordQueue
suggester: Optional[CommandSuggester]
[docs]
def dispatch(self) -> None:
"""Dispatch the log updater."""
log = self.query_one(Log)
while not self.queue.empty():
log.write_line(self.queue.get_nowait().getMessage())
[docs]
@on(Input.Submitted)
def handle_submit(self, event: Input.Submitted) -> None:
"""Handle input submission."""
self.query_one(InputWithHistory).previous = event.value
assert self.suggester is not None
result = self.suggester.processor.command(event.value)
self.logger.log(
INFO if result else ERROR, "%s: %s", event.value, result
)
# Reset input.
node = self.query_one(Input)
node.action_home()
node.action_delete_right_all()
[docs]
def compose(self) -> ComposeResult:
"""Create child nodes."""
# Initialize logger handling.
self.queue, handler = queue_handler(self.logger, root_formatter=False)
handler.setFormatter(Formatter(DEFAULT_TIME_FORMAT))
if self.logger is not Logger.root:
self.logger.info("Queue handler initialized.")
if self.suggester is not None:
input_box = InputWithHistory(
"set ",
classes="command_input",
suggester=self.suggester,
id=f"{css_name(self.parent_name)}-input",
)
input_box.previous = ""
yield input_box
yield Log(classes="log", max_lines=MAX_LINES)