start editing registerInlineDiff

This commit is contained in:
Andrew Pareles 2024-11-12 00:40:33 -08:00
parent 6e2030d4d4
commit 4de3f1c7ef

View file

@ -2,63 +2,65 @@
import { Disposable } from '../../../../base/common/lifecycle.js';
import { registerSingleton, InstantiationType } from '../../../../platform/instantiation/common/extensions.js';
import { createDecorator } from '../../../../platform/instantiation/common/instantiation.js';
import { ICodeEditor, IViewZone } from '../../../../editor/browser/editorBrowser.js';
import { IModelDeltaDecoration } from '../../../common/model.js';
import { ICodeEditor, IViewZone } from '../../editorBrowser.js';
import { IRange } from '../../../common/core/range.js';
import { EditorOption } from '../../../common/config/editorOptions.js';
import { UndoRedoGroup } from '../../../../platform/undoRedo/common/undoRedo.js';
// else if (m.type === 'applyChanges') {
if (m.type === 'applyChanges') {
// const editor = vscode.window.activeTextEditor
// if (!editor) {
// vscode.window.showInformationMessage('No active editor!')
// return
// }
// // create an area to show diffs
// const partialDiffArea: Omit<DiffArea, 'diffareaid'> = {
// startLine: 0, // in ctrl+L the start and end lines are the full document
// endLine: editor.document.lineCount,
// originalStartLine: 0,
// originalEndLine: editor.document.lineCount,
// sweepIndex: null,
// }
// const diffArea = diffProvider.createDiffArea(editor.document.uri, partialDiffArea, await readFileContentOfUri(editor.document.uri))
const editor = vscode.window.activeTextEditor
if (!editor) {
vscode.window.showInformationMessage('No active editor!')
return
}
// create an area to show diffs
const partialDiffArea: Omit<DiffArea, 'diffareaid'> = {
startLine: 0, // in ctrl+L the start and end lines are the full document
endLine: editor.document.lineCount,
originalStartLine: 0,
originalEndLine: editor.document.lineCount,
sweepIndex: null,
}
const diffArea = diffProvider.createDiffArea(editor.document.uri, partialDiffArea, await readFileContentOfUri(editor.document.uri))
// const docUri = editor.document.uri
// const fileStr = await readFileContentOfUri(docUri)
// const voidConfig = getVoidConfigFromPartial(context.globalState.get('partialVoidConfig') ?? {})
const docUri = editor.document.uri
const fileStr = await readFileContentOfUri(docUri)
const voidConfig = getVoidConfigFromPartial(context.globalState.get('partialVoidConfig') ?? {})
// await diffProvider.startStreamingInDiffArea({ docUri, oldFileStr: fileStr, diffRepr: m.diffRepr, voidConfig, diffArea, abortRef: abortApplyRef })
// }
await diffProvider.startStreamingInDiffArea({ docUri, oldFileStr: fileStr, diffRepr: m.diffRepr, voidConfig, diffArea, abortRef: abortApplyRef })
}
// // an area that is currently being diffed
// type DiffArea = {
// diffareaid: number,
// startLine: number,
// endLine: number,
// originalStartLine: number,
// originalEndLine: number,
// sweepIndex: number | null // null iff not sweeping
// }
type DiffArea = {
diffareaid: number,
startLine: number,
endLine: number,
originalStartLine: number,
originalEndLine: number,
sweepIndex: number | null // null iff not sweeping
}
// // the return type of diff creator
// type BaseDiff = {
// type: 'edit' | 'insertion' | 'deletion';
// // repr: string; // representation of the diff in text
// originalRange: vscode.Range;
// originalCode: string;
// range: vscode.Range;
// code: string;
// }
// the return type of diff creator
type BaseDiff = {
type: 'edit' | 'insertion' | 'deletion';
// repr: string; // representation of the diff in text
originalRange: vscode.Range;
originalCode: string;
range: vscode.Range;
code: string;
}
// // each diff on the user's screen
// type Diff = {
// diffid: number,
// lenses: vscode.CodeLens[],
// } & BaseDiff
// each diff on the user's screen
type Diff = BaseDiff & {
diffid: number,
lenses: vscode.CodeLens[],
}
@ -137,12 +139,20 @@ class InlineDiffService extends Disposable implements IInlineDiffService {
lineContent.appendChild(contentSpan);
domNode.appendChild(lineContent);
// gutter element
const gutterDiv = document.createElement('div');
gutterDiv.className = 'inline-diff-gutter';
const minusDiv = document.createElement('div');
minusDiv.className = 'inline-diff-deleted-gutter';
// minusDiv.textContent = '-';
gutterDiv.appendChild(minusDiv);
const viewZone: IViewZone = {
afterLineNumber: modifiedRange.startLineNumber - 1,
heightInLines: originalText.split('\n').length + 1,
domNode: domNode,
suppressMouseDown: true,
marginDomNode: this.createGutterElement()
marginDomNode: gutterDiv
};
const zoneId = accessor.addZone(viewZone);
@ -151,18 +161,6 @@ class InlineDiffService extends Disposable implements IInlineDiffService {
});
}
// gutter is the thing to the left
private createGutterElement(): HTMLElement {
const gutterDiv = document.createElement('div');
gutterDiv.className = 'inline-diff-gutter';
const minusDiv = document.createElement('div');
minusDiv.className = 'inline-diff-deleted-gutter';
// minusDiv.textContent = '-';
gutterDiv.appendChild(minusDiv);
return gutterDiv;
}
public removeDiffs(editor: ICodeEditor): void {
const decorationIds = this._diffDecorations.get(editor) || [];
@ -193,8 +191,119 @@ registerSingleton(IInlineDiffService, InlineDiffService, InstantiationType.Eager
class StreamManager extends Disposable {
// private readonly _disposables = new DisposableStore();
_streamingState: { type: 'streaming'; editGroup: UndoRedoGroup } | { type: 'idle' } = { type: 'idle' }
constructor(
context: IExtHostContext,
@IInlineDiffService private readonly _inlineDiff: IInlineDiffService,
@ICodeEditorService private readonly _editorService: ICodeEditorService,
// @IHistoryService private readonly _historyService: IHistoryService, // history service is the history of pressing alt left/right
@IUndoRedoService private readonly _undoRedoService: IUndoRedoService, // undoRedo service is the history of pressing ctrl+z
@IBulkEditService private readonly _bulkEditService: IBulkEditService,
) {
super();
}
startStreaming(editorId: string) {
const editor = this._getEditor(editorId)
if (!editor) return
const model = editor.getModel()
if (!model) return
// all changes made when streaming should be a part of the group so we can undo them all together
this._streamingState = {
type: 'streaming',
editGroup: new UndoRedoGroup()
}
// TODO probably need to convert this to a stack
const diffsSnapshotBefore = { placeholder: '' }
const diffsSnapshotAfter = { placeholder: '' }
const elt: IUndoRedoElement = {
type: UndoRedoElementType.Resource,
resource: model.uri,
label: 'Add Diffs',
code: 'undoredo.inlineDiff',
undo: () => {
// reapply diffareas and diffs here
console.log('reverting diffareas...', diffsSnapshotBefore.placeholder)
},
redo: () => {
// reapply diffareas and diffs here
// when done, need to record diffSnapshotAfter
console.log('re-applying diffareas...', diffsSnapshotAfter.placeholder)
}
}
this._undoRedoService.pushElement(elt, this._streamingState.editGroup)
// ---------- START ----------
editor.updateOptions({ readOnly: true })
// ---------- WHEN DONE ----------
editor.updateOptions({ readOnly: false })
}
streamChange(editorId: string, edit: WorkspaceEdit) {
const editor = this._getEditor(editorId)
if (!editor) return
if (this._streamingState.type !== 'streaming') {
console.error('Expected streamChange to be in state \'streaming\'.')
return
}
// count all changes towards the group
this._bulkEditService.apply(edit, { undoRedoGroupId: this._streamingState.editGroup.id, })
}
_getEditor = (editorId: string): ICodeEditor | undefined => {
let editor: ICodeEditor | undefined;
editorId = editorId.substr(0, editorId.indexOf(',')); //todo@jrieken HACK
for (const candidate of this._editorService.listCodeEditors()) {
if (candidate.getId() === editorId
// && candidate.hasModel() && isEqual(candidate.getModel().uri, URI.revive(uri))
) {
editor = candidate;
break;
}
}
return editor
}
$addDiff(editorId: string, originalText: string, range: IRange): void {
const editor = this._getEditor(editorId);
if (!editor) return
this._inlineDiff.addDiff(editor, originalText, range)
}
}
@ -220,120 +329,3 @@ registerSingleton(IInlineDiffService, InlineDiffService, InstantiationType.Eager
// import { IBulkEditService } from '../../../editor/browser/services/bulkEditService.js';
// import { WorkspaceEdit } from '../../../editor/common/languages.js';
// // import { IHistoryService } from '../../services/history/common/history.js';
// @extHostNamedCustomer(MainContext.MainThreadInlineDiff)
// export class MainThreadInlineDiff extends Disposable implements MainThreadInlineDiffShape {
// // private readonly _proxy: ExtHostEditorInsetsShape;
// // private readonly _disposables = new DisposableStore();
// constructor(
// context: IExtHostContext,
// @IInlineDiffService private readonly _inlineDiff: IInlineDiffService,
// @ICodeEditorService private readonly _editorService: ICodeEditorService,
// // @IHistoryService private readonly _historyService: IHistoryService, // history service is the history of pressing alt left/right
// @IUndoRedoService private readonly _undoRedoService: IUndoRedoService, // undoRedo service is the history of pressing ctrl+z
// @IBulkEditService private readonly _bulkEditService: IBulkEditService,
// ) {
// super();
// // this._proxy = context.getProxy(ExtHostContext.ExtHostEditorInsets);
// // this._wcHistoryService.addEntry()
// }
// _streamingState: { type: 'streaming'; editGroup: UndoRedoGroup } | { type: 'idle' } = { type: 'idle' }
// startStreaming(editorId: string) {
// const editor = this._getEditor(editorId)
// if (!editor) return
// const model = editor.getModel()
// if (!model) return
// // all changes made when streaming should be a part of the group so we can undo them all together
// this._streamingState = {
// type: 'streaming',
// editGroup: new UndoRedoGroup()
// }
// // TODO probably need to convert this to a stack
// const diffsSnapshotBefore = { placeholder: '' }
// const diffsSnapshotAfter = { placeholder: '' }
// const elt: IUndoRedoElement = {
// type: UndoRedoElementType.Resource,
// resource: model.uri,
// label: 'Add Diffs',
// code: 'undoredo.inlineDiff',
// undo: () => {
// // reapply diffareas and diffs here
// console.log('reverting diffareas...', diffsSnapshotBefore.placeholder)
// },
// redo: () => {
// // reapply diffareas and diffs here
// // when done, need to record diffSnapshotAfter
// console.log('re-applying diffareas...', diffsSnapshotAfter.placeholder)
// }
// }
// this._undoRedoService.pushElement(elt, this._streamingState.editGroup)
// // ---------- START ----------
// editor.updateOptions({ readOnly: true })
// // ---------- WHEN DONE ----------
// editor.updateOptions({ readOnly: false })
// }
// streamChange(editorId: string, edit: WorkspaceEdit) {
// const editor = this._getEditor(editorId)
// if (!editor) return
// if (this._streamingState.type !== 'streaming') {
// console.error('Expected streamChange to be in state \'streaming\'.')
// return
// }
// // count all changes towards the group
// this._bulkEditService.apply(edit, { undoRedoGroupId: this._streamingState.editGroup.id, })
// }
// _getEditor = (editorId: string): ICodeEditor | undefined => {
// let editor: ICodeEditor | undefined;
// editorId = editorId.substr(0, editorId.indexOf(',')); //todo@jrieken HACK
// for (const candidate of this._editorService.listCodeEditors()) {
// if (candidate.getId() === editorId
// // && candidate.hasModel() && isEqual(candidate.getModel().uri, URI.revive(uri))
// ) {
// editor = candidate;
// break;
// }
// }
// return editor
// }
// $addDiff(editorId: string, originalText: string, range: IRange): void {
// const editor = this._getEditor(editorId);
// if (!editor) return
// this._inlineDiff.addDiff(editor, originalText, range)
// }
// }