_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
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)]
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):
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