Skip to content

link mode: badges go stale on filter changes and shift on ring-buffer eviction #77

Description

@edTheGuy00

Summary

Two related staleness gaps in link-highlight mode, surfaced (with file:line evidence) during the verified research for #75 / PR #76. Both pre-date that work; both affect the badge display itself — the row-count estimate consumes the same stale state as the formatter, so scroll math stays self-consistent throughout.

1. Links are not rescanned on filter changes

rescan_links_if_active (crates/fdemon-app/src/handler/scroll.rs:128-155) runs from every scroll handler, but the filter-change arms (CycleLevelFilter / CycleSourceFilter / ResetFilters, crates/fdemon-app/src/handler/update.rs:~715-734) never call it. Changing a filter while link mode is active leaves LinkHighlightState.links describing the previous filtered viewport: badges can point at entries that are no longer visible, and newly visible entries get no badges until the next scroll.

Repro: enter link mode (L) on a view with links, press the level-filter cycle key — badges/shortcuts now disagree with what's on screen; press a stale shortcut and the jump targets the wrong (hidden) entry.

2. DetectedLink.entry_index is a raw buffer index that shifts on eviction

scan_viewport stores the raw VecDeque index (crates/fdemon-app/src/hyperlinks.rs:285-380). While link mode is active on a chatty session, ring-buffer eviction (Session::add_log pop_front) shifts every raw index down by one per evicted entry — badges (and shortcut jumps) silently reattach to neighboring entries. New-log arrival also doesn't trigger a rescan.

Fix directions

  • Cheapest: call rescan_links_if_active from the filter-change arms (mirrors the scroll handlers) and after eviction while link mode is active — links are already viewport-scoped and cheap to rebuild (≤35).
  • Sturdier: key DetectedLink by LogEntry.id (stable, monotonic) instead of raw index, converting at scan time; consumers (format_entry, format_stack_frame_line_with_links, entry_display_rows_cached's bypass, SelectLink) compare against entry.id. This eliminates the whole index-shift class and makes rescan timing a pure freshness concern.

Acceptance

  • Filter change in link mode → badges match the new visible set immediately.
  • Continuous log arrival + eviction in link mode → existing badges stay attached to the same entries (or are rescanned away), never reattach to neighbors.
  • Tests for both, plus one asserting the row-count estimate still equals rendered rows through a mid-link-mode rescan.

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions