Fix search: Enter advances to next match, invalidate on new content

- Pressing Enter in find bar now advances to next match instead of
  re-running search when needle is unchanged
- Invalidate search cache when new log lines flush or log is cleared
- Extract _invalidate_search() helper for consistent state reset

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
wongyiekheng 2026-03-31 10:00:06 +08:00
parent 5b873aefc4
commit 21e16d9872

View File

@ -36,6 +36,8 @@ class LogManager(QObject):
self._search_worker: Optional[SearchWorker] = None
self._matches: List[int] = []
self._match_index = -1
self._last_needle = ""
self._last_case = False
self._flush_timer = QTimer(self)
self._flush_timer.setInterval(config.LOG_FLUSH_INTERVAL_MS)
@ -87,6 +89,8 @@ class LogManager(QObject):
visible = [line for line in to_flush if line.direction != Direction.TX]
if visible:
self.view.log_view.append_lines(visible)
if self._matches:
self._invalidate_search()
# Adaptive: slow down flush when queue is heavy to reduce UI stalls
pending_count = len(self._pending)
if pending_count > 500:
@ -96,12 +100,17 @@ class LogManager(QObject):
else:
self._flush_timer.setInterval(config.LOG_FLUSH_INTERVAL_MS)
def _invalidate_search(self) -> None:
self._matches.clear()
self._match_index = -1
self._last_needle = ""
self._last_case = False
self.view.log_view.set_matches([], -1)
def clear(self) -> None:
self.buffer.clear()
self.view.log_view.clear_log()
self._matches.clear()
self._match_index = -1
self.view.log_view.set_matches([], -1)
self._invalidate_search()
def save(self) -> None:
dlg = QFileDialog(self.view, "Save Log", str(Path.home() / "ameba_log.txt"))
@ -126,14 +135,21 @@ class LogManager(QObject):
if self._search_worker and self._search_worker.isRunning():
return
needle = self.view.find_input.text()
self.view.log_view.set_needle(needle, self.view.case_checkbox.isChecked())
case = self.view.case_checkbox.isChecked()
# If needle unchanged and we already have matches, just advance
if needle == self._last_needle and case == self._last_case and self._matches:
self.find_next()
return
self._last_needle = needle
self._last_case = case
self.view.log_view.set_needle(needle, case)
if not needle:
self.view.log_view.set_matches([], -1)
self._matches = []
self._match_index = -1
return
lines = [l.as_display() for l in self.view.log_view.displayed_lines()]
self._search_worker = SearchWorker(lines, needle, self.view.case_checkbox.isChecked())
self._search_worker = SearchWorker(lines, needle, case)
self._search_worker.finished.connect(self._on_search_finished)
self._search_worker.start()