Skip to content

fix(sessions): widen close reselection when local history is empty - #589

Closed
ssgreg wants to merge 1 commit into
umputun:masterfrom
ssgreg:feat/close-reselect-mru-widening
Closed

fix(sessions): widen close reselection when local history is empty#589
ssgreg wants to merge 1 commit into
umputun:masterfrom
ssgreg:feat/close-reselect-mru-widening

Conversation

@ssgreg

@ssgreg ssgreg commented Sep 11, 2026

Copy link
Copy Markdown
Contributor

Closing the active session in a workspace that holds no session you have ever visited puts you on the
positional neighbour rather than on the last session you actually used. So the question first, because
the answer is a product call and it is yours: when the visible survivors in the closing workspace were
never visited, should locality still win over a session you did visit elsewhere?

This branch is what "no" looks like, ready to merge or to close.

closeReselectionTarget picked one scope and asked recency once, widening only when the narrower set was
EMPTY. A workspace whose survivors were opened but never selected has nothing to recall, so the walk took
over. session new --no-select leaves every tab it opens in exactly that state until its first visit,
which makes a script-filled workspace normally in it - mine is one tab per Jira event, I read one of them,
and closing it lands me on a ticket I have never opened.

Recency is now asked per level, narrowest first: the closing session's workspace ∩ the visible set,
then that visible set. A remembered local survivor still wins, and a workspace that remembers nobody
yields only to a remembered session inside the same visible set - under a single-workspace narrowing the
two levels are one set, so the walk still takes it even when a remembered session sits outside the
filter. The change is the empty-local-history case, not locality itself.

The whole tree stays gated on an empty visible set. Outside the visible set a pick has no good end in
either mode: in .flagged it sits off the navigation set with disableFocusIfSelectionOutsideSet
returning early, and in .tree that same net fires and drops your focus filter to reveal it. Two of the
tests exist only to hold that gate.

Two things worth knowing before you decide. With no filter on, navigableSessions is every session,
so the second level is the whole tree in practice: this does let a close cross workspaces in the default
configuration, which is where the §2 objection below actually bites. And the selection carries currentWorkspaceID, so session close followed by a
target-less session new or workspace focus now resolves to a different workspace. The bundled skill, the website and menu-actions.md say so
now.

This reverses half of one call in the plan. 20260714-mru-reselection-on-close.md §2 rejected an
unscoped most-recent survivor as "more disorienting than the positional neighbor", on two grounds: it
could pull you into another workspace, and it could silently drop a focus filter. The second ground is
preserved by the gate above, and the first changes only where the workspace remembers nobody and the
visible set remembers someone else.
workspaceRemovalTarget and the Ctrl-Tab switcher already prefer recency across workspaces, though
neither faces this choice; they are why it looked worth trying, not proof that §2 was wrong.

If you would rather keep the workspace term, close this and I will drop it.

Tested with swift test (3156) and swiftlint --strict. Six cases cover the crossing, both filters held
in scope with one marked workspace, both crossing with a filter spanning two, and a soft close where the
closing session stays in recency for undo and only the tree-derived sets keep it out.

Mutation-checked, each mutant dying to the tests meant to catch it. Worth naming one: consulting the
visible level only while no filter applies passed the whole suite before review, which is why the
spanning tests exist.

Related to #147

@ssgreg
ssgreg requested a review from umputun as a code owner September 11, 2026 08:22
@ssgreg
ssgreg force-pushed the feat/close-reselect-mru-widening branch from 774a55b to b938c3e Compare September 11, 2026 08:28
@ssgreg ssgreg changed the title fix(sessions): close returns to the last session actually used fix(sessions): widen close reselection when local history is empty Sep 11, 2026
Closing the session you are in put you on whichever tab sat next to it whenever the workspace held no session you had ever visited, which is the normal state of a workspace a script fills: a tab opened without stealing focus is never recorded as used, so there was nothing to return to and the neighbour won by default. The most recently used session now wins at each level in turn, the closing session's workspace first and then the whole set the sidebar is currently listing, and the neighbour is taken only when nothing in that listing has been used.

So the pick can leave the workspace, but never the listing: a filter narrowed to one workspace keeps it local even when a session you used sits outside the filter. The whole tree is consulted only while the listing is empty, because outside it a pick has no good end - in the flagged view nothing would bring the selection back, and in the tree the net that does bring it back works by switching your workspace filter off.

The selection carries the current workspace with it, so a close that crosses workspaces also moves what workspace-scoped `--target active` resolves to. The bundled agent skill, the website and the close-reselection rule say so now; none of them mentioned that closing the selected session moves the selection at all.
@ssgreg
ssgreg force-pushed the feat/close-reselect-mru-widening branch from b938c3e to 7b82429 Compare September 11, 2026 08:40
@umputun

umputun commented Sep 11, 2026

Copy link
Copy Markdown
Owner

closing, keeping the workspace term from #147.

the case is real, and wider than the --no-select one: entering a workspace through its row records only its first session, so closing that one leaves the rest unvisited too. But the neighbour is the answer I want there. For me a script-filled workspace is a queue, and I want closing an item in it to move me to the next one, not send me back to another workspace and move the active workspace for a following session new with it.

nothing needed on your side, and thx for asking first instead of building on it.

@umputun umputun closed this Sep 11, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants