Skip to content

Commit 4d2aa6f

Browse files
committed
Make the first tab press actually select the first menu item for the TUI completion bar
1 parent b6616b5 commit 4d2aa6f

1 file changed

Lines changed: 30 additions & 7 deletions

File tree

aider/tui/widgets/completion_bar.py

Lines changed: 30 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,10 @@ class CompletionBar(Widget, can_focus=False):
4444
text-style: bold;
4545
}
4646
47+
CompletionBar .completion-item.preselected {
48+
color: $secondary;
49+
}
50+
4751
CompletionBar .completion-more {
4852
width: auto;
4953
height: 1;
@@ -82,6 +86,7 @@ def __init__(self, suggestions: list[str] = None, prefix: str = "", **kwargs):
8286
self.suggestions = (suggestions or [])[: self.MAX_SUGGESTIONS]
8387
self.prefix = prefix
8488
self.selected_index = 0
89+
self._has_cycled = False # Track if user has actively cycled through suggestions
8590
self._item_widgets: list[Static] = []
8691
self._prefix_widget: Static | None = None
8792
self._left_more: Static | None = None
@@ -150,7 +155,8 @@ def compose(self) -> ComposeResult:
150155
self._item_widgets = []
151156
for i in range(self.WINDOW_SIZE):
152157
if i < len(self._display_names):
153-
classes = "completion-item selected" if i == 0 else "completion-item"
158+
selected_class = "selected" if self._has_cycled else "preselected"
159+
classes = f"completion-item {selected_class}" if i == 0 else "completion-item"
154160
item = Static(self._display_names[i], classes=classes)
155161
else:
156162
item = Static("", classes="completion-item")
@@ -173,6 +179,7 @@ def update_suggestions(self, suggestions: list[str], prefix: str = "") -> None:
173179
self.suggestions = suggestions[: self.MAX_SUGGESTIONS]
174180
self.prefix = prefix
175181
self.selected_index = 0
182+
self._has_cycled = False # Reset cycling flag when suggestions change
176183

177184
# Recompute display names
178185
self._compute_display_names()
@@ -267,12 +274,20 @@ def _set_selection_classes(self) -> None:
267274
for i, item in enumerate(self._item_widgets):
268275
if not item.display:
269276
item.remove_class("selected")
277+
item.remove_class("preselected")
270278
continue
271279
# First item is always the selected one
272280
if i == 0:
273-
item.add_class("selected")
281+
# Use "preselected" style if we haven't cycled yet and are at index 0
282+
if not self._has_cycled and self.selected_index == 0:
283+
item.add_class("preselected")
284+
item.remove_class("selected")
285+
else:
286+
item.add_class("selected")
287+
item.remove_class("preselected")
274288
else:
275289
item.remove_class("selected")
290+
item.remove_class("preselected")
276291

277292
def _update_selection(self) -> None:
278293
"""Update visual selection state."""
@@ -284,16 +299,24 @@ def _update_selection(self) -> None:
284299
def cycle_next(self) -> None:
285300
"""Cycle to next suggestion."""
286301
if self.suggestions:
287-
self.selected_index = (self.selected_index + 1) % len(self.suggestions)
302+
if not self._has_cycled:
303+
self._has_cycled = True # User has actively cycled
304+
else:
305+
self.selected_index = (self.selected_index + 1) % len(self.suggestions)
306+
288307
self._update_selection()
289308

290309
def cycle_previous(self) -> None:
291-
"""Cycle to next suggestion."""
310+
"""Cycle to previous suggestion."""
292311
if self.suggestions:
293-
if not self.selected_index:
294-
self.selected_index = len(self.suggestions) - 1
312+
if not self._has_cycled:
313+
self._has_cycled = True # User has actively cycled
295314
else:
296-
self.selected_index = (self.selected_index - 1) % len(self.suggestions)
315+
if not self.selected_index:
316+
self.selected_index = len(self.suggestions) - 1
317+
else:
318+
self.selected_index = (self.selected_index - 1) % len(self.suggestions)
319+
297320
self._update_selection()
298321

299322
def select_current(self) -> None:

0 commit comments

Comments
 (0)