Extract Log Search execution into LogSearcher #652
Merged
Conversation
Extracts the Log Window search loop semantics into a table-tested module per docs/specs/log-search-extraction.md: direction resolution (forward/find-next/Shift+F3), wrap-around-once, regex/ordinal matching over ILogfileReader, progress + wrap events via IProgress, cancellation via CancellationToken. Regex compiles once per search and a bad pattern returns InvalidPattern before any line is read; Find operates on a snapshot so mutating the shared SearchParams cannot affect a run. Lands unused; call-site migration is ticket 2. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Deletes the private ~113-line Search loop; StartSearch runs LogSearcher.Find on the background task with a CancellationToken and a synchronous progress relay. The control keeps the UI half: wrap notices and not-found on the status line, progress bar updates, SelectLine on a hit. ESC cancels the search token (the shared _shouldCancel flag stays for the filter loops and SelectLine gate, exactly as before); reload, dead-file, and close teardown cancel a running search too. The unreachable not-found MessageBox in SelectLine is removed. The token source is replaced only after a consumed cancellation, mirroring the old _shouldCancel=false reset so a superseding search keeps racing and one ESC cancels every running search. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…cket 3) The start-line computation now calls LogSearcher.ResolveDirection, so the (IsForward || IsFindNext) && !IsShiftF3Pressed predicate exists in exactly one place. Truth-table equivalent to the deleted expression. The snapshot half of the ticket was already satisfied in the module: Find copies its params at entry, pinned by Find_MutatingSearchParamsMidRun_DoesNotAffectTheRunningSearch. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…t 4) An invalid regex reaching a search (F3 with SearchParams restored from persisted settings, or programmatic callers - the Search dialog pre-validates its own input) now shows the existing localized invalid-regular-expression status-line error, the same resource the filter path uses, instead of dying silently on the background task. Menus and progress bar were already restored for every outcome by SearchComplete. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
CONTEXT.md gains the canonical Log Search entry - the Ctrl+F/F3 feature owned by LogSearcher - with the Avoid note disambiguating it from filtering (FilterSearch belongs to the filter path). The sweep found one pinning gap: backward wrapped-full-circle NotFound was untested; added Find_BackwardWrappedFullCircleWithoutMatch_ReturnsNotFoundWrapped. Closes the Log Search extraction epic (tickets 1-5). Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Root cause: LoadHistory (run on dialog Load) binds both combo boxes via DataSource, and OnButtonOkClick then modified ComboBox.Items directly - which WinForms forbids while a DataSource is set. Every OK click on a shown dialog threw. The handler now mutates only the bound history lists and never touches Items; this also removes a latent value-vs- index bug (Items.Remove(Count - 1) removed the value, not the last entry). Regression-tested by replaying the Load-then-OK sequence. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Extracts the Log Window's search implementation (Ctrl+F / F3 / Shift+F3) into a pure, table-tested
LogSearchermodule inLogExpert.Core— Candidate 2 of the LogWindow architecture review, following the pattern proven by the Filter Spread extraction pure module in Core, table-tested in LogExpert.Tests, control delegates.The ~113-line private search loop in
LogWindow.csis gone.LogSearcher.Findowns direction resolution, the wrap-around-once rule, and regex/ordinal matching overILogfileReader; the Log Window keeps only the UI half — status-line narration, progress bar, grid scrolling, and cancellation wiring.Commits / tickets
LogSearchermodule + 34 tests —Find(params, reader, token, progress)returns aSearchResult(Found / NotFound / Cancelled / InvalidPattern + wrapped flag). Direction truth table, wrap semantics, case modes, regex, cancellation ordering and progress cadence all pinned against a mocked reader — no WinForms needed.CancellationToken(ESC, reload, dead-file, and close all cancel); wrap notices and progress keep their original mid-search timing; the dead "not found" MessageBox is deleted. The shared_shouldCancelflag is untouched for the filter loops.(IsForward || IsFindNext) && !IsShiftF3Pressedpredicate, previously hand-copied in three places, now exists only inLogSearcher.ResolveDirection.FilterSearch); the contract sweep closed one pinning gap (backward wrapped-full-circle).Plus one drive-by fix found during manual smoke: the Regex Helper dialog crashed on every OK click (
Itemsmodified whileDataSourcewas bound) — fixed and regression-tested with three tests replaying the Load→OK sequence.User-visible changes
ArgumentException.Everything else is behaviour-preserving, pinned by tests (including cancellation ordering and wrap-notice timing).
Testing
LogSearcherTests+ 3RegexHelperDialogTests; full solution suite green (1,394 passed, 0 failed).