Repository navigation
Jumping into a file that isn't open yet puts the line right under the sticky lines, with no context above it #504
Description
Opportunity
When a jump opens a file that isn't open yet, its line lands right under the sticky lines, with nothing above it.
#349 promised that every jump lands two rows below the pinned lines, so you can see what leads into the line you came for, and once a file is open that holds. But the first jump into a file doesn't. That is how you arrive cold: tuicode Workbench.cs:205 pasted from grep -n, a stack trace or a CI log, or the first Find in files result you open in a file you haven't looked at yet. It's exactly when you most need the two lines of context, and they're the ones missing.
Tried on main (f0cf5de) with a fresh ~/.tui, in src/TuiCode.Workbench/Workbench.cs, where line 205 is inside ShowCursorPosition():
tuicode Workbench.cs:205: pins for 13 (class Workbench) and 200 (ShowCursorPosition()), then 205 straight under them. Lines 203–204, the two statements before it, are hidden.- Find in files,
SetDiffStatus(Editor, Enter on the result with the file not open: the same, 205 straight under the pins. - Go to line
205in the same file once it's open: 13, 200, then 203, 204, 205, as Halfway down a long method or class, I can't see what I'm inside of #349 intended.
The pins come from a scan of the file that runs a little at a time between frames, so a freshly opened file has no pins yet when the jump scrolls. The jump allows for none, then the pins appear over the two lines it left for context. AGENTS.md Navigation already lists tuicode file.cs:42 among the jumps that land clear of the pins.
Options considered
- Do nothing. The target line is never hidden, only its context. Bad: it breaks Halfway down a long method or class, I can't see what I'm inside of #349's promise on the jumps you take when you know the file least, and the gap is visible every time you come in from a terminal.
- Allow for the most pins a jump could get (three) when the file's pins aren't known yet. Good: no scroll after the first frame. Bad: the line lands up to three rows lower than any other jump puts it, with blank space or unrelated lines above, so arriving from a terminal still looks different from Go to line.
- Finish the scan before scrolling. Good: the jump is right first time. Bad: the scan runs in slices so a large file doesn't freeze the editor; finishing it on open brings that freeze back for exactly the files where the scan takes longest.
- Once the file's pins are first known, scroll the jump again, unless you've moved since (chosen). Good: the line ends where every other jump puts it, with the same two rows of context, and nothing blocks. Bad: on a large file the view can shift down a row or two a moment after it first appears. Leaving it alone once you've scrolled, typed or moved the cursor means it never fights you.
Proposal
A jump that opens a file at a line ends the way Go to line does once the file is open: the line two rows below the sticky lines. If the file's pins aren't known when it first draws, TuiCode scrolls it into place as soon as they are, and only if you haven't scrolled, typed or moved the cursor since.
That covers every way in that opens a file at a line: the command line (tuicode file:line, and git handing TuiCode a file), Find in files, Usages, Go to definition, Go to symbol, the History panel, and Back or Forward into a file that was closed. With word wrap on it works the same.
Mockup
tuicode src/TuiCode.Workbench/Workbench.cs:205, today:
│ Workbench.cs │
│ 13 public sealed class Workbench : Window │
│ 200 public void ShowCursorPosition() │
│ 205 StatusBar.SetDiffStatus(Editor.Group.Active…│
│ 206 ? string.Join(" • ", new[] { … │
│ 207 : null); │
After, and the same as Go to line 205 gives today:
│ Workbench.cs │
│ 13 public sealed class Workbench : Window │
│ 200 public void ShowCursorPosition() │
│ 203 StatusBar.SetPosition(tab is null ? null : …│
│ 204 StatusBar.SetSelection(tab?.CaretCount ?? 1…│
│ 205 StatusBar.SetDiffStatus(Editor.Group.Active…│
│ 206 ? string.Join(" • ", new[] { … │
Scope
In: every jump that opens a file at a line, listed above, with and without word wrap.
Out:
- Where the line lands once the file is already open; Halfway down a long method or class, I can't see what I'm inside of #349 settled that.
- Reopening a file at the position it was left in (Reopening a file puts me back where I was in it #514): that brings back the scroll you had, it isn't a jump.
- How sticky lines are chosen or drawn.
- Making the scan itself faster.
Delivery
One PR.
Decided
All of these were the Lead's calls, accepted by the stakeholder's approval.
- A late scroll is better than a wrong one. On most files the pins are known within a frame or two, so you won't see it; on a large file a one-off shift of a row or two is a smaller cost than landing somewhere no other jump does (option 2) or freezing on open (option 3).
- Any move of yours cancels it. Scrolling, typing, clicking or moving the cursor between the jump and the pins arriving means you've taken over, and the view stays where you put it.
- Every way in, not just the command line. The idea named the command line; Find in files has the same gap, and the fix is the same for all of them, so fixing one alone would leave Halfway down a long method or class, I can't see what I'm inside of #349's promise broken elsewhere.
Original idea
When I open tuicode file.cs:214, the line lands right under the sticky lines with nothing above it for context.
Every other jump (Go to line, Go to symbol, a Find result, Back) puts its line two rows below the pinned ones, so you can see what leads into it. Opening a file at a position from the command line, which is what you do from grep -n, a stack trace or a CI log, puts the line directly under the pins instead. It's never hidden, but the two lines of context are missing just when you've arrived cold.
Evidence as filed: on origin/main after #474, tuicode src/TuiCode.Workbench/Workbench.cs:214 showed pins for 12 and 207, then 214 directly below; Go to line 214 showed 212–213 as intended. Most likely the startup reveal runs before the first sticky-lines scan has finished. Follow-up from #349; theme 1.
Activity
a-team-app commentedon Oct 11, 2026
Recommended: Medium · theme 1, tiny · finishes #349's promise for the most common way in, from grep/stack traces
[-]Opening a file at a line from the command line puts that line right under the sticky lines, with no context above it[/-][+]Jumping into a file that isn't open yet puts the line right under the sticky lines, with no context above it[/+]a-team-app commentedon Oct 17, 2026
Pitched now that a slot freed. Checked against
main(stillf0cf5de, where I reproduced it): nothing's changed, so the pitch is as drafted. No questions for you; approving accepts the Assumed list.jamescrosswell commentedon Oct 23, 2026
Broken down into one task, #588, which covers every way into a file at a line. It doesn't depend on anything else, so the Dev can start it now. The Assumed list is now Decided, unchanged.
a-team-app commentedon Oct 23, 2026
That comment is the Lead's own breakdown note (it carries the Lead marker but was posted from your account), so there's nothing new to act on. #588 is already In progress with the Dev.
a-team-app commentedon Oct 23, 2026
Tried on
main(2388b26, after #589) with a fresh home, inWorkbench.csline 229.tuicode Workbench.cs:229and a Find in files result opened into the unopened file both show the pins for 13 and 224, then 227 and 228 for context, then 229. That's where Go to line puts it. Closing as done.