mirror of
https://github.com/pacnpal/Roo-Code.git
synced 2025-12-21 04:41:16 -05:00
Refactor DiffViewProvider
This commit is contained in:
@@ -888,13 +888,21 @@ export class ClaudeDev {
|
||||
const partialMessage = JSON.stringify(sharedMessageProps)
|
||||
await this.ask("tool", partialMessage, block.partial).catch(() => {})
|
||||
// update editor
|
||||
await this.diffViewProvider.update(relPath, newContent)
|
||||
if (!this.diffViewProvider.isEditing) {
|
||||
// open the editor and prepare to stream content in
|
||||
await this.diffViewProvider.open(relPath)
|
||||
}
|
||||
// editor is open, stream content in
|
||||
await this.diffViewProvider.update(newContent)
|
||||
break
|
||||
} else {
|
||||
// if isEditingFile false, that means we have the full contents of the file already.
|
||||
// it's important to note how this function works, you can't make the assumption that the block.partial conditional will always be called since it may immediately get complete, non-partial data. So this part of the logic will always be called.
|
||||
// in other words, you must always repeat the block.partial logic here
|
||||
await this.diffViewProvider.update(relPath, newContent)
|
||||
if (!this.diffViewProvider.isEditing) {
|
||||
await this.diffViewProvider.open(relPath)
|
||||
}
|
||||
await this.diffViewProvider.update(newContent)
|
||||
if (!relPath) {
|
||||
this.consecutiveMistakeCount++
|
||||
pushToolResult(await this.sayAndCreateMissingParamError("write_to_file", "path"))
|
||||
|
||||
@@ -1,34 +1,26 @@
|
||||
import * as vscode from "vscode"
|
||||
import * as path from "path"
|
||||
import * as fs from "fs/promises"
|
||||
import { createDirectoriesForFile, fileExistsAtPath } from "../../utils/fs"
|
||||
import { createDirectoriesForFile } from "../../utils/fs"
|
||||
import { arePathsEqual } from "../../utils/path"
|
||||
import { formatResponse } from "../../core/prompts/responses"
|
||||
import * as diff from "diff"
|
||||
|
||||
export class DiffViewProvider {
|
||||
editType?: "create" | "modify"
|
||||
isEditing = false
|
||||
// private isEditingExistingFile: boolean | undefined
|
||||
originalContent: string | undefined
|
||||
private createdDirs: string[] = []
|
||||
private documentWasOpen = false
|
||||
|
||||
private relPath?: string
|
||||
private newContent?: string
|
||||
|
||||
constructor(private cwd: string) {}
|
||||
|
||||
async update(relPath: string, newContent: string): Promise<void> {
|
||||
async open(relPath: string): Promise<void> {
|
||||
this.relPath = relPath
|
||||
this.newContent = newContent
|
||||
const fileExists = this.editType === "modify"
|
||||
const absolutePath = path.resolve(this.cwd, relPath)
|
||||
|
||||
if (!this.isEditing) {
|
||||
// starting edit
|
||||
// open the editor and prepare to stream content in
|
||||
|
||||
this.isEditing = true
|
||||
|
||||
// if the file is already open, ensure it's not dirty before getting its contents
|
||||
@@ -109,8 +101,7 @@ export class DiffViewProvider {
|
||||
.map((tg) => tg.tabs)
|
||||
.flat()
|
||||
.filter(
|
||||
(tab) =>
|
||||
tab.input instanceof vscode.TabInputText && arePathsEqual(tab.input.uri.fsPath, absolutePath)
|
||||
(tab) => tab.input instanceof vscode.TabInputText && arePathsEqual(tab.input.uri.fsPath, absolutePath)
|
||||
)
|
||||
for (const tab of tabs) {
|
||||
await vscode.window.tabGroups.close(tab)
|
||||
@@ -118,7 +109,14 @@ export class DiffViewProvider {
|
||||
}
|
||||
}
|
||||
|
||||
// editor is open, stream content in
|
||||
async update(newContent: string): Promise<void> {
|
||||
if (!this.relPath) {
|
||||
return
|
||||
}
|
||||
this.newContent = newContent
|
||||
|
||||
const fileExists = this.editType === "modify"
|
||||
const absolutePath = path.resolve(this.cwd, this.relPath)
|
||||
|
||||
const updatedDocument = vscode.workspace.textDocuments.find((doc) =>
|
||||
arePathsEqual(doc.uri.fsPath, absolutePath)
|
||||
@@ -132,13 +130,13 @@ export class DiffViewProvider {
|
||||
updatedDocument.positionAt(0),
|
||||
updatedDocument.positionAt(updatedDocument.getText().length)
|
||||
)
|
||||
edit.replace(updatedDocument.uri, fullRange, newContent)
|
||||
edit.replace(updatedDocument.uri, fullRange, this.newContent)
|
||||
} else {
|
||||
const fullRange = new vscode.Range(
|
||||
updatedDocument.positionAt(0),
|
||||
updatedDocument.positionAt(updatedDocument.getText().length)
|
||||
)
|
||||
edit.replace(updatedDocument.uri, fullRange, newContent)
|
||||
edit.replace(updatedDocument.uri, fullRange, this.newContent)
|
||||
}
|
||||
// Apply the edit, but without saving so this doesnt trigger a local save in timeline history
|
||||
await vscode.workspace.applyEdit(edit) // has the added benefit of maintaing the file's original EOLs
|
||||
@@ -272,7 +270,7 @@ export class DiffViewProvider {
|
||||
|
||||
await vscode.window.showTextDocument(vscode.Uri.file(absolutePath), { preview: false })
|
||||
|
||||
await this.closeDiffViews()
|
||||
await this.closeAllDiffViews()
|
||||
|
||||
/*
|
||||
Getting diagnostics before and after the file edit is a better approach than
|
||||
@@ -334,7 +332,7 @@ export class DiffViewProvider {
|
||||
if (updatedDocument.isDirty) {
|
||||
await updatedDocument.save()
|
||||
}
|
||||
await this.closeDiffViews()
|
||||
await this.closeAllDiffViews()
|
||||
await fs.unlink(absolutePath)
|
||||
// Remove only the directories we created, in reverse order
|
||||
for (let i = this.createdDirs.length - 1; i >= 0; i--) {
|
||||
@@ -359,14 +357,14 @@ export class DiffViewProvider {
|
||||
preview: false,
|
||||
})
|
||||
}
|
||||
await this.closeDiffViews()
|
||||
await this.closeAllDiffViews()
|
||||
}
|
||||
|
||||
// edit is done
|
||||
this.reset()
|
||||
await this.reset()
|
||||
}
|
||||
|
||||
async closeDiffViews() {
|
||||
private async closeAllDiffViews() {
|
||||
const tabs = vscode.window.tabGroups.all
|
||||
.map((tg) => tg.tabs)
|
||||
.flat()
|
||||
|
||||
Reference in New Issue
Block a user