create diffArea; remove _computedLensesOfDocument

This commit is contained in:
Mathew P 2024-10-03 03:00:55 -07:00
parent f4a407d80f
commit 19b2b8bd77
4 changed files with 51 additions and 26 deletions

View file

@ -1,13 +1,8 @@
import * as vscode from 'vscode';
import { SuggestedEdit } from './getDiffedLines';
import { Diff, DiffArea } from './shared_types';
// each diff on the user's screen right now
type DiffType = {
diffid: number,
lenses: vscode.CodeLens[],
greenRange: vscode.Range,
originalCode: string, // If a revert happens, we replace the greenRange with this content.
}
// TODO in theory this should be disposed
const greenDecoration = vscode.window.createTextEditorDecorationType({
@ -19,7 +14,9 @@ const greenDecoration = vscode.window.createTextEditorDecorationType({
// responsible for displaying diffs and showing accept/reject buttons
export class ApplyChangesProvider implements vscode.CodeLensProvider {
private _diffsOfDocument: { [docUriStr: string]: DiffType[] } = {};
private _diffAreasOfDocument: { [docUriStr: string]: DiffArea[] } = {}
private _diffsOfDocument: { [docUriStr: string]: Diff[] } = {}
private _computedLensesOfDocument: { [docUriStr: string]: vscode.CodeLens[] } = {} // computed from diffsOfDocument[docUriStr].lenses
private _diffidPool = 0
private _weAreEditing: boolean = false
@ -32,7 +29,7 @@ export class ApplyChangesProvider implements vscode.CodeLensProvider {
// used internally by vscode
public provideCodeLenses(document: vscode.TextDocument, token: vscode.CancellationToken): vscode.ProviderResult<vscode.CodeLens[]> {
const docUriStr = document.uri.toString()
return this._computedLensesOfDocument[docUriStr]
return this._diffsOfDocument[docUriStr].flatMap(diff => diff.lenses)
}
// declared by us, registered with vscode.languages.registerCodeLensProvider()
@ -51,7 +48,6 @@ export class ApplyChangesProvider implements vscode.CodeLensProvider {
this._diffsOfDocument[docUriStr].splice(0) // clear diffs
editor.setDecorations(greenDecoration, []) // clear decorations
this._computedLensesOfDocument[docUriStr] = this._diffsOfDocument[docUriStr].flatMap(diff => diff.lenses) // recompute codelenses
this._onDidChangeCodeLenses.fire() // rerender codelenses
})
}
@ -59,7 +55,7 @@ export class ApplyChangesProvider implements vscode.CodeLensProvider {
// used by us only
private refreshLenses = (editor: vscode.TextEditor, docUriStr: string) => {
editor.setDecorations(greenDecoration, this._diffsOfDocument[docUriStr].map(diff => diff.greenRange)) // refresh highlighting
this._computedLensesOfDocument[docUriStr] = this._diffsOfDocument[docUriStr].flatMap(diff => diff.lenses) // recompute _computedLensesOfDocument (can optimize this later)
this._onDidChangeCodeLenses.fire() // fire event for vscode to refresh lenses
}
@ -72,9 +68,6 @@ export class ApplyChangesProvider implements vscode.CodeLensProvider {
// if no diffs, set diffs to []
if (!this._diffsOfDocument[docUriStr])
this._diffsOfDocument[docUriStr] = []
// if no codelenses, set codelenses to []
if (!this._computedLensesOfDocument[docUriStr])
this._computedLensesOfDocument[docUriStr] = []
// 1. convert suggested edits (which are described using line numbers) into actual edits (described using vscode.Range, vscode.Uri)

View file

@ -1,5 +1,5 @@
import * as vscode from 'vscode';
import { WebviewMessage } from './shared_types';
import { DiffArea, WebviewMessage } from './shared_types';
import { CtrlKCodeLensProvider } from './CtrlKCodeLensProvider';
import { getDiffedLines } from './getDiffedLines';
import { ApplyChangesProvider as DisplayChangesProvider } from './DisplayChangesProvider';
@ -121,12 +121,28 @@ export function activate(context: vscode.ExtensionContext) {
return
}
const beforeCode = await readFileContentOfUri(editor.document.uri)
const diffArea: DiffArea = {
startLine: 0, // in ctrl+L the start and end lines are the full document
endLine: editor.document.lineCount,
originalCode: undefined,
}
// TODO change this to be animated
const suggestedEdits = getDiffedLines(beforeCode, m.code)
// save the original code
diffArea.originalCode = await readFileContentOfUri(editor.document.uri)
// when changes have been created
// write the new code `m.code` to the document
// TODO make this animated
editor.edit(editBuilder => {
editBuilder.replace(new vscode.Range(diffArea.startLine, 0, diffArea.endLine, 0), m.code);
});
// rediff the changes based on the diffArea (start, end, original code, current code)
// TODO!!! put this logic in `displayChangesProvider.displayChanges(diffArea)` function
const suggestedEdits = getDiffedLines(diffArea.originalCode, m.code)
await displayChangesProvider.addNewChanges(editor, suggestedEdits)
}
else if (m.type === 'getApiConfig') {

View file

@ -3,14 +3,29 @@ import * as vscode from 'vscode';
import { ApiConfig } from './common/sendLLMMessage';
// a selection is a frozen snapshot
type Selection = { selectionStr: string, selectionRange: vscode.Range, filePath: vscode.Uri }
type CodeSelection = { selectionStr: string, selectionRange: vscode.Range, filePath: vscode.Uri }
type File = { filepath: vscode.Uri, content: string }
// an area that is currently being diffed
type DiffArea = {
startLine: number,
endLine: number,
originalCode: string | undefined
}
// each diff on the user's screen right now
type Diff = {
diffid: number,
lenses: vscode.CodeLens[],
greenRange: vscode.Range,
originalCode: string, // If a revert happens, we replace the greenRange with this content.
}
type WebviewMessage = (
// editor -> sidebar
| { type: 'ctrl+l', selection: Selection } // user presses ctrl+l in the editor
| { type: 'ctrl+l', selection: CodeSelection } // user presses ctrl+l in the editor
// sidebar -> editor
| { type: 'applyChanges', code: string } // user clicks "apply" in the sidebar
@ -32,8 +47,9 @@ type WebviewMessage = (
type Command = WebviewMessage['type']
export {
Selection,
CodeSelection,
File,
WebviewMessage,
Command,
Diff, DiffArea,
}

View file

@ -1,6 +1,6 @@
import React, { useState, ChangeEvent, useEffect, useRef, useCallback, FormEvent } from "react"
import { ApiConfig, LLMMessage, sendLLMMessage } from "../common/sendLLMMessage"
import { Command, File, Selection, WebviewMessage } from "../shared_types"
import { Command, File, CodeSelection, WebviewMessage } from "../shared_types"
import { awaitVSCodeResponse, getVSCodeAPI, resolveAwaitingVSCodeResponse } from "./getVscodeApi"
import { marked } from 'marked';
@ -18,7 +18,7 @@ ${content}
\`\`\``).join('\n')
}
const userInstructionsStr = (instructions: string, files: File[], selection: Selection | null) => {
const userInstructionsStr = (instructions: string, files: File[], selection: CodeSelection | null) => {
return `
${filesStr(files)}
@ -110,7 +110,7 @@ type ChatMessage = {
role: 'user'
content: string, // content sent to the llm
displayContent: string, // content displayed to user
selection: Selection | null, // the user's selection
selection: CodeSelection | null, // the user's selection
files: vscode.Uri[], // the files sent in the message
} | {
role: 'assistant',
@ -136,7 +136,7 @@ const useInstantState = <T,>(initVal: T) => {
const Sidebar = () => {
// state of current message
const [selection, setSelection] = useState<Selection | null>(null) // the code the user is selecting
const [selection, setSelection] = useState<CodeSelection | null>(null) // the code the user is selecting
const [files, setFiles] = useState<vscode.Uri[]>([]) // the names of the files in the chat
const [instructions, setInstructions] = useState('') // the user's instructions