diff --git a/src/vban_tui/history.py b/src/vban_tui/history.py new file mode 100644 index 0000000..6a33598 --- /dev/null +++ b/src/vban_tui/history.py @@ -0,0 +1,23 @@ +from collections import UserList + + +class CommandHistory(UserList): + """A simple list to store command history.""" + + def add(self, command: str): + """Add a command to the history if it's not empty and not a duplicate of the last.""" + command = command.strip() + if command and (not self.data or command != self.data[-1]): + self.data.append(command) + + def get_previous(self, index: int) -> str: + """Get the previous command based on the current index.""" + if 0 <= index < len(self.data): + return self.data[index] + return '' + + def get_next(self, index: int) -> str: + """Get the next command based on the current index.""" + if 0 <= index < len(self.data): + return self.data[index] + return '' diff --git a/src/vban_tui/tui.py b/src/vban_tui/tui.py index 879cf41..38a3407 100644 --- a/src/vban_tui/tui.py +++ b/src/vban_tui/tui.py @@ -3,6 +3,7 @@ from textual.app import App, ComposeResult from textual.containers import Grid from textual.widgets import RichLog +from .history import CommandHistory from .hybrid import LabelInput from .settings import Settings @@ -15,6 +16,8 @@ class VbanTui(App): def __init__(self): super().__init__() self._settings = Settings() + self._command_history = CommandHistory() + self._history_index = None def compose(self) -> ComposeResult: """Create child widgets for the app.""" @@ -61,17 +64,46 @@ class VbanTui(App): def on_key(self, event): """Handle key events.""" + request_input = self.query_one('#request-input') match event.key: case 'q': self.exit() - case 'enter' if self.query_one('#request-input').has_focus: - self.query_one('#response-log').clear() - request_input = self.query_one('#request-input') + case 'enter' if request_input.has_focus: request_input.add_class('request-sent') self.send_request() self.set_timer(0.5, lambda: request_input.remove_class('request-sent')) + value = request_input.value.strip() + if value: + self._command_history.add(value) + self._history_index = None + self.query_one('#request-input').clear() + case 'up' if request_input.has_focus: + if self._command_history: + if self._history_index is None: + self._history_index = len(self._command_history) - 1 + elif self._history_index > 0: + self._history_index -= 1 + request_input.value = self._command_history.get_previous( + self._history_index + ) + case 'down' if request_input.has_focus: + if self._command_history and self._history_index is not None: + if self._history_index < len(self._command_history) - 1: + self._history_index += 1 + request_input.value = self._command_history.get_next( + self._history_index + ) + else: + self._history_index = None + request_input.value = '' + def send_request(self): + request = self.query_one('#request-input').value.strip() + if request == 'clear': + self.query_one('#response-log').clear() + return + with vban_cmd.api( 'potato', host=self.query_one('#host-input').value, @@ -79,7 +111,7 @@ class VbanTui(App): streamname=self.query_one('#streamname-input').value, disable_rt_listeners=True, ) as vban: - if response := vban.sendtext(self.query_one('#request-input').value): + if response := vban.sendtext(request): self.query_one('#response-log').write(response)