mirror of
https://github.com/voideditor/void
synced 2026-05-24 09:58:23 +00:00
draft
This commit is contained in:
parent
4b5e09c124
commit
d4a2ac2796
4 changed files with 323 additions and 96 deletions
|
|
@ -1,8 +0,0 @@
|
|||
|
||||
class Diff {
|
||||
|
||||
constructor(){
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
115
extensions/void/src/DiffProvider.ts
Normal file
115
extensions/void/src/DiffProvider.ts
Normal file
|
|
@ -0,0 +1,115 @@
|
|||
import * as vscode from 'vscode';
|
||||
import { SuggestedEdit } from './findDiffs';
|
||||
|
||||
const greenDecoration = vscode.window.createTextEditorDecorationType({
|
||||
backgroundColor: 'rgba(0 255 51 / 0.2)',
|
||||
isWholeLine: false, // after: { contentText: ' [original]', color: 'rgba(0 255 60 / 0.5)' } // hoverMessage: originalText // this applies to hovering over after:...
|
||||
})
|
||||
|
||||
|
||||
|
||||
|
||||
export class DiffProvider {
|
||||
|
||||
originalCodeOfDocument: { [docUri: string]: string }
|
||||
|
||||
|
||||
|
||||
diffsOfDocument: {
|
||||
[docUri: string]: {
|
||||
startLine,
|
||||
startCol,
|
||||
endLine,
|
||||
endCol,
|
||||
originalText,
|
||||
|
||||
inset,
|
||||
diffid,
|
||||
}
|
||||
}
|
||||
|
||||
// sweep
|
||||
currentLine: { [docUri: string]: undefined | number }
|
||||
weAreEditing: boolean = false
|
||||
|
||||
|
||||
constructor() {
|
||||
|
||||
vscode.workspace.onDidChangeTextDocument((e) => {
|
||||
// on user change, grow/shrink/merge/delete diff AREAS
|
||||
// you dont have to do anything to the diffs here bc they all get recomputed in refresh()
|
||||
// user changes only get highlighted if theyre in a diffarea
|
||||
|
||||
// go thru all diff areas and adjust line numbers based on the user's change
|
||||
|
||||
|
||||
this.refreshStyles(e.document.uri.toString())
|
||||
})
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
// refreshes styles on page
|
||||
refreshStyles(docUriStr: string) {
|
||||
|
||||
if (this.weAreEditing) return
|
||||
|
||||
// recompute all diffs on the page
|
||||
// run inset.dispose() on all diffs
|
||||
|
||||
// original and current code -> diffs
|
||||
// originalCodeOfDocument[docUriStr]
|
||||
|
||||
// create new diffs
|
||||
const inset = vscode.window.createWebviewTextEditorInset(editor, lineStart, height, {})
|
||||
inset.webview.html = `
|
||||
<html>
|
||||
<body style="pointer-events:none;">Hello World!</body>
|
||||
</html>
|
||||
`;
|
||||
|
||||
}
|
||||
|
||||
// called on void.acceptDiff
|
||||
public async acceptDiff({ diffid }: { diffid: number }) {
|
||||
|
||||
// update original based on the diff
|
||||
// refresh()
|
||||
|
||||
}
|
||||
|
||||
|
||||
// called on void.rejectDiff
|
||||
public async rejectDiff({ diffid }: { diffid: number }) {
|
||||
|
||||
// get diffs[diffid]
|
||||
|
||||
// revert current file based on diff
|
||||
// refresh()
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
// sweep
|
||||
initializeSweep({ startLine }) {
|
||||
// reject all diffs on the page
|
||||
// store original code
|
||||
// currentLine=start of sweep
|
||||
}
|
||||
|
||||
onUpdateSweep(addedText) {
|
||||
// update final
|
||||
// refresh() ?
|
||||
// currentLine += number of newlines in addedText
|
||||
}
|
||||
|
||||
onAbortSweep() {
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
|
@ -1,10 +1,12 @@
|
|||
import * as vscode from 'vscode';
|
||||
import { DisplayChangesProvider } from './DisplayChangesProvider';
|
||||
import { BaseDiffArea, ChatThreads, MessageFromSidebar, MessageToSidebar } from './common/shared_types';
|
||||
import { ApprovalCodeLensProvider } from './ApprovalCodeLensProvider';
|
||||
import { ChatThreads, MessageFromSidebar, MessageToSidebar } from './common/shared_types';
|
||||
import { SidebarWebviewProvider } from './SidebarWebviewProvider';
|
||||
import { v4 as uuidv4 } from 'uuid'
|
||||
import { applyDiffLazily } from './common/ctrlL';
|
||||
import { getVoidConfig } from './sidebar/contextForConfig';
|
||||
import { DiffProvider } from './DiffProvider';
|
||||
// import { getVoidConfig } from './sidebar/contextForConfig';
|
||||
|
||||
// this comes from vscode.proposed.editorInsets.d.ts
|
||||
declare module 'vscode' {
|
||||
|
|
@ -88,7 +90,8 @@ export function activate(context: vscode.ExtensionContext) {
|
|||
);
|
||||
|
||||
// 3. Show an approve/reject
|
||||
const displayChangesProvider = new DisplayChangesProvider();
|
||||
const displayChangesProvider = new DiffProvider();
|
||||
// context.subscriptions.push(vscode.languages.registerCodeLensProvider('*', displayChangesProvider));
|
||||
|
||||
// 4. Add approve/reject commands
|
||||
context.subscriptions.push(vscode.commands.registerCommand('void.acceptDiff', async (params) => {
|
||||
|
|
@ -135,16 +138,15 @@ export function activate(context: vscode.ExtensionContext) {
|
|||
return
|
||||
}
|
||||
|
||||
|
||||
// create an area to show diffs
|
||||
const diffArea: BaseDiffArea = {
|
||||
startLine: 0, // in ctrl+L the start and end lines are the full document
|
||||
endLine: editor.document.lineCount,
|
||||
originalStartLine: 0,
|
||||
originalEndLine: editor.document.lineCount,
|
||||
originalCode: await readFileContentOfUri(editor.document.uri),
|
||||
}
|
||||
displayChangesProvider.addDiffArea(editor.document.uri, diffArea)
|
||||
// // create an area to show diffs
|
||||
// const diffArea = {
|
||||
// startLine: 0, // in ctrl+L the start and end lines are the full document
|
||||
// endLine: editor.document.lineCount,
|
||||
// originalStartLine: 0,
|
||||
// originalEndLine: editor.document.lineCount,
|
||||
// originalCode: await readFileContentOfUri(editor.document.uri),
|
||||
// }
|
||||
// displayChangesProvider.addDiffArea(editor.document.uri, diffArea)
|
||||
|
||||
|
||||
// write new code `m.code` to the document
|
||||
|
|
@ -168,7 +170,7 @@ export function activate(context: vscode.ExtensionContext) {
|
|||
// });
|
||||
|
||||
// rediff the changes based on the diffAreas
|
||||
displayChangesProvider.refreshDiffAreas(editor.document.uri)
|
||||
displayChangesProvider.refreshLenses(editor, editor.document.uri.toString())
|
||||
|
||||
}
|
||||
else if (m.type === 'getPartialVoidConfig') {
|
||||
|
|
|
|||
|
|
@ -1,9 +1,121 @@
|
|||
|
||||
import * as vscode from 'vscode';
|
||||
// import { diffLines, Change } from 'diff';
|
||||
import { diff_match_patch } from 'diff-match-patch';
|
||||
import { diffLines } from 'diff';
|
||||
import { BaseDiff } from './common/shared_types';
|
||||
import { diffLines, Change } from 'diff';
|
||||
|
||||
export type SuggestedEdit = {
|
||||
// start/end of current file
|
||||
startLine: number;
|
||||
startCol: number;
|
||||
endLine: number;
|
||||
endCol: number;
|
||||
|
||||
// start/end of original file
|
||||
originalStartLine: number,
|
||||
originalStartCol: number,
|
||||
originalEndLine: number,
|
||||
originalEndCol: number,
|
||||
type: 'insertion' | 'deletion' | 'edit',
|
||||
originalContent: string, // original content (originalfile[originalStart...originalEnd])
|
||||
newContent: string,
|
||||
}
|
||||
|
||||
export function findDiffs(oldStr: string, newStr: string) {
|
||||
// an ordered list of every original line, line added to the new file, and line removed from the old file (order is unambiguous, think about it)
|
||||
const lineByLineChanges: Change[] = diffLines(oldStr, newStr);
|
||||
lineByLineChanges.push({ value: '' }) // add a dummy so we flush any streaks we haven't yet at the very end (!line.added && !line.removed)
|
||||
|
||||
let oldFileLineNum: number = 0;
|
||||
let newFileLineNum: number = 0;
|
||||
|
||||
let streakStartInNewFile: number | undefined = undefined
|
||||
let streakStartInOldFile: number | undefined = undefined
|
||||
|
||||
let oldStrLines = oldStr.split('\n')
|
||||
let newStrLines = newStr.split('\n')
|
||||
|
||||
const replacements: SuggestedEdit[] = []
|
||||
for (let line of lineByLineChanges) {
|
||||
|
||||
// no change on this line
|
||||
if (!line.added && !line.removed) {
|
||||
|
||||
// do nothing
|
||||
|
||||
// if we were on a streak of +s and -s, end it
|
||||
if (streakStartInNewFile !== undefined) {
|
||||
let type: 'edit' | 'insertion' | 'deletion' = 'edit'
|
||||
|
||||
let startLine = streakStartInNewFile
|
||||
let endLine = newFileLineNum - 1 // don't include current line, the edit was up to this line but not including it
|
||||
let startCol = 0
|
||||
let endCol = Number.MAX_SAFE_INTEGER
|
||||
|
||||
let originalStartLine = streakStartInOldFile!
|
||||
let originalEndLine = oldFileLineNum - 1 // don't include current line, the edit was up to this line but not including it
|
||||
let originalStartCol = 0
|
||||
let originalEndCol = Number.MAX_SAFE_INTEGER
|
||||
|
||||
let newContent = newStrLines.slice(startLine, endLine + 1).join('\n')
|
||||
let originalContent = oldStrLines.slice(originalStartLine, originalEndLine + 1).join('\n')
|
||||
|
||||
// if the range is empty, mark it as a deletion / insertion (both won't be true at once)
|
||||
// DELETION
|
||||
if (endLine === startLine - 1) {
|
||||
type = 'deletion'
|
||||
endLine = startLine
|
||||
startCol = 0
|
||||
endCol = 0
|
||||
newContent += '\n'
|
||||
}
|
||||
|
||||
// INSERTION
|
||||
else if (originalEndLine === originalStartLine - 1) {
|
||||
type = 'insertion'
|
||||
originalEndLine = originalStartLine
|
||||
originalStartCol = 0
|
||||
originalEndCol = 0
|
||||
}
|
||||
|
||||
const replacement: SuggestedEdit = {
|
||||
type,
|
||||
startLine, startCol, endLine, endCol, newContent,
|
||||
originalStartLine, originalStartCol, originalEndLine, originalEndCol, originalContent
|
||||
} as SuggestedEdit
|
||||
|
||||
replacements.push(replacement)
|
||||
|
||||
streakStartInNewFile = undefined
|
||||
streakStartInOldFile = undefined
|
||||
}
|
||||
oldFileLineNum += line.count ?? 0;
|
||||
newFileLineNum += line.count ?? 0;
|
||||
}
|
||||
|
||||
// line was removed from old file
|
||||
else if (line.removed) {
|
||||
// if we weren't on a streak, start one on this current line num
|
||||
if (streakStartInNewFile === undefined) {
|
||||
streakStartInNewFile = newFileLineNum
|
||||
streakStartInOldFile = oldFileLineNum
|
||||
}
|
||||
oldFileLineNum += line.count ?? 0 // we processed the line so add 1
|
||||
}
|
||||
|
||||
// line was added to new file
|
||||
else if (line.added) {
|
||||
// if we weren't on a streak, start one on this current line num
|
||||
if (streakStartInNewFile === undefined) {
|
||||
streakStartInNewFile = newFileLineNum
|
||||
streakStartInOldFile = oldFileLineNum
|
||||
}
|
||||
newFileLineNum += line.count ?? 0; // we processed the line so add 1
|
||||
}
|
||||
} // end for
|
||||
|
||||
console.debug('Replacements', replacements)
|
||||
return replacements
|
||||
}
|
||||
|
||||
|
||||
|
||||
// const diffLinesOld = (text1: string, text2: string) => {
|
||||
|
|
@ -98,86 +210,92 @@ import { BaseDiff } from './common/shared_types';
|
|||
// };
|
||||
|
||||
|
||||
export const findDiffs = (oldText: string, newText: string): BaseDiff[] => {
|
||||
|
||||
let diffs = diffLines(oldText, newText)
|
||||
.map(diff => {
|
||||
const operation = diff.added ? 1 : diff.removed ? -1 : 0;
|
||||
const text = diff.value;
|
||||
return [operation, text] as const;
|
||||
})
|
||||
|
||||
|
||||
const blocks: BaseDiff[] = [];
|
||||
let reprBlock: string[] = [];
|
||||
let deletedBlock: string[] = [];
|
||||
let insertedBlock: string[] = [];
|
||||
let newFileLine = 0;
|
||||
let oldFileLine = 0;
|
||||
let insertedStart = 0;
|
||||
let deletedStart = 0;
|
||||
|
||||
diffs.forEach(([operation, text]) => {
|
||||
|
||||
const lines = text.split('\n');
|
||||
|
||||
switch (operation) {
|
||||
|
||||
// insertion
|
||||
case 1:
|
||||
if (reprBlock.length === 0) { reprBlock.push('@@@@'); }
|
||||
if (insertedBlock.length === 0) insertedStart = newFileLine;
|
||||
newFileLine += lines.length - 1; // update the line count for new text
|
||||
insertedBlock.push(text);
|
||||
reprBlock.push(lines.map(line => `+ ${line}`).join('\n'));
|
||||
break;
|
||||
// export const findDiffs = (oldText: string, newText: string): BaseDiff[] => {
|
||||
|
||||
// deletion
|
||||
case -1:
|
||||
if (reprBlock.length === 0) { reprBlock.push('@@@@'); }
|
||||
if (deletedBlock.length === 0) deletedStart = oldFileLine;
|
||||
oldFileLine += lines.length - 1; // update the line count for old text
|
||||
deletedBlock.push(text);
|
||||
reprBlock.push(lines.map(line => `- ${line}`).join('\n'));
|
||||
break;
|
||||
// let diffs = diffLines(oldText, newText)
|
||||
// .map(diff => {
|
||||
// const operation = diff.added ? 1 : diff.removed ? -1 : 0;
|
||||
// const text = diff.value;
|
||||
// return [operation, text] as const;
|
||||
// })
|
||||
|
||||
// no change
|
||||
case 0:
|
||||
// add pending block to the blocks array
|
||||
if (insertedBlock.length > 0 || deletedBlock.length > 0) {
|
||||
blocks.push({
|
||||
code: reprBlock.join(''),
|
||||
deletedCode: deletedBlock.join(''),
|
||||
insertedCode: insertedBlock.join(''),
|
||||
deletedRange: new vscode.Range(deletedStart, 0, oldFileLine, Number.MAX_SAFE_INTEGER),
|
||||
insertedRange: new vscode.Range(insertedStart, 0, newFileLine, Number.MAX_SAFE_INTEGER),
|
||||
});
|
||||
}
|
||||
|
||||
// update variables
|
||||
reprBlock = [];
|
||||
deletedBlock = [];
|
||||
insertedBlock = [];
|
||||
deletedStart += lines.length - 1;
|
||||
insertedStart += lines.length - 1;
|
||||
newFileLine += lines.length - 1;
|
||||
oldFileLine += lines.length - 1;
|
||||
// const blocks: BaseDiff[] = [];
|
||||
// let reprBlock: string[] = [];
|
||||
// let deletedBlock: string[] = [];
|
||||
// let insertedBlock: string[] = [];
|
||||
// let newFileLine = 0;
|
||||
// let oldFileLine = 0;
|
||||
// let insertedStart = 0;
|
||||
// let deletedStart = 0;
|
||||
|
||||
break;
|
||||
}
|
||||
});
|
||||
// diffs.forEach(([operation, text]) => {
|
||||
|
||||
// Add any remaining blocks after the loop ends
|
||||
if (insertedBlock.length > 0 || deletedBlock.length > 0) {
|
||||
blocks.push({
|
||||
code: reprBlock.join(''),
|
||||
deletedCode: deletedBlock.join(''),
|
||||
insertedCode: insertedBlock.join(''),
|
||||
deletedRange: new vscode.Range(deletedStart, 0, oldFileLine, Number.MAX_SAFE_INTEGER),
|
||||
insertedRange: new vscode.Range(insertedStart, 0, newFileLine, Number.MAX_SAFE_INTEGER),
|
||||
});
|
||||
}
|
||||
// const lines = text.split('\n');
|
||||
|
||||
return blocks;
|
||||
};
|
||||
// switch (operation) {
|
||||
|
||||
// // insertion
|
||||
// case 1:
|
||||
// if (reprBlock.length === 0) { reprBlock.push('@@@@'); }
|
||||
// if (insertedBlock.length === 0) insertedStart = newFileLine;
|
||||
// newFileLine += lines.length - 1; // update the line count for new text
|
||||
// insertedBlock.push(text);
|
||||
// reprBlock.push(lines.map(line => `+ ${line}`).join('\n'));
|
||||
// break;
|
||||
|
||||
// // deletion
|
||||
// case -1:
|
||||
// if (reprBlock.length === 0) { reprBlock.push('@@@@'); }
|
||||
// if (deletedBlock.length === 0) deletedStart = oldFileLine;
|
||||
// oldFileLine += lines.length - 1; // update the line count for old text
|
||||
// deletedBlock.push(text);
|
||||
// reprBlock.push(lines.map(line => `- ${line}`).join('\n'));
|
||||
// break;
|
||||
|
||||
// // no change
|
||||
// case 0:
|
||||
// // add pending block to the blocks array
|
||||
// if (insertedBlock.length > 0 || deletedBlock.length > 0) {
|
||||
// blocks.push({
|
||||
// code: reprBlock.join(''),
|
||||
// deletedCode: deletedBlock.join(''),
|
||||
// insertedCode: insertedBlock.join(''),
|
||||
// deletedRange: new vscode.Range(deletedStart, 0, oldFileLine, Number.MAX_SAFE_INTEGER),
|
||||
// insertedRange: new vscode.Range(insertedStart, 0, newFileLine, Number.MAX_SAFE_INTEGER),
|
||||
// });
|
||||
// }
|
||||
|
||||
// // update variables
|
||||
// reprBlock = [];
|
||||
// deletedBlock = [];
|
||||
// insertedBlock = [];
|
||||
// deletedStart += lines.length - 1;
|
||||
// insertedStart += lines.length - 1;
|
||||
// newFileLine += lines.length - 1;
|
||||
// oldFileLine += lines.length - 1;
|
||||
|
||||
// break;
|
||||
// }
|
||||
// });
|
||||
|
||||
// // Add any remaining blocks after the loop ends
|
||||
// if (insertedBlock.length > 0 || deletedBlock.length > 0) {
|
||||
// blocks.push({
|
||||
// code: reprBlock.join(''),
|
||||
// deletedCode: deletedBlock.join(''),
|
||||
// insertedCode: insertedBlock.join(''),
|
||||
// deletedRange: new vscode.Range(deletedStart, 0, oldFileLine, Number.MAX_SAFE_INTEGER),
|
||||
// insertedRange: new vscode.Range(insertedStart, 0, newFileLine, Number.MAX_SAFE_INTEGER),
|
||||
// });
|
||||
// }
|
||||
|
||||
// return blocks;
|
||||
// };
|
||||
|
||||
|
|
|
|||
Loading…
Reference in a new issue