Repository navigation
fix(web): Tab nests numbered list items in the composer - #17138
michal-billtech wants to merge 1 commit into
Conversation
Tab on a list item only prepended two spaces and kept the marker, so `1. a` / Shift+Enter / Tab produced ` 2. ` instead of a nested `1.`. Two spaces under `1. ` is also not nesting in CommonMark (the child must reach the parent's content column), so the agent received a flat list. - Tab nests the item at the content column of the item above and numbers a nested ordered list from 1, or continues an existing sublist. - Shift+Enter on an empty nested item moves it up one level and continues the parent's numbering (the rich-text composer already did this; the plain composer left the whole list). Fixes pingdotgg#17124
ApprovabilityVerdict: Approved at Macroscope's review found this PR approvable — This is a focused composer bug fix that corrects Markdown list nesting and caret placement for Tab and nested empty-item handling. Runtime changes are confined to list editing, with targeted tests covering ordered, bullet, task, multi-level, and fallback cases. You can add or adjust custom eligibility rules. Learn more. |
|
No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info⚙️ Run configuration
📒 Files selected for processing (4)
Included review availability: This review used your included allowance. Your plan provides up to 10 included reviews per hour; 9 remain after this review. 📝 WalkthroughWalkthroughThe composer now moves out of empty nested list items one level at a time. Tab nests list items at the preceding item's content column and updates ordered-list numbering. Tests and composer documentation cover these behaviors. ChangesComposer list editing
Priority: ⬇️ Low Estimated code review effort: 3 (Moderate) | ~20 minutes Change: Bug fix · Severity of issue fixed: Low Suggested reviewers: Merge Risk: ⚪ Minimal · up to This change makes Tab nest numbered list items and Shift+Enter move out of empty nested items one level at a time in the composer. No concrete merge-blocking risk was identified. 🚥 Pre-merge checks | ✅ 4✅ Passed checks (4 passed)
✨ Finishing Touches🧪 Generate unit tests (beta)
Comment |
Problem
In the composer, Tab on a numbered list item prepends two spaces and keeps the number, so
1. first→ Shift+Enter → Tab gives2.instead of a nested1.. Two spaces under1.is not nesting in CommonMark (a child must reach the parent's content column), so the agent and the sent message get a flat list. In the plain composer, Shift+Enter on an empty nested item also drops out of the whole list instead of moving up one level.Fixes #17124.
Change
listIndentForTab) nests the item at the content column of the item above: 3 spaces under1., 4 under10., 2 under-(unchanged for bullets). A nested ordered item starts at1., or continues the sublist the item above already has. With no item to nest under, it keeps today's two-space indent.listContinuationForEnter) moves it to the parent's indent with the parent's next marker, which is what the rich-text composer already does throughsplitOrLiftListItem. An empty top-level item still leaves the list.ComposerListEditgets an optionalcursor, so the caret stays on the item text when the marker width changes;ChatComposerpasses it through instead of assuming a pure insertion.docs/user/composer.mddescribes the nesting.Both composer modes route Tab through
listIndentForTab, and rich mode rebuilds from the stored Markdown, so the one change fixes both. Mobile has no list continuation in its composer; desktop uses the web composer.Not included:
ComposerListEdit, so whichever lands second needs a small reconcile.Scope and approval
Bug report #17124, triaged (
bug,via-triage) and confirmed in #17124 (comment), which also suggested this fix direction and keeping Shift+Tab out.Verification
Focused tests:
New cases in
composer-list-continuation.test.tscover Tab nesting under1.,10), bullets and tasks, joining and continuing an existing sublist (including one written at a non-standard indent), the caret position after the marker changes width, the two-space fallback, and Shift+Enter leaving one level of nesting (ordered → ordered, bullet parent, task child, two levels deep) or the list at the top level. The existing rich-mode test for lifting1. a\n 1. xwrites the same 3-space indent that Tab now produces, so both modes agree.tsc --noEmitforapps/webpasses, andvp lintreports no new warnings on the changed files.CommonMark check with
mdast-util-from-markdown:"1. foo\n 2. bar"parses as one flat list with 2 items, and"1. foo\n 1. bar"parses as a nested list.Manual check in the web client (
vp run devon isolated worktree state, macOS, Node 24). Before ismain@30cc78897, after is this branch. Steps: type1. first, Shift+Enter, Tab, typenested. For the third pair, then Shift+Enter, Shift+Enter, and typesecond.Rich-text composer, Tab
Before:
After:
Plain composer (the raw Markdown the agent receives), Tab
Before:
After:
Plain composer, Shift+Enter twice after the nested item
Before:
After:
Not checked: sending the prompt to a provider (no provider configured in the test state), and the desktop shell, which wraps the same web composer.
Local dev pairing on Node 24 needed #16730 applied locally (issue #16797); that change is not part of this PR.
Work done with Claude Opus 5.5 in Claude Code, running inside T3 Code.
🤖 Generated with Claude Code