diff --git a/src/cmdforge/cli/picker.py b/src/cmdforge/cli/picker.py index 1e52f06..3740d00 100644 --- a/src/cmdforge/cli/picker.py +++ b/src/cmdforge/cli/picker.py @@ -112,6 +112,7 @@ def run_picker() -> Optional[PickerResult]: query = "" selected = 0 + scroll = 0 last_drawn = 0 print(HIDE_CURSOR, end='', flush=True) @@ -133,21 +134,28 @@ def run_picker() -> Optional[PickerResult]: if selected >= len(filtered): selected = max(0, len(filtered) - 1) + # Adjust scroll to keep selection visible + if selected < scroll: + scroll = selected + elif selected >= scroll + MAX_VISIBLE: + scroll = selected - MAX_VISIBLE + 1 + # Clear previous if last_drawn: clear_dropdown(last_drawn) # Draw - visible = filtered[:MAX_VISIBLE] + visible = filtered[scroll:scroll + MAX_VISIBLE] lines = [] # Query line - prompt = f"{DIM}>{RESET} {YELLOW}{query}{RESET}{'▌' if True else ''}" + prompt = f"{DIM}>{RESET} {YELLOW}{query}{RESET}▌" lines.append(prompt) # Items for i, t in enumerate(visible): - if i == selected: + actual_idx = scroll + i + if actual_idx == selected: prefix = f"{CYAN}{BOLD}▸ {t['name']}{RESET}" else: prefix = f" {t['name']}" @@ -162,10 +170,6 @@ def run_picker() -> Optional[PickerResult]: lines.append(prefix) - # Show count if more - if len(filtered) > MAX_VISIBLE: - lines.append(f"{DIM} ... +{len(filtered) - MAX_VISIBLE} more{RESET}") - # Print sys.stdout.write('\n'.join(lines) + '\n') sys.stdout.flush() @@ -204,10 +208,12 @@ def run_picker() -> Optional[PickerResult]: elif ch == '\x7f' or ch == '\b': # Backspace query = query[:-1] selected = 0 + scroll = 0 elif ch.isprintable(): query += ch selected = 0 + scroll = 0 except Exception as e: print(SHOW_CURSOR, end='', flush=True)