From: Christian Heller Date: Mon, 9 Jun 2025 13:37:06 +0000 (+0200) Subject: Refactor Terminal.write_yx() into more flexible Terminal.write(). X-Git-Url: https://plomlompom.com/repos/%7B%7Bprefix%7D%7D/%22https:/validator.w3.org/template?a=commitdiff_plain;h=53a877c32683c88ffb33741ee4620c8e55ecd54a;p=ircplom Refactor Terminal.write_yx() into more flexible Terminal.write(). --- diff --git a/ircplom.py b/ircplom.py index 5a85656..bffd3c2 100755 --- a/ircplom.py +++ b/ircplom.py @@ -77,6 +77,7 @@ class Terminal: size: YX tui: 'TuiLoop' _blessed: BlessedTerminal + _cursor_yx_: YX @contextmanager def context(self, q_to_main: EventQueue) -> Generator: @@ -87,9 +88,19 @@ class Terminal: self._blessed.fullscreen(), self._blessed.hidden_cursor(), KeyboardLoop(q_to_main, self.get_keypresses())): + self._cursor_yx = YX(0, 0) with TuiLoop(self, q_to_main) as self.tui: yield self + @property + def _cursor_yx(self) -> YX: + return self._cursor_yx_ + + @_cursor_yx.setter + def _cursor_yx(self, yx: YX) -> None: + print(self._blessed.move_yx(yx.y, yx.x), end='') + self._cursor_yx_ = yx + def calc_geometry(self) -> None: '(Re-)calculate .size..' self.size = YX(self._blessed.height, self._blessed.width) @@ -107,17 +118,28 @@ class Terminal: return self._blessed.wrap(line, width=self.size.x, subsequent_indent=' '*4) - def write_yx(self, offset: YX, msg: str) -> None: - 'Starting at offset, write line with msg, padded at end with spaces.' - print(self._blessed.move_yx(offset.y, offset.x), end='') - # ._blessed.length can slow down things notably, only use where needed - len_with_offset = offset.x + (len(msg) if msg.isascii() - else self._blessed.length(msg)) - if len_with_offset > self.size.x: - print(self._blessed.truncate(msg, self.size.x - offset.x), end='') - else: - len_padding = self.size.x - len_with_offset - print(msg + (' ' * len_padding), end='') + def write(self, + msg: str = '', + start_y: Optional[int] = None, + attribute: Optional[str] = None, + padding: bool = True + ) -> None: + 'Print to terminal, with position, padding to line end, attributes.' + if start_y: + self._cursor_yx = YX(start_y, 0) + # ._blessed.length can slow down things notably: only use where needed! + end_x = self._cursor_yx.x + (len(msg) if msg.isascii() + else self._blessed.length(msg)) + len_padding = self.size.x - end_x + if len_padding < 0: + msg = self._blessed.truncate(msg, self.size.x - self._cursor_yx.x) + elif padding: + msg += ' ' * len_padding + end_x = self.size.x + if attribute: + msg = getattr(self._blessed, attribute)(msg) + print(msg, end='') + self._cursor_yx = YX(self._cursor_yx.y, end_x) def get_keypresses(self) -> Iterator[str]: '''Loop through keypresses from terminal, collect what blessed ignores. @@ -466,8 +488,9 @@ class ScrollableWidget(Widget): 'Defines some API shared between PromptWidget and LogWidget.' _history_idx: int - def __init__(self, write_yx: Callable[[YX, str], None]) -> None: - self._write_yx = write_yx + def __init__(self, write: Callable[..., None], *args, **kwargs) -> None: + super().__init__(*args, **kwargs) + self._write = write self._history: list[str] = [] @abstractmethod @@ -514,7 +537,7 @@ class PromptWidget(ScrollableWidget): break offset += len_too_much prompt = f'<{offset}|{prompt_template}…' - self._write_yx(YX(self._y, 0), to_write) + self._write(to_write, self._y) def _scroll(self, up: bool = True) -> None: if up and -(self._history_idx) < len(self._history): @@ -604,7 +627,7 @@ class LogWidget(ScrollableWidget): else: to_write += [self._wrapped[self._wrapped_idx][1]] for i, line in enumerate(to_write): - self._write_yx(YX(i, 0), line) + self._write(line, i) def _scroll(self, up: bool = True) -> None: if up: @@ -625,8 +648,8 @@ class Window(Widget): def __init__(self, idx: int, term: Terminal) -> None: self.idx = idx self._term = term - self.log = LogWidget(self._term.wrap, self._term.write_yx) - self.prompt = PromptWidget(self._term.write_yx) + self.log = LogWidget(self._term.wrap, self._term.write) + self.prompt = PromptWidget(self._term.write) if hasattr(self._term, 'size'): self.set_geometry() @@ -641,12 +664,12 @@ class Window(Widget): status_line = idx_box + '=' * (self._term.size.x - len(idx_box)) self._term.clear() self.log.draw() - self._term.write_yx(YX(self._y_status, 0), status_line) + self._term.write(status_line, self._y_status) self.prompt.draw() def cmd__paste(self) -> None: 'Write OSC 52 ? sequence to get encoded clipboard paste into stdin.' - self._term.write_yx(YX(self._y_status, 0), f'\033{OSC_52_PREFIX}?\007') + self._term.write(f'\033{OSC_52_PREFIX}?\007', self._y_status) self.draw()