Refactor DiffViewProvider

This commit is contained in:
Saoud Rizwan
2024-09-29 19:06:07 -04:00
parent 8b243fa536
commit 20c1984fb0
2 changed files with 110 additions and 104 deletions

View File

@@ -888,13 +888,21 @@ export class ClaudeDev {
const partialMessage = JSON.stringify(sharedMessageProps) const partialMessage = JSON.stringify(sharedMessageProps)
await this.ask("tool", partialMessage, block.partial).catch(() => {}) await this.ask("tool", partialMessage, block.partial).catch(() => {})
// update editor // 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 break
} else { } else {
// if isEditingFile false, that means we have the full contents of the file already. // 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. // 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 // 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) { if (!relPath) {
this.consecutiveMistakeCount++ this.consecutiveMistakeCount++
pushToolResult(await this.sayAndCreateMissingParamError("write_to_file", "path")) pushToolResult(await this.sayAndCreateMissingParamError("write_to_file", "path"))

View File

@@ -1,34 +1,26 @@
import * as vscode from "vscode" import * as vscode from "vscode"
import * as path from "path" import * as path from "path"
import * as fs from "fs/promises" import * as fs from "fs/promises"
import { createDirectoriesForFile, fileExistsAtPath } from "../../utils/fs" import { createDirectoriesForFile } from "../../utils/fs"
import { arePathsEqual } from "../../utils/path" import { arePathsEqual } from "../../utils/path"
import { formatResponse } from "../../core/prompts/responses" import { formatResponse } from "../../core/prompts/responses"
import * as diff from "diff"
export class DiffViewProvider { export class DiffViewProvider {
editType?: "create" | "modify" editType?: "create" | "modify"
isEditing = false isEditing = false
// private isEditingExistingFile: boolean | undefined
originalContent: string | undefined originalContent: string | undefined
private createdDirs: string[] = [] private createdDirs: string[] = []
private documentWasOpen = false private documentWasOpen = false
private relPath?: string private relPath?: string
private newContent?: string private newContent?: string
constructor(private cwd: string) {} constructor(private cwd: string) {}
async update(relPath: string, newContent: string): Promise<void> { async open(relPath: string): Promise<void> {
this.relPath = relPath this.relPath = relPath
this.newContent = newContent
const fileExists = this.editType === "modify" const fileExists = this.editType === "modify"
const absolutePath = path.resolve(this.cwd, relPath) const absolutePath = path.resolve(this.cwd, relPath)
if (!this.isEditing) {
// starting edit
// open the editor and prepare to stream content in
this.isEditing = true this.isEditing = true
// if the file is already open, ensure it's not dirty before getting its contents // 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) .map((tg) => tg.tabs)
.flat() .flat()
.filter( .filter(
(tab) => (tab) => tab.input instanceof vscode.TabInputText && arePathsEqual(tab.input.uri.fsPath, absolutePath)
tab.input instanceof vscode.TabInputText && arePathsEqual(tab.input.uri.fsPath, absolutePath)
) )
for (const tab of tabs) { for (const tab of tabs) {
await vscode.window.tabGroups.close(tab) 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) => const updatedDocument = vscode.workspace.textDocuments.find((doc) =>
arePathsEqual(doc.uri.fsPath, absolutePath) arePathsEqual(doc.uri.fsPath, absolutePath)
@@ -132,13 +130,13 @@ export class DiffViewProvider {
updatedDocument.positionAt(0), updatedDocument.positionAt(0),
updatedDocument.positionAt(updatedDocument.getText().length) updatedDocument.positionAt(updatedDocument.getText().length)
) )
edit.replace(updatedDocument.uri, fullRange, newContent) edit.replace(updatedDocument.uri, fullRange, this.newContent)
} else { } else {
const fullRange = new vscode.Range( const fullRange = new vscode.Range(
updatedDocument.positionAt(0), updatedDocument.positionAt(0),
updatedDocument.positionAt(updatedDocument.getText().length) 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 // 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 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 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 Getting diagnostics before and after the file edit is a better approach than
@@ -334,7 +332,7 @@ export class DiffViewProvider {
if (updatedDocument.isDirty) { if (updatedDocument.isDirty) {
await updatedDocument.save() await updatedDocument.save()
} }
await this.closeDiffViews() await this.closeAllDiffViews()
await fs.unlink(absolutePath) await fs.unlink(absolutePath)
// Remove only the directories we created, in reverse order // Remove only the directories we created, in reverse order
for (let i = this.createdDirs.length - 1; i >= 0; i--) { for (let i = this.createdDirs.length - 1; i >= 0; i--) {
@@ -359,14 +357,14 @@ export class DiffViewProvider {
preview: false, preview: false,
}) })
} }
await this.closeDiffViews() await this.closeAllDiffViews()
} }
// edit is done // edit is done
this.reset() await this.reset()
} }
async closeDiffViews() { private async closeAllDiffViews() {
const tabs = vscode.window.tabGroups.all const tabs = vscode.window.tabGroups.all
.map((tg) => tg.tabs) .map((tg) => tg.tabs)
.flat() .flat()