fix(sessions): widen close reselection when local history is empty - #589
Closed
ssgreg wants to merge 1 commit into
Closed
fix(sessions): widen close reselection when local history is empty#589ssgreg wants to merge 1 commit into
ssgreg wants to merge 1 commit into
Conversation
ssgreg
force-pushed
the
feat/close-reselect-mru-widening
branch
from
September 11, 2026 08:28
774a55b to
b938c3e
Compare
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
force-pushed
the
feat/close-reselect-mru-widening
branch
from
September 11, 2026 08:40
b938c3e to
7b82429
Compare
Owner
|
closing, keeping the workspace term from #147. the case is real, and wider than the nothing needed on your side, and thx for asking first instead of building on it. |
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.
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.
closeReselectionTargetpicked one scope and asked recency once, widening only when the narrower set wasEMPTY. A workspace whose survivors were opened but never selected has nothing to recall, so the walk took
over.
session new --no-selectleaves 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
.flaggedit sits off the navigation set withdisableFocusIfSelectionOutsideSetreturning early, and in
.treethat same net fires and drops your focus filter to reveal it. Two of thetests exist only to hold that gate.
Two things worth knowing before you decide. With no filter on,
navigableSessionsis 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, sosession closefollowed by atarget-less
session neworworkspace focusnow resolves to a different workspace. The bundled skill, the website andmenu-actions.mdsay sonow.
This reverses half of one call in the plan.
20260714-mru-reselection-on-close.md§2 rejected anunscoped 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.
workspaceRemovalTargetand the Ctrl-Tab switcher already prefer recency across workspaces, thoughneither 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) andswiftlint --strict. Six cases cover the crossing, both filters heldin 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