Repository navigation
Description
Before submitting
- I searched existing issues and didn't find this bug
- This is one bug. Other problems get their own issue.
Where it happens
Web in a browser and the desktop app (Windows) are where I reproduced it. The VS Code extension ships the same Files view from packages/ui, so it has the same gutter, the same handlers and the same behaviour; the fix belongs in the shared UI package so web, desktop and the VS Code webview all get it.
I hit it in the desktop app 2.5.0, and checked the built VS Code extension 2.5.1 (dist/webview/assets) — identical logic.
Steps to reproduce
- Open the Files view and open a code file (any
.ts/.pyworks). - Press the mouse on a line number in the gutter and drag down over the next 5-10 line numbers.
- Release.
Roughly half the attempts end with a one-line range, and long drags fail more often than short ones. Any drag that drifts a few pixels to the right, into the code area, stops extending at the line where it left the gutter. The same happens in the VS Code extension's Files view.
What I expected
The selected range follows the pointer as far down as I drag, and keeps going (auto-scrolling) when I reach the bottom edge of the editor.
What happened instead
The range freezes as soon as the pointer is no longer over the line-number column, and dragging past the last visible line does nothing because there is no auto-scroll. The same gesture sometimes extends correctly and sometimes does nothing, so comments end up on the wrong line range.
OpenChamber version
Desktop app 2.5.0, VS Code extension 2.5.1
OpenCode version and model/provider (if relevant)
2.0.32
Why it happens (from the shipped bundles)
In Files view, the code editor passes domEventHandlers (mousedown / mouseover / mouseup) to CodeMirror's lineNumbers(). The drag extension is driven only by that mouseover:
- CodeMirror binds the handlers to the gutter element (
src/gutter.ts), somouseoverfires only while the pointer is inside that narrow column. Leaving it — sideways into the code, or out of the editor — ends the extension. - The handler requires
event.buttons === 1and theisSelectingRefset bymousedown; there is nosetPointerCapture, no document-levelpointermovewith a clientY -> line mapping, and no edge auto-scroll. - Each step also calls
setLineSelection+setIsDragging, which changeshighlightLinesand re-creates theblockWidgetsmemo (it depends onlineSelection). Both compartments are reconfigured, so the editor re-renders on every line the drag crosses.
I confirmed the same code in the shipped web-dist/assets/FilesView-*.js (desktop 2.5.0) and dist/webview/assets (extension 2.5.1); I have not built from source.
Suggested fix
Track the drag outside the gutter as well: on gutter pointerdown, either capture the pointer or attach a document pointermove that maps clientY to a line (lineBlockAtHeight / posAtCoords), so drifting out of the column keeps extending instead of stopping. Add auto-scroll near the top/bottom edge, recomputing the line per frame. Flip isDragging only at drag start/end and keep the highlight and comment-widget extensions stable during the drag so the editor is not reconfigured on every crossed line.
Workaround that works today, in both the desktop app and the VS Code extension: click the first line number, then Shift+click the last one. That goes through the same lineSelection state with a single mousedown and does not depend on the drag.
Activity
[-][Bug] Files view: dragging across line numbers to comment is unreliable[/-][+][Bug] Files view: dragging across line numbers to comment is unreliable (web, desktop, VS Code extension)[/+]openchamber-bot commentedon Oct 24, 2026
For the maintainer:
fix-ready— cause tracedThe drag state machine for gutter line selection lives entirely in gutter-bound handlers:
mousedownsetsisSelectingRef(packages/ui/src/components/views/FilesView.tsx:3681-3730),mouseoverextends the range only whileevent.buttons === 1(FilesView.tsx:3731-3748), andmouseupends it (FilesView.tsx:3749-3754). These are handed to CodeMirror'slineNumbers()vialineNumbersConfig.domEventHandlers(FilesView.tsx:3758-3764), which binds them to the gutter element — somouseoverfires only while the pointer is inside the line-number column. Leaving it freezes the range at the last gutter line crossed; a fast drift can cross zero gutter cells, leaving the one-line range frommousedown. There is nosetPointerCapture, no document-level move handler with aclientY → linemapping, and no edge auto-scroll, so your two failure modes and the flakiness follow directly. Your analysis is right; nothing in currentmainchanges it.Two additions:
mouseuphandler is gutter-bound (FilesView.tsx:3749), so releasing over the code area never clearsisDragging/isSelectingRef; they persist until the next gutter event.packages/ui/src/components/views/PlanView.tsx:976-1015), so the fix should cover both.The per-line reconfiguration claim also checks out: each
mouseovercallssetLineSelection+setIsDragging(FilesView.tsx:3745-3746);lineSelectionfeedshighlightLines(FilesView.tsx:5353-5356) and both feed theblockWidgetsmemo (FilesView.tsx:4078-4100), andCodeMirrorEditor.tsx:503-507reconfigures both compartments on change — two compartment reconfigurations plusrequestMeasureper crossed line (CodeMirrorEditor.tsx:516-519).Code path
mousedownon a gutter line:FilesView.tsx:3681setsisSelectingRef.current = true,selectionStartRef.current = lineNumber,setIsDragging(true), andsetLineSelection({start: n, end: n})(3717-3726).mouseover(FilesView.tsx:3731) checksevent.buttons === 1and the ref, thensetLineSelection(3743-3746). CodeMirror invokes gutterdomEventHandlersonly for events on the gutter DOM, so anymouseoverover the code area never reaches this handler.mouseup(3749) never runs →isDraggingstaystrue.setLineSelection:highlightLinesprop changes (5353) andblockWidgetsmemo identity changes (4100);CodeMirrorEditor.tsx:503-507dispatches compartment reconfigurations for both on every crossed line.Mechanism is confirmed by source reading; it matches your shipped-bundle analysis, but has not been runtime-reproduced against your specific Windows 2.5.0 build.
The suggested fix shape (gutter
pointerdown→ pointer capture or documentpointermovewithposAtCoords, edge auto-scroll,isDraggingflipped only at drag start/end) fits what the code needs; the Shift+click path you found is unaffected.fix(files): line range follows a drag that leaves the line numbers (#…