From 54e83ebad8ae06d5fa8411e1ac907e1512c69ac8 Mon Sep 17 00:00:00 2001 From: blasty Date: Thu, 9 Jul 2026 15:19:48 +0200 Subject: search: land the cursor on the match's starting column _goto_line now sets cursor_x to the first match range's start on the target line (and _hscroll's it into view for the pseudocode view), so jumping to a search hit positions the cursor exactly on the match, not the old column. Search cancel/empty also restore the origin column. pilot suite 47/47. --- idatui/app.py | 8 ++++++++ tests/test_tui.py | 3 +++ 2 files changed, 11 insertions(+) diff --git a/idatui/app.py b/idatui/app.py index d68e827..497f0ac 100644 --- a/idatui/app.py +++ b/idatui/app.py @@ -346,6 +346,7 @@ class SearchMixin: # --- driven by the app's prompt (incremental / as-you-type) --- def search_begin(self, direction: int) -> None: self._search_origin = self.cursor + self._search_origin_x = self.cursor_x self._search_dir = direction def search_update(self, term: str) -> None: @@ -355,6 +356,7 @@ class SearchMixin: self._matches = [] self._ranges = {} self.cursor = getattr(self, "_search_origin", self.cursor) + self.cursor_x = getattr(self, "_search_origin_x", self.cursor_x) self.refresh() self._app_status("/") return @@ -392,6 +394,7 @@ class SearchMixin: self._matches = [] self._ranges = {} self.cursor = getattr(self, "_search_origin", self.cursor) + self.cursor_x = getattr(self, "_search_origin_x", self.cursor_x) self.scroll_to(y=max(self.cursor - self._visible_height() // 2, 0), animate=False) self.refresh() @@ -447,7 +450,12 @@ class SearchMixin: def _goto_line(self, idx: int) -> None: total = self._search_line_count() self.cursor = max(0, min(total - 1, idx)) + # Land the cursor on the start of the (first) match on this line. + ranges = self._ranges.get(self.cursor) + if ranges: + self.cursor_x = ranges[0][0] self.scroll_to(y=max(self.cursor - self._visible_height() // 2, 0), animate=False) + self._hscroll() # bring the match column into horizontal view self.refresh() def clear_search(self) -> None: diff --git a/tests/test_tui.py b/tests/test_tui.py index 9813c1f..688df57 100644 --- a/tests/test_tui.py +++ b/tests/test_tui.py @@ -171,6 +171,9 @@ async def run(db): check("cursor sits on a match", dis.cursor in dis._matches, f"cursor={dis.cursor}") check("match substring highlighted", bool(dis._ranges.get(dis.cursor)), str(dis._ranges.get(dis.cursor))) + check("search cursor lands on the match's starting column", + dis.cursor_x == dis._ranges[dis.cursor][0][0], + f"cursor_x={dis.cursor_x} ranges={dis._ranges.get(dis.cursor)}") prev = dis.cursor await pilot.press("slash") await pilot.pause(0.1) -- cgit v1.3.1-sl0p