Skip to content

Commit b8af02e

Browse files
celestial-vaultElephant Lumps
andauthored
Stop doomscrolling (RooCodeInc#3354)
* disable auto scroll on user scroll up * changeset --------- Co-authored-by: Elephant Lumps <[email protected]>
1 parent 904df9f commit b8af02e

File tree

2 files changed

+58
-18
lines changed

2 files changed

+58
-18
lines changed

.changeset/stupid-hotels-brush.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
"claude-dev": minor
3+
---
4+
5+
Allow the user to scroll when Cline is editing a file by disabling auto-scroll when the user scrolls up

src/integrations/editor/DiffViewProvider.ts

Lines changed: 53 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,9 @@ export class DiffViewProvider {
2626
private streamedLines: string[] = []
2727
private preDiagnostics: [vscode.Uri, vscode.Diagnostic[]][] = []
2828
private fileEncoding: string = "utf8"
29+
private lastFirstVisibleLine: number = 0
30+
private shouldAutoScroll: boolean = true
31+
private scrollListener?: vscode.Disposable
2932

3033
constructor(private cwd: string) {}
3134

@@ -34,6 +37,8 @@ export class DiffViewProvider {
3437
const fileExists = this.editType === "modify"
3538
const absolutePath = path.resolve(this.cwd, relPath)
3639
this.isEditing = true
40+
this.shouldAutoScroll = true
41+
this.lastFirstVisibleLine = 0
3742
// if the file is already open, ensure it's not dirty before getting its contents
3843
if (fileExists) {
3944
const existingDocument = vscode.workspace.textDocuments.find((doc) => arePathsEqual(doc.uri.fsPath, absolutePath))
@@ -79,6 +84,21 @@ export class DiffViewProvider {
7984
this.fadedOverlayController.addLines(0, this.activeDiffEditor.document.lineCount)
8085
this.scrollEditorToLine(0) // will this crash for new files?
8186
this.streamedLines = []
87+
88+
// Add scroll detection to disable auto-scrolling when user scrolls up
89+
this.scrollListener = vscode.window.onDidChangeTextEditorVisibleRanges((e: vscode.TextEditorVisibleRangesChangeEvent) => {
90+
if (e.textEditor === this.activeDiffEditor) {
91+
const currentFirstVisibleLine = e.visibleRanges[0]?.start.line || 0
92+
93+
// If the first visible line moved upward, user scrolled up
94+
if (currentFirstVisibleLine < this.lastFirstVisibleLine) {
95+
this.shouldAutoScroll = false
96+
}
97+
98+
// Always update our tracking variable
99+
this.lastFirstVisibleLine = currentFirstVisibleLine
100+
}
101+
})
82102
}
83103

84104
async update(accumulatedContent: string, isFinal: boolean) {
@@ -128,25 +148,30 @@ export class DiffViewProvider {
128148
this.activeLineController.setActiveLine(currentLine)
129149
this.fadedOverlayController.updateOverlayAfterLine(currentLine, document.lineCount)
130150

131-
// Scroll to the last changed line
132-
if (diffLines.length <= 5) {
133-
// For small changes, just jump directly to the line
134-
this.scrollEditorToLine(currentLine)
135-
} else {
136-
// For larger changes, create a quick scrolling animation
137-
const startLine = this.streamedLines.length
138-
const endLine = currentLine
139-
const totalLines = endLine - startLine
140-
const numSteps = 10 // Adjust this number to control animation speed
141-
const stepSize = Math.max(1, Math.floor(totalLines / numSteps))
142-
143-
// Create and await the smooth scrolling animation
144-
for (let line = startLine; line <= endLine; line += stepSize) {
145-
this.activeDiffEditor?.revealRange(new vscode.Range(line, 0, line, 0), vscode.TextEditorRevealType.InCenter)
146-
await new Promise((resolve) => setTimeout(resolve, 16)) // ~60fps
151+
// Scroll to the last changed line only if the user hasn't scrolled up
152+
if (this.shouldAutoScroll) {
153+
if (diffLines.length <= 5) {
154+
// For small changes, just jump directly to the line
155+
this.scrollEditorToLine(currentLine)
156+
} else {
157+
// For larger changes, create a quick scrolling animation
158+
const startLine = this.streamedLines.length
159+
const endLine = currentLine
160+
const totalLines = endLine - startLine
161+
const numSteps = 10 // Adjust this number to control animation speed
162+
const stepSize = Math.max(1, Math.floor(totalLines / numSteps))
163+
164+
// Create and await the smooth scrolling animation
165+
for (let line = startLine; line <= endLine; line += stepSize) {
166+
this.activeDiffEditor?.revealRange(
167+
new vscode.Range(line, 0, line, 0),
168+
vscode.TextEditorRevealType.InCenter,
169+
)
170+
await new Promise((resolve) => setTimeout(resolve, 16)) // ~60fps
171+
}
172+
// Ensure we end at the final line
173+
this.scrollEditorToLine(currentLine)
147174
}
148-
// Ensure we end at the final line
149-
this.scrollEditorToLine(currentLine)
150175
}
151176
}
152177

@@ -418,5 +443,15 @@ export class DiffViewProvider {
418443
this.activeLineController = undefined
419444
this.streamedLines = []
420445
this.preDiagnostics = []
446+
447+
// Clean up the scroll listener
448+
if (this.scrollListener) {
449+
this.scrollListener.dispose()
450+
this.scrollListener = undefined
451+
}
452+
453+
// Reset auto-scroll state
454+
this.shouldAutoScroll = true
455+
this.lastFirstVisibleLine = 0
421456
}
422457
}

0 commit comments

Comments
 (0)