diff --git a/src/vs/workbench/contrib/void/browser/editCodeService.ts b/src/vs/workbench/contrib/void/browser/editCodeService.ts index f8e47af9..242ba070 100644 --- a/src/vs/workbench/contrib/void/browser/editCodeService.ts +++ b/src/vs/workbench/contrib/void/browser/editCodeService.ts @@ -3,7 +3,7 @@ * Licensed under the Apache License, Version 2.0. See LICENSE.txt for more information. *--------------------------------------------------------------------------------------*/ -import { Disposable } from '../../../../base/common/lifecycle.js'; +import { Disposable, IDisposable } from '../../../../base/common/lifecycle.js'; import { registerSingleton, InstantiationType } from '../../../../platform/instantiation/common/extensions.js'; import { IInstantiationService } from '../../../../platform/instantiation/common/instantiation.js'; import { ICodeEditor, IOverlayWidget, IViewZone, OverlayWidgetPositionPreference } from '../../../../editor/browser/editorBrowser.js'; @@ -331,7 +331,7 @@ class EditCodeService extends Disposable implements IEditCodeService { } // initialize all existing models + initialize when a new model mounts for (let model of this._modelService.getModels()) { initializeModel(model) } - this._register(this._modelService.onModelAdded(model => { console.log('initialized model!!', model.uri.fsPath); initializeModel(model) })); + this._register(this._modelService.onModelAdded(model => { initializeModel(model) })); // this function adds listeners to refresh styles when editor changes tab @@ -517,8 +517,9 @@ class EditCodeService extends Disposable implements IEditCodeService { }) // mount react + let disposablesRef: IDisposable[] | undefined = undefined this._instantiationService.invokeFunction(accessor => { - mountCtrlK(domNode, accessor, { + disposablesRef = mountCtrlK(domNode, accessor, { diffareaid: ctrlKZone.diffareaid, @@ -547,10 +548,11 @@ class EditCodeService extends Disposable implements IEditCodeService { }) - return () => editor.changeViewZones(accessor => { - if (zoneId) - accessor.removeZone(zoneId) - }) + // cleanup + return () => { + editor.changeViewZones(accessor => { if (zoneId) accessor.removeZone(zoneId) }) + disposablesRef?.forEach(d => d.dispose()) + } }) return { @@ -746,9 +748,9 @@ class EditCodeService extends Disposable implements IEditCodeService { } return model } - // not obvious at all, but if we want the model we can just create it. our listeners in the constructor handle it - private async _forceModel(uri: URI) { + // not obvious at all, but if we want the model we can just create it. our listeners in the constructor handle it. call this the moment we know we have a uri that we want to make changes to + private async _ensureModelExists(uri: URI) { const m = this._getModel(uri) if (m !== null) return m @@ -770,10 +772,8 @@ class EditCodeService extends Disposable implements IEditCodeService { weAreWriting = false private async _writeURIText(uri: URI, text: string, range_: IRange | 'wholeFileRange', { shouldRealignDiffAreas, }: { shouldRealignDiffAreas: boolean, }) { - let m = this._getModel(uri) - if (m === null) { m = await this._forceModel(uri) } - if (m === null) return // if still null, return - const model: ITextModel = m + const model = this._getModel(uri) + if (model === null) return const range: IRange = range_ === 'wholeFileRange' ? { startLineNumber: 1, startColumn: 1, endLineNumber: model.getLineCount(), endColumn: Number.MAX_SAFE_INTEGER } // whole file @@ -890,7 +890,7 @@ class EditCodeService extends Disposable implements IEditCodeService { } this._undoRedoService.pushElement(elt) - const onFinishEdit = async () => { afterSnapshot = getCurrentSnapshot() } + const onFinishEdit = () => { afterSnapshot = getCurrentSnapshot() } return { onFinishEdit } } @@ -1160,9 +1160,13 @@ class EditCodeService extends Disposable implements IEditCodeService { // called first, then call startApplying public addCtrlKZone({ startLine, endLine, editor }: AddCtrlKOpts) { + // don't need to await this, because in order to add a ctrl+K zone must already have the model open on your screen + // await this._ensureModelExists(uri) + const uri = editor.getModel()?.uri if (!uri) return + // check if there's overlap with any other ctrlKZone and if so, focus it const overlappingCtrlKZone = this._findOverlappingDiffArea({ startLine, endLine, uri, filter: (diffArea) => diffArea.type === 'CtrlKZone' }) if (overlappingCtrlKZone) { @@ -1219,18 +1223,18 @@ class EditCodeService extends Disposable implements IEditCodeService { // the applyDonePromise this returns can throw an error (reject) public async startApplying(opts: StartApplyingOpts): Promise<[URI, Promise] | null> { let res: [DiffZone, Promise] | undefined = undefined - if (opts.type === 'rewrite') res = await this._initializeWriteoverStream(opts) - else if (opts.type === 'searchReplace') res = await this._initializeSearchAndReplaceStream(opts) + + if (Math.random() > 0) { + console.log('writeover....') + res = await this._initializeWriteoverStream(opts) + } else { + + if (opts.type === 'rewrite') res = await this._initializeWriteoverStream(opts) + else if (opts.type === 'searchReplace') res = await this._initializeSearchAndReplaceStream(opts) + } if (!res) return null const [diffZone, applyDonePromise] = res - applyDonePromise.then(() => { - const diffareaids = this.diffAreasOfURI[diffZone._URI.fsPath] - for (const diffareaid of diffareaids || []) { - const diffArea = this.diffAreaOfId[diffareaid] - console.log('DA!!', diffArea) - } - }) return [diffZone._URI, applyDonePromise] } @@ -1270,9 +1274,12 @@ class EditCodeService extends Disposable implements IEditCodeService { const uri_ = this._getActiveEditorURI() if (!uri_) return uri = uri_ + await this._ensureModelExists(uri) + const c_ = await this._voidFileService.readFile(uri) if (c_ === null) return currentFileStr = c_ + console.log('got curent file', c_.length) const numLines = numLinesOfStr(currentFileStr) @@ -1291,6 +1298,7 @@ class EditCodeService extends Disposable implements IEditCodeService { const { startLine: startLine_, endLine: endLine_, _URI } = ctrlKZone uri = _URI + await this._ensureModelExists(uri) const c_ = await this._voidFileService.readFile(uri) if (c_ === null) return @@ -1317,7 +1325,7 @@ class EditCodeService extends Disposable implements IEditCodeService { onUndo: () => { if (diffZone._streamState.isStreaming) rejApplyPromise(new Error('Edit was interrupted by pressing undo.')) } }) - // __TODO__ let users customize modelFimTags + // TODO!!! let users customize modelFimTags const quickEditFIMTags = defaultQuickEditFimTags const adding: Omit = { @@ -1377,6 +1385,7 @@ class EditCodeService extends Disposable implements IEditCodeService { const onDone = () => { + console.log('called onDone') diffZone._streamState = { isStreaming: false, } this._onDidChangeDiffZoneStreaming.fire({ uri, diffareaid: diffZone.diffareaid }) @@ -1463,6 +1472,7 @@ class EditCodeService extends Disposable implements IEditCodeService { }) await messageDonePromise + console.log('done waiting') } writeover().then(() => resApplyPromise()).catch((e) => rejApplyPromise(e)) @@ -1485,6 +1495,8 @@ class EditCodeService extends Disposable implements IEditCodeService { else { uri = givenURI } + await this._ensureModelExists(uri) + // generate search/replace block text const originalFileCode = await this._voidFileService.readFile(uri) @@ -1544,8 +1556,6 @@ class EditCodeService extends Disposable implements IEditCodeService { this._onDidChangeDiffZoneStreaming.fire({ uri, diffareaid: diffZone.diffareaid }) this._onDidAddOrDeleteDiffZones.fire({ uri }) - console.log('b', uri) - const convertOriginalRangeToFinalRange = (originalRange: readonly [number, number]): [number, number] => { // adjust based on the changes by computing line offset @@ -1614,6 +1624,13 @@ class EditCodeService extends Disposable implements IEditCodeService { shouldSendAnotherMessage = false nMessagesSent += 1 + if (nMessagesSent >= 5) { + this._notifyError({ message: 'Void Error: Tried to Fast Apply 5 times but failed. Please try again with a smarter model or disable Fast Apply.', fullError: null }) + onDone() + this._undoHistory(uri) + break + } + let resMessageDonePromise: () => void = () => { } const messageDonePromise = new Promise((res, rej) => { resMessageDonePromise = res }) diff --git a/src/vs/workbench/contrib/void/browser/editCodeServiceInterface.ts b/src/vs/workbench/contrib/void/browser/editCodeServiceInterface.ts index 99e0c937..bdcdc05e 100644 --- a/src/vs/workbench/contrib/void/browser/editCodeServiceInterface.ts +++ b/src/vs/workbench/contrib/void/browser/editCodeServiceInterface.ts @@ -38,9 +38,10 @@ export const IEditCodeService = createDecorator('editCodeServi export interface IEditCodeService { readonly _serviceBrand: undefined; + // main entrypoints (initialize things for the functions below to be called): startApplying(opts: StartApplyingOpts): Promise<[URI, Promise] | null>; - addCtrlKZone(opts: AddCtrlKOpts): number | undefined; + removeCtrlKZone(opts: { diffareaid: number }): void; removeDiffAreas(opts: { uri: URI, removeCtrlKs: boolean, behavior: 'reject' | 'accept' }): void; diff --git a/src/vs/workbench/contrib/void/browser/react/src/quick-edit-tsx/QuickEditChat.tsx b/src/vs/workbench/contrib/void/browser/react/src/quick-edit-tsx/QuickEditChat.tsx index c7ecf1ba..9fb95451 100644 --- a/src/vs/workbench/contrib/void/browser/react/src/quick-edit-tsx/QuickEditChat.tsx +++ b/src/vs/workbench/contrib/void/browser/react/src/quick-edit-tsx/QuickEditChat.tsx @@ -8,7 +8,6 @@ import { useSettingsState, useSidebarState, useChatThreadsState, useQuickEditSta import { TextAreaFns, VoidInputBox2 } from '../util/inputs.js'; import { QuickEditPropsType } from '../../../quickEditActions.js'; import { ButtonStop, ButtonSubmit, IconX, VoidChatArea } from '../sidebar-tsx/SidebarChat.js'; -import { ModelDropdown } from '../void-settings-tsx/ModelDropdown.js'; import { VOID_CTRL_K_ACTION_ID } from '../../../actionIDs.js'; import { useRefState } from '../util/helpers.js'; import { useScrollbarStyles } from '../util/useScrollbarStyles.js'; diff --git a/src/vs/workbench/contrib/void/browser/react/src/sidebar-tsx/SidebarChat.tsx b/src/vs/workbench/contrib/void/browser/react/src/sidebar-tsx/SidebarChat.tsx index 57357e57..d65e15d6 100644 --- a/src/vs/workbench/contrib/void/browser/react/src/sidebar-tsx/SidebarChat.tsx +++ b/src/vs/workbench/contrib/void/browser/react/src/sidebar-tsx/SidebarChat.tsx @@ -236,7 +236,7 @@ const ReasoningOptionDropdown = () => { const value = voidSettingsState.optionsOfModelSelection[modelSelection.providerName]?.[modelSelection.modelName]?.reasoningBudget ?? defaultVal const nSteps = 8 // only used in calculating stepSize, stepSize is what actually matters - const stepSize = Math.round((max - min_) / 8) + const stepSize = Math.round((max - min_) / nSteps) const min = canToggleReasoning ? min_ - stepSize : min_ return
@@ -249,7 +249,6 @@ const ReasoningOptionDropdown = () => { step={stepSize} value={value} onChange={(newVal) => { - console.log('NEWVAL', newVal) const disabled = newVal === min && canToggleReasoning voidSettingsService.setOptionsOfModelSelection(modelSelection.providerName, modelSelection.modelName, { reasoningEnabled: !disabled, reasoningBudget: newVal }) }} diff --git a/src/vs/workbench/contrib/void/browser/react/src/util/mountFnGenerator.tsx b/src/vs/workbench/contrib/void/browser/react/src/util/mountFnGenerator.tsx index 9839201d..5eba467d 100644 --- a/src/vs/workbench/contrib/void/browser/react/src/util/mountFnGenerator.tsx +++ b/src/vs/workbench/contrib/void/browser/react/src/util/mountFnGenerator.tsx @@ -18,7 +18,6 @@ export const mountFnGenerator = (Component: (params: any) => React.ReactNode) => const disposables = _registerServices(accessor) - const root = ReactDOM.createRoot(rootElement) root.render(); // tailwind dark theme indicator diff --git a/src/vs/workbench/contrib/void/browser/react/src/util/services.tsx b/src/vs/workbench/contrib/void/browser/react/src/util/services.tsx index dd9c0756..4da31c05 100644 --- a/src/vs/workbench/contrib/void/browser/react/src/util/services.tsx +++ b/src/vs/workbench/contrib/void/browser/react/src/util/services.tsx @@ -85,18 +85,10 @@ const uriStreamingStateListeners: Set<(uri: URI, s: URIStreamState) => void> = n // must call this before you can use any of the hooks below // this should only be called ONCE! this is the only place you don't need to dispose onDidChange. If you use state.onDidChange anywhere else, make sure to dispose it! -let wasCalled = false export const _registerServices = (accessor: ServicesAccessor) => { const disposables: IDisposable[] = [] - // don't register services twice - if (wasCalled) { - return - // console.error(`⚠️ Void _registerServices was called again! It should only be called once.`) - } - wasCalled = true - _registerAccessor(accessor) const stateServices = {