From d387a138558c9c023e3a885e3ae124d37db013ad Mon Sep 17 00:00:00 2001 From: xbl Date: Tue, 23 Dec 2025 22:32:49 +0100 Subject: [PATCH] laul --- .gitignore | 1 + ui.py | 104 +++++++++++++++++++++++++++++++++++++++++++++++------ 2 files changed, 95 insertions(+), 10 deletions(-) diff --git a/.gitignore b/.gitignore index 47d4bab..b0f7d02 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,4 @@ __pycache__/ venv3/ *.log +cvarlist.txt diff --git a/ui.py b/ui.py index b8deae9..7e2e356 100644 --- a/ui.py +++ b/ui.py @@ -82,6 +82,8 @@ class UIManager: self.input_window = None self.divider_window = None self.input_queue = None + self.command_history = [] + self.history_index = -1 self._init_curses() self._create_windows() @@ -142,6 +144,8 @@ class UIManager: maxy - 2, 4 ) + self.input_window.keypad(True) + self.input_window.nodelay(False) self.screen.addstr(maxy - 2, 2, '$ ') self.input_window.idlok(True) self.input_window.leaveok(False) @@ -160,20 +164,100 @@ class UIManager: self.screen.refresh() def setup_input_queue(self): - """Setup threaded input queue""" - def wait_stdin(q, window): + """Setup threaded input queue with command history""" + def wait_stdin(q, window, manager): + current_input = "" + cursor_pos = 0 + temp_history_index = -1 + temp_input = "" # Temp storage when navigating history + while True: - line = curses.textpad.Textbox(window).edit() - if len(line) > 0: - q.put(line) - window.clear() - window.refresh() - + try: + key = window.getch() + + if key == -1: # No input + continue + + # Enter key + if key in (curses.KEY_ENTER, 10, 13): + if len(current_input) > 0: + # Add to history + manager.command_history.append(current_input) + if len(manager.command_history) > 10: + manager.command_history.pop(0) + + q.put(current_input) + current_input = "" + cursor_pos = 0 + temp_history_index = -1 + temp_input = "" + window.clear() + window.refresh() + + # Arrow UP - previous command + elif key == curses.KEY_UP: + if len(manager.command_history) > 0: + # Save current input when first entering history + if temp_history_index == -1: + temp_input = current_input + temp_history_index = len(manager.command_history) + + if temp_history_index > 0: + temp_history_index -= 1 + current_input = manager.command_history[temp_history_index] + cursor_pos = len(current_input) + window.clear() + window.addstr(0, 0, current_input) + window.refresh() + + # Arrow DOWN - next command + elif key == curses.KEY_DOWN: + if temp_history_index != -1: + temp_history_index += 1 + if temp_history_index >= len(manager.command_history): + # Restore temp input + current_input = temp_input + temp_history_index = -1 + temp_input = "" + else: + current_input = manager.command_history[temp_history_index] + + cursor_pos = len(current_input) + window.clear() + window.addstr(0, 0, current_input) + window.refresh() + + # Backspace + elif key in (curses.KEY_BACKSPACE, 127, 8): + if cursor_pos > 0: + current_input = current_input[:cursor_pos-1] + current_input[cursor_pos:] + cursor_pos -= 1 + temp_history_index = -1 # Exit history mode + window.clear() + window.addstr(0, 0, current_input) + window.move(0, cursor_pos) + window.refresh() + + # Regular character + elif 32 <= key <= 126: + char = chr(key) + current_input = current_input[:cursor_pos] + char + current_input[cursor_pos:] + cursor_pos += 1 + temp_history_index = -1 # Exit history mode + window.clear() + window.addstr(0, 0, current_input) + window.move(0, cursor_pos) + window.refresh() + + except Exception as e: + import logging + logging.getLogger('ui').error(f'Input error: {e}') + self.input_queue = queue.Queue() - t = threading.Thread(target=wait_stdin, args=(self.input_queue, self.input_window)) + t = threading.Thread(target=wait_stdin, args=(self.input_queue, self.input_window, self)) t.daemon = True t.start() - + return self.input_queue def setup_logging(self):