From d4a726fd3733589e13615f86cf2fd1a824d3fd2d Mon Sep 17 00:00:00 2001 From: Christian Heller Date: Wed, 11 Jun 2025 15:46:53 +0200 Subject: [PATCH] Refactor prompt geometry calculations. --- ircplom.py | 51 ++++++++++++++++++++++----------------------------- 1 file changed, 22 insertions(+), 29 deletions(-) diff --git a/ircplom.py b/ircplom.py index 2280276..50a916a 100755 --- a/ircplom.py +++ b/ircplom.py @@ -542,12 +542,12 @@ class PromptWidget(ScrollableWidget): _width: int _prompt: str = PROMPT_TEMPLATE _history_idx = 0 + _input_buffer: str _cursor_x: int def __init__(self, *args, **kwargs) -> None: super().__init__(*args, **kwargs) - self._clear() - self._input_buffer = '' + self._reset_buffer('') def set_geometry(self, measurements: YX) -> None: self._y, self._width = measurements @@ -558,27 +558,25 @@ class PromptWidget(ScrollableWidget): def append(self, to_append: str) -> None: self._cursor_x += len(to_append) - self._input_buffer = (self._input_buffer[:self._cursor_x - 2] + self._input_buffer = (self._input_buffer[:self._cursor_x - 1] + to_append - + self._input_buffer[self._cursor_x - 2:]) + + self._input_buffer[self._cursor_x - 1:]) self._history_idx = 0 self.draw() def draw(self) -> None: prefix = self._prompt[:] content = self._input_buffer[:] - if self._cursor_x > len(self._input_buffer): + if self._cursor_x == len(self._input_buffer): content += ' ' - half_width = self._width // 2 + half_width = (self._width - len(prefix)) // 2 offset = 0 if len(prefix) + len(content) > self._width\ and self._cursor_x > half_width: prefix += PROMPT_ELL_IN - if self._cursor_x > len(content) - half_width: - offset = len(content) - self._width + len(prefix) - else: - offset = self._cursor_x - half_width + (len(prefix) // 2) - cursor_x_to_write = len(prefix) - 1 + self._cursor_x - offset + offset = min(len(prefix) + len(content) - self._width, + self._cursor_x - half_width + len(PROMPT_ELL_IN)) + cursor_x_to_write = len(prefix) + self._cursor_x - offset to_write = f'{prefix}{content[offset:]}' if len(to_write) > self._width: to_write = (to_write[:self._width - len(PROMPT_ELL_OUT)] @@ -589,41 +587,36 @@ class PromptWidget(ScrollableWidget): self._write(to_write[cursor_x_to_write + 1:]) def _scroll(self, up: bool = True) -> None: - - def set_to_record_at_idx() -> None: - self._input_buffer = self._history[self._history_idx][:] - self._cursor_x = len(self._input_buffer) + 1 - if up and -(self._history_idx) < len(self._history): if self._history_idx == 0 and self._input_buffer: self._history += [self._input_buffer[:]] - self._clear() + self._reset_buffer('') self._history_idx -= 1 self._history_idx -= 1 - set_to_record_at_idx() + self._reset_buffer(self._history[self._history_idx]) elif not up: if self._history_idx < 0: self._history_idx += 1 if self._history_idx == 0: - self._clear() + self._reset_buffer('') else: - set_to_record_at_idx() + self._reset_buffer(self._history[self._history_idx]) elif self._input_buffer: self._history += [self._input_buffer[:]] - self._clear() + self._reset_buffer('') def cmd__backspace(self) -> None: 'Truncate current content by one character, if possible.' - if self._cursor_x > 1: + if self._cursor_x > 0: self._cursor_x -= 1 - self._input_buffer = (self._input_buffer[:self._cursor_x - 1] - + self._input_buffer[self._cursor_x:]) + self._input_buffer = (self._input_buffer[:self._cursor_x] + + self._input_buffer[self._cursor_x + 1:]) self._history_idx = 0 self.draw() def cmd__move_cursor(self, direction: str) -> None: 'Move cursor one space into direction ("left" or "right") if possible.' - if direction == 'left' and self._cursor_x > 1: + if direction == 'left' and self._cursor_x > 0: self._cursor_x -= 1 elif direction == 'right'\ and self._cursor_x <= len(self._input_buffer): @@ -632,16 +625,16 @@ class PromptWidget(ScrollableWidget): return self.draw() - def _clear(self) -> None: - self._input_buffer = '' - self._cursor_x = len(self._input_buffer) + 1 + def _reset_buffer(self, content: str) -> None: + self._input_buffer = content + self._cursor_x = len(self._input_buffer) def enter(self) -> str: 'Return current content while also clearing and then redrawing.' to_return = self._input_buffer[:] if to_return: self._history += [to_return] - self._clear() + self._reset_buffer('') self.draw() return to_return -- 2.30.2