Review outline panel design against codebase
Created docs/feature/code-outline.md. Key findings from the review:
- No existing outline design doc — this is a fresh plan, unlike the terminal doc which needed updating
- ~60% of the work is already done via dock infrastructure:
PanelId::Outlineregistered,Cmd+7wired, right dock with resize/focus/hit-testing all working, placeholder rendering in place - No new dependencies needed — tree-sitter is already there with cached
Treeper document on the syntax worker thread - Revised effort: 3–5 days (not the 1–2 weeks the panel-ui-abstraction doc estimated) because:
- All panel chrome/dock code exists
- Outline extraction piggybacks on the existing syntax worker thread (same debounce, same revision tracking)
- Sidebar file tree rendering provides a direct pattern to copy for the outline tree
- Tree-sitter queries (
outline.scm) are declarative and quick to write per language
The design follows the oracle's recommendation: reuse the syntax worker thread, use tree-sitter queries for extraction, store outline on Document (like syntax_highlights), and keep UI state (expand/collapse/selection) separate in OutlinePanelState.
Yes, you're right — the dock infrastructure, tree-sitter parsing, and sidebar tree rendering pattern are all in place. The main new work is: data structures, outline queries, extraction logic, and swapping the placeholder for a tree renderer. Let me start implementing.
Let me first re-read the exact integration points I need to hook into:
Now let me check the Cmd enum to see RunSyntaxParse and the update mod.rs:
Now let me check the Cmd enum and how RunSyntaxParse is handled:
Now I have complete understanding. Let me check how process_cmd handles RunSyntaxParse to understand where I send the request:
Now I have a complete picture. Let me implement this in parallel tasks — the work is cleanly separable:
The outline module task failed. Let me create those files directly:
Now register the outline module in lib.rs and verify the model changes from the task:
Now let me verify the model changes:
Good, model changes are in place. Let me try to build:
Need to fix two binaries that construct AppModel directly:
Compiles clean. Now let me hook outline extraction into the syntax worker thread. I need to modify ParserState to expose the cached tree, then call extract_outline in the worker loop:
The parse_and_highlight method already has access to the Tree internally. Rather than exposing the tree (which is !Sync), the cleanest approach is to add a method that returns both highlights and outline. Let me add a get_cached_tree accessor so the worker loop can extract outline after parsing:
Now hook the outline extraction into the syntax worker loop and add outline to ParseCompleted:
Now update the syntax worker loop to extract outline after parsing:
Now update the update_syntax handler to store the outline:
Now fix the tests that construct ParseCompleted without the outline field:
Clean compile. Now let me fix the tests:
These are test-only occurrences. Let me add outline: None to each:
Now let me also check for ParseCompleted in the initial parsing path:
Good, only the one place in the worker. Let me build and run tests:
More AppModel constructors to fix:
All 5 locations follow the same pattern. Let me fix them all:
All tests pass. Now let me implement the outline panel rendering — replacing the placeholder in render_dock:
Now I'll replace the placeholder rendering in render_dock to dispatch to an outline renderer when the active panel is Outline:
Now let me add the OutlineMsg to messages and wire up the interaction (click-to-jump, keyboard navigation). Let me add the messages and update handler:
Now add Msg::Outline to the top-level enum:
Now create the outline update handler:
Register the outline update in the update mod and wire it into the main dispatch:
Now add the Msg::Outline dispatch to the main update_inner function:
Also add to the debug msg_type_name function:
Now let me run the full test suite:
All tests pass. Let me also run the outline-specific tests:
All 3 outline tests pass. Let me also run lint:
Clippy caught the duplicate branch. Let me fix it:
More AppModel constructors in benchmarks:
Clean lint. Let me run the full test suite one more time:
All tests pass, lint clean. Here's what was implemented:
Summary
Phases 1-3 of the outline panel are now implemented:
New files created:
src/outline/mod.rs—OutlineData,OutlineNode,OutlineKind,OutlineRangedata structuressrc/outline/extract.rs— Symbol extraction via tree-sitter AST walking for 8 language families (Rust, TS/JS, Python, Go, Java, PHP, C/C++) + markdown heading hierarchy with 3 unit testssrc/update/outline.rs—OutlineMsghandler (jump-to-symbol, navigate, expand/collapse, scroll)docs/feature/code-outline.md— Full design doc
Files modified:
src/model/document.rs— Addedoutline: Option<OutlineData>per documentsrc/model/ui.rs— AddedOutlinePanelState(collapse tracking, selection, scroll)src/model/mod.rs— Addedoutline_paneltoAppModelsrc/messages.rs— AddedOutlineMsgenum +Msg::Outlinevariant +outlinefield onParseCompletedsrc/syntax/parser.rs— Addedget_cached_tree()accessorsrc/runtime/app.rs— Syntax worker extracts outline alongside highlightssrc/update/syntax.rs— Stores outline on document fromParseCompletedsrc/update/mod.rs— WiredMsg::Outlinedispatchsrc/view/mod.rs—render_dockdispatches torender_outline_panelfor the outline, showing a tree with expand/collapse indicators, kind labels, and symbol namessrc/lib.rs— Registeredoutlinemodule- Various bin/test/bench files — Added
outline_panelfield
What works now:
- Open a Rust/TS/Python/etc file → outline is extracted on the syntax worker thread alongside highlights
- Press
Cmd+7→ outline panel opens in right dock showing symbol tree - Symbols nested by range containment (methods inside impl/class)
- Markdown headings nested by level (
# > ## > ###) - "No outline available" shown for unsupported languages