mirror of
https://github.com/voideditor/void
synced 2026-05-24 09:58:23 +00:00
quick edit stream state?
This commit is contained in:
parent
86dfc5521d
commit
9005de65a6
6 changed files with 136 additions and 105 deletions
|
|
@ -35,7 +35,7 @@ import { filenameToVscodeLanguage } from './helpers/detectLanguage.js';
|
|||
import { INotificationService, Severity } from '../../../../platform/notification/common/notification.js';
|
||||
import { isMacintosh } from '../../../../base/common/platform.js';
|
||||
import { EditorOption } from '../../../../editor/common/config/editorOptions.js';
|
||||
import { Emitter } from '../../../../base/common/event.js';
|
||||
import { Emitter, Event } from '../../../../base/common/event.js';
|
||||
import { VOID_OPEN_SETTINGS_ACTION_ID } from './voidSettingsPane.js';
|
||||
import { ICommandService } from '../../../../platform/commands/common/commands.js';
|
||||
import { ILLMMessageService } from '../common/llmMessageService.js';
|
||||
|
|
@ -66,7 +66,6 @@ registerColor('void.sweepIdxBG', configOfBG(sweepIdxBG), '', true);
|
|||
|
||||
|
||||
|
||||
|
||||
const getLeadingWhitespacePx = (editor: ICodeEditor, startLine: number): number => {
|
||||
|
||||
const model = editor.getModel();
|
||||
|
|
@ -122,6 +121,7 @@ const findTextInCode = (text: string, fileContents: string, startingAtLine?: num
|
|||
}
|
||||
|
||||
|
||||
type AcceptRejectAllState = 'idle' | 'acceptRejectAll' | 'streaming'
|
||||
|
||||
|
||||
export type StartApplyingOpts = {
|
||||
|
|
@ -142,7 +142,7 @@ export type AddCtrlKOpts = {
|
|||
}
|
||||
|
||||
// // TODO diffArea should be removed if we just discovered it has no more diffs in it
|
||||
// for (const diffareaid of this.diffAreasOfURI[uri.fsPath]) {
|
||||
// for (const diffareaid of this.diffAreasOfURI[uri.fsPath] || []) {
|
||||
// const diffArea = this.diffAreaOfId[diffareaid]
|
||||
// if (Object.keys(diffArea._diffOfId).length === 0 && !diffArea._sweepState.isStreaming) {
|
||||
// const { onFinishEdit } = this._addToHistory(uri)
|
||||
|
|
@ -197,10 +197,12 @@ type DiffZone = {
|
|||
isStreaming: true;
|
||||
streamRequestIdRef: { current: string | null };
|
||||
line: number;
|
||||
applyBoxId?: string;
|
||||
} | {
|
||||
isStreaming: false;
|
||||
streamRequestIdRef?: undefined;
|
||||
line?: undefined;
|
||||
applyBoxId?: undefined;
|
||||
};
|
||||
editorId?: undefined;
|
||||
linkedStreamingDiffZone?: undefined;
|
||||
|
|
@ -253,11 +255,15 @@ export interface IEditCodeService {
|
|||
addCtrlKZone(opts: AddCtrlKOpts): number | undefined;
|
||||
removeCtrlKZone(opts: { diffareaid: number }): void;
|
||||
|
||||
isDiffZoneStreaming(opts: { diffareaid: number }): boolean;
|
||||
// CtrlKZone streaming state
|
||||
isCtrlKZoneStreaming(opts: { diffareaid: number }): boolean;
|
||||
|
||||
interruptDiffZoneStreaming(opts: { diffareaid: number }): void;
|
||||
interruptCtrlKStreaming(opts: { diffareaid: number }): void;
|
||||
onDidChangeCtrlKZoneStreaming: Event<{ uri: URI; diffareaid: number }>;
|
||||
|
||||
// // DiffZone streaming state
|
||||
// isApplyBoxIdStreaming(opts: { applyBoxId: string }): boolean;
|
||||
// interruptApplyBoxId(opts: { applyBoxId: string }): void;
|
||||
// onDidChangeApplyBoxIdStreaming: Event<{ applyBoxId: string }>;
|
||||
|
||||
// testDiffs(): void;
|
||||
}
|
||||
|
|
@ -277,10 +283,14 @@ class EditCodeService extends Disposable implements IEditCodeService {
|
|||
|
||||
// only applies to diffZones
|
||||
// streamingDiffZones: Set<number> = new Set()
|
||||
private readonly _onDidChangeStreaming = new Emitter<{ uri: URI }>();
|
||||
private readonly _onDidAddOrDeleteDiffZones = new Emitter<{ uri: URI }>();
|
||||
private readonly _onDidChangeDiffZoneStreaming = new Emitter<{ uri: URI; diffareaid: number }>();
|
||||
private readonly _onDidChangeCtrlKZoneStreaming = new Emitter<{ uri: URI; diffareaid: number }>();
|
||||
private readonly _onDidAddOrDeleteDiffZone = new Emitter<{ uri: URI }>();
|
||||
|
||||
private readonly _onDidChangeAcceptRejectAllState = new Emitter<{ uri: URI, state: AcceptRejectAllState }>(); // was going to be used, but decided not to
|
||||
|
||||
onDidChangeDiffZoneStreaming = this._onDidChangeDiffZoneStreaming.event
|
||||
onDidChangeCtrlKZoneStreaming = this._onDidChangeCtrlKZoneStreaming.event
|
||||
|
||||
constructor(
|
||||
// @IHistoryService private readonly _historyService: IHistoryService, // history service is the history of pressing alt left/right
|
||||
|
|
@ -315,23 +325,33 @@ class EditCodeService extends Disposable implements IEditCodeService {
|
|||
})
|
||||
)
|
||||
|
||||
// when a stream starts or ends
|
||||
// add the accept|reject UI here
|
||||
let removeAcceptRejectAllUI: (() => void) | null = null
|
||||
this._register(this._onDidChangeAcceptRejectAllState.event(({ uri, state }) => {
|
||||
if (state === 'acceptRejectAll' && !removeAcceptRejectAllUI) {
|
||||
removeAcceptRejectAllUI = this._addAcceptRejectAllUI(uri) ?? null
|
||||
} else {
|
||||
removeAcceptRejectAllUI?.()
|
||||
removeAcceptRejectAllUI = null
|
||||
}
|
||||
}))
|
||||
|
||||
// when a stream starts or ends
|
||||
const changeUriState = () => {
|
||||
const uri = model.uri
|
||||
const diffZones = [...this.diffAreasOfURI[uri.fsPath].values()]
|
||||
.map(diffareaid => this.diffAreaOfId[diffareaid])
|
||||
.filter(diffArea => !!diffArea && diffArea.type === 'DiffZone')
|
||||
const isStreaming = diffZones.find(diffZone => !!diffZone._streamState.isStreaming)
|
||||
if (diffZones.length !== 0 && !isStreaming && !removeAcceptRejectAllUI) {
|
||||
removeAcceptRejectAllUI = this._addAcceptRejectAllUI(uri) ?? null
|
||||
} else {
|
||||
removeAcceptRejectAllUI?.()
|
||||
removeAcceptRejectAllUI = null
|
||||
}
|
||||
|
||||
const state: AcceptRejectAllState = isStreaming ? 'streaming' : (diffZones.length === 0 ? 'idle' : 'acceptRejectAll')
|
||||
this._onDidChangeAcceptRejectAllState.fire({ uri, state })
|
||||
}
|
||||
this._register(this._onDidAddOrDeleteDiffZones.event(({ uri: uri_ }) => { if (uri_.fsPath === model.uri.fsPath) changeUriState() }))
|
||||
this._register(this._onDidChangeStreaming.event(({ uri: uri_ }) => { if (uri_.fsPath === model.uri.fsPath) changeUriState() }))
|
||||
this._register(this._onDidChangeDiffZoneStreaming.event(({ uri: uri_ }) => { if (uri_.fsPath === model.uri.fsPath) changeUriState() }))
|
||||
this._register(this._onDidAddOrDeleteDiffZone.event(({ uri: uri_ }) => { if (uri_.fsPath === model.uri.fsPath) changeUriState() }))
|
||||
|
||||
|
||||
|
||||
}
|
||||
// initialize all existing models + initialize when a new model mounts
|
||||
for (let model of this._modelService.getModels()) { initializeModel(model) }
|
||||
|
|
@ -412,7 +432,7 @@ class EditCodeService extends Disposable implements IEditCodeService {
|
|||
private _addDiffAreaStylesToURI = (uri: URI) => {
|
||||
const model = this._getModel(uri)
|
||||
|
||||
for (const diffareaid of this.diffAreasOfURI[uri.fsPath]) {
|
||||
for (const diffareaid of this.diffAreasOfURI[uri.fsPath] || []) {
|
||||
const diffArea = this.diffAreaOfId[diffareaid]
|
||||
|
||||
if (diffArea.type === 'DiffZone') {
|
||||
|
|
@ -441,7 +461,7 @@ class EditCodeService extends Disposable implements IEditCodeService {
|
|||
private _computeDiffsAndAddStylesToURI = (uri: URI) => {
|
||||
const fullFileText = this._readURI(uri) ?? ''
|
||||
|
||||
for (const diffareaid of this.diffAreasOfURI[uri.fsPath]) {
|
||||
for (const diffareaid of this.diffAreasOfURI[uri.fsPath] || []) {
|
||||
const diffArea = this.diffAreaOfId[diffareaid]
|
||||
if (diffArea.type !== 'DiffZone') continue
|
||||
|
||||
|
|
@ -465,7 +485,7 @@ class EditCodeService extends Disposable implements IEditCodeService {
|
|||
|
||||
// find all diffzones that aren't streaming
|
||||
const diffZones: DiffZone[] = []
|
||||
for (let diffareaid of this.diffAreasOfURI[uri.fsPath]) {
|
||||
for (let diffareaid of this.diffAreasOfURI[uri.fsPath] || []) {
|
||||
const diffArea = this.diffAreaOfId[diffareaid]
|
||||
if (diffArea.type !== 'DiffZone') continue
|
||||
if (diffArea._streamState.isStreaming) continue
|
||||
|
|
@ -583,7 +603,7 @@ class EditCodeService extends Disposable implements IEditCodeService {
|
|||
|
||||
|
||||
private _refreshCtrlKInputs = async (uri: URI) => {
|
||||
for (const diffareaid of this.diffAreasOfURI[uri.fsPath]) {
|
||||
for (const diffareaid of this.diffAreasOfURI[uri.fsPath] || []) {
|
||||
const diffArea = this.diffAreaOfId[diffareaid]
|
||||
if (diffArea.type !== 'CtrlKZone') continue
|
||||
if (!diffArea._mountInfo) {
|
||||
|
|
@ -852,7 +872,7 @@ class EditCodeService extends Disposable implements IEditCodeService {
|
|||
}
|
||||
this.diffAreasOfURI[uri.fsPath].add(diffareaid)
|
||||
}
|
||||
this._onDidAddOrDeleteDiffZones.fire({ uri })
|
||||
this._onDidAddOrDeleteDiffZone.fire({ uri })
|
||||
|
||||
// restore file content
|
||||
const numLines = this._getNumLines(uri)
|
||||
|
|
@ -910,7 +930,7 @@ class EditCodeService extends Disposable implements IEditCodeService {
|
|||
|
||||
// clears all Diffs (and their styles) and all styles of DiffAreas, etc
|
||||
private _clearAllEffects(uri: URI) {
|
||||
for (let diffareaid of this.diffAreasOfURI[uri.fsPath]) {
|
||||
for (let diffareaid of this.diffAreasOfURI[uri.fsPath] || []) {
|
||||
const diffArea = this.diffAreaOfId[diffareaid]
|
||||
this._clearAllDiffAreaEffects(diffArea)
|
||||
}
|
||||
|
|
@ -922,7 +942,7 @@ class EditCodeService extends Disposable implements IEditCodeService {
|
|||
this._clearAllDiffAreaEffects(diffZone)
|
||||
delete this.diffAreaOfId[diffZone.diffareaid]
|
||||
this.diffAreasOfURI[diffZone._URI.fsPath].delete(diffZone.diffareaid.toString())
|
||||
this._onDidAddOrDeleteDiffZones.fire({ uri: diffZone._URI })
|
||||
this._onDidAddOrDeleteDiffZone.fire({ uri: diffZone._URI })
|
||||
}
|
||||
|
||||
private _deleteTrackingZone(trackingZone: TrackingZone<unknown>) {
|
||||
|
|
@ -1221,7 +1241,7 @@ class EditCodeService extends Disposable implements IEditCodeService {
|
|||
|
||||
private _findOverlappingDiffArea({ startLine, endLine, uri, filter }: { startLine: number, endLine: number, uri: URI, filter?: (diffArea: DiffArea) => boolean }): DiffArea | null {
|
||||
// check if there's overlap with any other diffAreas and return early if there is
|
||||
for (const diffareaid of this.diffAreasOfURI[uri.fsPath]) {
|
||||
for (const diffareaid of this.diffAreasOfURI[uri.fsPath] || []) {
|
||||
const diffArea = this.diffAreaOfId[diffareaid]
|
||||
if (!diffArea) continue
|
||||
if (!filter?.(diffArea)) continue
|
||||
|
|
@ -1305,8 +1325,8 @@ class EditCodeService extends Disposable implements IEditCodeService {
|
|||
_removeStylesFns: new Set(),
|
||||
}
|
||||
const diffZone = this._addDiffArea(adding)
|
||||
this._onDidChangeStreaming.fire({ uri })
|
||||
this._onDidAddOrDeleteDiffZones.fire({ uri })
|
||||
this._onDidChangeDiffZoneStreaming.fire({ uri, diffareaid: diffZone.diffareaid })
|
||||
this._onDidAddOrDeleteDiffZone.fire({ uri })
|
||||
|
||||
if (from === 'QuickEdit') {
|
||||
const { diffareaid } = opts
|
||||
|
|
@ -1314,6 +1334,7 @@ class EditCodeService extends Disposable implements IEditCodeService {
|
|||
if (ctrlKZone.type !== 'CtrlKZone') return
|
||||
|
||||
ctrlKZone._linkedStreamingDiffZone = diffZone.diffareaid
|
||||
this._onDidChangeCtrlKZoneStreaming.fire({ uri, diffareaid: ctrlKZone.diffareaid })
|
||||
}
|
||||
|
||||
// now handle messages
|
||||
|
|
@ -1347,12 +1368,13 @@ class EditCodeService extends Disposable implements IEditCodeService {
|
|||
|
||||
const onDone = () => {
|
||||
diffZone._streamState = { isStreaming: false, }
|
||||
this._onDidChangeStreaming.fire({ uri })
|
||||
this._onDidChangeDiffZoneStreaming.fire({ uri, diffareaid: diffZone.diffareaid })
|
||||
|
||||
if (from === 'QuickEdit') {
|
||||
const ctrlKZone = this.diffAreaOfId[opts.diffareaid] as CtrlKZone
|
||||
|
||||
ctrlKZone._linkedStreamingDiffZone = null
|
||||
this._onDidChangeCtrlKZoneStreaming.fire({ uri, diffareaid: ctrlKZone.diffareaid })
|
||||
this._deleteCtrlKZone(ctrlKZone)
|
||||
}
|
||||
this._refreshStylesAndDiffsInURI(uri)
|
||||
|
|
@ -1476,8 +1498,8 @@ class EditCodeService extends Disposable implements IEditCodeService {
|
|||
_removeStylesFns: new Set(),
|
||||
}
|
||||
const diffZone = this._addDiffArea(adding)
|
||||
this._onDidChangeStreaming.fire({ uri })
|
||||
this._onDidAddOrDeleteDiffZones.fire({ uri })
|
||||
this._onDidChangeDiffZoneStreaming.fire({ uri, diffareaid: diffZone.diffareaid })
|
||||
this._onDidAddOrDeleteDiffZone.fire({ uri })
|
||||
|
||||
|
||||
const revertAndContinueHistory = () => {
|
||||
|
|
@ -1516,7 +1538,7 @@ class EditCodeService extends Disposable implements IEditCodeService {
|
|||
|
||||
const onDone = () => {
|
||||
diffZone._streamState = { isStreaming: false, }
|
||||
this._onDidChangeStreaming.fire({ uri })
|
||||
this._onDidChangeDiffZoneStreaming.fire({ uri, diffareaid: diffZone.diffareaid })
|
||||
this._refreshStylesAndDiffsInURI(uri)
|
||||
|
||||
// delete the tracking zones
|
||||
|
|
@ -1704,7 +1726,7 @@ class EditCodeService extends Disposable implements IEditCodeService {
|
|||
this._llmMessageService.abort(streamRequestId)
|
||||
|
||||
diffZone._streamState = { isStreaming: false, }
|
||||
this._onDidChangeStreaming.fire({ uri })
|
||||
this._onDidChangeDiffZoneStreaming.fire({ uri, diffareaid: diffZone.diffareaid })
|
||||
}
|
||||
|
||||
_undoHistory(uri: URI) {
|
||||
|
|
@ -1715,6 +1737,12 @@ class EditCodeService extends Disposable implements IEditCodeService {
|
|||
|
||||
|
||||
|
||||
isDiffZoneStreaming({ diffareaid }: { diffareaid: number }) {
|
||||
const diffZone = this.diffAreaOfId[diffareaid]
|
||||
if (diffZone?.type !== 'DiffZone') return false
|
||||
return diffZone._streamState.isStreaming
|
||||
}
|
||||
|
||||
isCtrlKZoneStreaming({ diffareaid }: { diffareaid: number }) {
|
||||
const ctrlKZone = this.diffAreaOfId[diffareaid]
|
||||
if (!ctrlKZone) return false
|
||||
|
|
@ -1722,14 +1750,7 @@ class EditCodeService extends Disposable implements IEditCodeService {
|
|||
return !!ctrlKZone._linkedStreamingDiffZone
|
||||
}
|
||||
|
||||
isDiffZoneStreaming({ diffareaid }: { diffareaid: number }) {
|
||||
const diffZone = this.diffAreaOfId[diffareaid]
|
||||
if (diffZone?.type !== 'DiffZone') return false
|
||||
return diffZone._streamState.isStreaming
|
||||
}
|
||||
|
||||
|
||||
// call this outside undo/redo (it calls undo). this is only for aborting a diffzone stream
|
||||
interruptDiffZoneStreaming({ diffareaid }: { diffareaid: number }) {
|
||||
const diffZone = this.diffAreaOfId[diffareaid]
|
||||
if (diffZone?.type !== 'DiffZone') return
|
||||
|
|
@ -1739,6 +1760,7 @@ class EditCodeService extends Disposable implements IEditCodeService {
|
|||
this._undoHistory(diffZone._URI)
|
||||
}
|
||||
|
||||
// diffareaid of the ctrlKZone (even though the stream state is dictated by the linked diffZone)
|
||||
interruptCtrlKStreaming({ diffareaid }: { diffareaid: number }) {
|
||||
const ctrlKZone = this.diffAreaOfId[diffareaid]
|
||||
if (ctrlKZone?.type !== 'CtrlKZone') return
|
||||
|
|
@ -1749,14 +1771,11 @@ class EditCodeService extends Disposable implements IEditCodeService {
|
|||
if (linkedStreamingDiffZone.type !== 'DiffZone') return
|
||||
|
||||
this.interruptDiffZoneStreaming({ diffareaid: linkedStreamingDiffZone.diffareaid })
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
// public removeDiffZone(diffZone: DiffZone, behavior: 'reject' | 'accept') {
|
||||
// const uri = diffZone._URI
|
||||
// const { onFinishEdit } = this._addToHistory(uri)
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
import { useState, useEffect, useCallback } from 'react'
|
||||
import { useAccessor, useIsURIStreaming } from '../util/services.js'
|
||||
import { useAccessor, useIsDiffZoneStreaming } from '../util/services.js'
|
||||
import { useRefState } from '../util/helpers.js'
|
||||
import { isFeatureNameDisabled } from '../../../../common/voidSettingsTypes.js'
|
||||
|
||||
|
|
@ -52,43 +52,33 @@ const ApplyButton = ({ codeStr, codeBoxId }: { codeStr: string, codeBoxId: strin
|
|||
const metricsService = accessor.get('IMetricsService')
|
||||
|
||||
|
||||
const [currStreamingDiffZoneRef, setCurrentlyStreamingDiffZone] = useRefState<number | null>(initStreamingDiffZoneId)
|
||||
const isStreaming = currStreamingDiffZoneRef.current !== null
|
||||
const isDisabled = !!isFeatureNameDisabled('Ctrl+K', settingsState)
|
||||
|
||||
useIsDiffZoneStreaming(isDiffAreaStreaming)
|
||||
|
||||
|
||||
const onSubmit = useCallback(() => {
|
||||
|
||||
const diffareaid = editCodeService.startApplying({
|
||||
from: 'ClickApply',
|
||||
type: 'searchReplace',
|
||||
applyStr: codeStr,
|
||||
})
|
||||
|
||||
metricsService.capture('Apply Code', { length: codeStr.length }) // capture the length only
|
||||
// const isStreaming = useIsDiffZoneStreaming(isDiffAreaStreaming)
|
||||
|
||||
|
||||
|
||||
if (isDisabled) return
|
||||
if (currStreamingDiffZoneRef.current !== null) return
|
||||
textAreaFnsRef.current?.disable()
|
||||
// const onSubmit = useCallback(() => {
|
||||
|
||||
const id = editCodeService.startApplying({
|
||||
from: 'QuickEdit',
|
||||
type: 'rewrite',
|
||||
diffareaid: diffareaid,
|
||||
})
|
||||
setCurrentlyStreamingDiffZone(id ?? null)
|
||||
}, [currStreamingDiffZoneRef, setCurrentlyStreamingDiffZone, isDisabled, editCodeService, diffareaid])
|
||||
// const uri = editCodeService.startApplying({
|
||||
// from: 'ClickApply',
|
||||
// type: 'searchReplace',
|
||||
// applyStr: codeStr,
|
||||
// })
|
||||
|
||||
const onInterrupt = useCallback(() => {
|
||||
if (currStreamingDiffZoneRef.current === null) return
|
||||
editCodeService.interruptStreaming(currStreamingDiffZoneRef.current)
|
||||
setCurrentlyStreamingDiffZone(null)
|
||||
textAreaFnsRef.current?.enable()
|
||||
}, [currStreamingDiffZoneRef, setCurrentlyStreamingDiffZone, editCodeService])
|
||||
// metricsService.capture('Apply Code', { length: codeStr.length }) // capture the length only
|
||||
|
||||
|
||||
|
||||
// if (isStreaming) return
|
||||
|
||||
// setCurrentlyStreamingDiffZone(id ?? null)
|
||||
// }, [isStreaming, editCodeService])
|
||||
|
||||
// const onInterrupt = useCallback(() => {
|
||||
// if (currStreamingDiffZoneRef.current === null) return
|
||||
// editCodeService.interruptStreaming(currStreamingDiffZoneRef.current)
|
||||
// setCurrentlyStreamingDiffZone(null)
|
||||
// textAreaFnsRef.current?.enable()
|
||||
// }, [isStreaming, editCodeService])
|
||||
|
||||
|
||||
|
||||
|
|
@ -101,7 +91,7 @@ const ApplyButton = ({ codeStr, codeBoxId }: { codeStr: string, codeBoxId: strin
|
|||
return <button
|
||||
// btn btn-secondary btn-sm border text-sm border-vscode-input-border rounded
|
||||
className={`${isSingleLine ? '' : 'px-1 py-0.5'} text-sm bg-void-bg-1 text-void-fg-1 hover:brightness-110 border border-vscode-input-border rounded`}
|
||||
onClick={onApply}
|
||||
// onClick={onApply}
|
||||
>
|
||||
Apply
|
||||
</button>
|
||||
|
|
|
|||
|
|
@ -9,6 +9,7 @@ import { BlockCode } from './BlockCode.js'
|
|||
import { ChatMessageLocation, } from '../../../aiRegexService.js'
|
||||
import { nameToVscodeLanguage } from '../../../helpers/detectLanguage.js'
|
||||
import { ApplyBlockHoverButtons } from './ApplyBlockHoverButtons.js'
|
||||
import { URI } from '../../../../../../../base/common/uri.js'
|
||||
|
||||
|
||||
type ApplyBoxLocation = ChatMessageLocation & { tokenIdx: string }
|
||||
|
|
@ -33,7 +34,7 @@ export const CodeSpan = ({ children, className }: { children: React.ReactNode, c
|
|||
</code>
|
||||
}
|
||||
|
||||
const RenderToken = ({ token, nested = false, noSpace = false, chatMessageLocation, tokenIdx }: { token: Token | string, nested?: boolean, noSpace?: boolean, chatMessageLocation?: ChatMessageLocation, tokenIdx: string }): JSX.Element => {
|
||||
const RenderToken = ({ token, nested, noSpace, chatMessageLocation, tokenIdx }: { token: Token | string, nested?: boolean, noSpace?: boolean, chatMessageLocation?: ChatMessageLocation, tokenIdx: string }): JSX.Element => {
|
||||
|
||||
|
||||
// deal with built-in tokens first (assume marked token)
|
||||
|
|
|
|||
|
|
@ -4,7 +4,7 @@
|
|||
*--------------------------------------------------------------------------------------*/
|
||||
|
||||
import React, { FormEvent, useCallback, useEffect, useRef, useState } from 'react';
|
||||
import { useSettingsState, useSidebarState, useChatThreadsState, useQuickEditState, useAccessor, useIsCtrlKZoneStreaming } from '../util/services.js';
|
||||
import { useSettingsState, useSidebarState, useChatThreadsState, useQuickEditState, useAccessor, useCtrlKZoneStreamingState } from '../util/services.js';
|
||||
import { TextAreaFns, VoidInputBox2 } from '../util/inputs.js';
|
||||
import { QuickEditPropsType } from '../../../quickEditActions.js';
|
||||
import { ButtonStop, ButtonSubmit, IconX, VoidChatArea } from '../sidebar-tsx/SidebarChat.js';
|
||||
|
|
@ -48,11 +48,17 @@ export const QuickEditChat = ({
|
|||
const [instructionsAreEmpty, setInstructionsAreEmpty] = useState(!(initText ?? '')) // the user's instructions
|
||||
const isDisabled = instructionsAreEmpty || !!isFeatureNameDisabled('Ctrl+K', settingsState)
|
||||
|
||||
const isStreamingRefState = useIsCtrlKZoneStreaming(diffareaid)
|
||||
|
||||
const [isStreamingRef, setIsStreamingRef] = useRefState(false)
|
||||
useCtrlKZoneStreamingState(useCallback((diffareaid2, isStreaming) => {
|
||||
if (diffareaid !== diffareaid2) return
|
||||
setIsStreamingRef(isStreaming)
|
||||
}, [diffareaid, setIsStreamingRef]))
|
||||
|
||||
|
||||
const onSubmit = useCallback(() => {
|
||||
if (isDisabled) return
|
||||
if (isStreamingRefState.current) return
|
||||
if (isStreamingRef.current) return
|
||||
textAreaFnsRef.current?.disable()
|
||||
|
||||
editCodeService.startApplying({
|
||||
|
|
@ -60,13 +66,13 @@ export const QuickEditChat = ({
|
|||
type: 'rewrite',
|
||||
diffareaid,
|
||||
})
|
||||
}, [isStreamingRefState, isDisabled, editCodeService, diffareaid])
|
||||
}, [isStreamingRef, isDisabled, editCodeService, diffareaid])
|
||||
|
||||
const onInterrupt = useCallback(() => {
|
||||
if (!isStreamingRefState.current ) return
|
||||
if (!isStreamingRef.current) return
|
||||
editCodeService.interruptCtrlKStreaming({ diffareaid })
|
||||
textAreaFnsRef.current?.enable()
|
||||
}, [isStreamingRefState, editCodeService])
|
||||
}, [isStreamingRef, editCodeService])
|
||||
|
||||
|
||||
const onX = useCallback(() => {
|
||||
|
|
@ -85,7 +91,7 @@ export const QuickEditChat = ({
|
|||
onSubmit={onSubmit}
|
||||
onAbort={onInterrupt}
|
||||
onClose={onX}
|
||||
isStreaming={isStreamingRefState.current}
|
||||
isStreaming={isStreamingRef.current}
|
||||
isDisabled={isDisabled}
|
||||
featureName="Ctrl+K"
|
||||
className="py-2 w-full"
|
||||
|
|
|
|||
|
|
@ -552,9 +552,9 @@ const ChatBubble = ({ chatMessage, isLoading, messageIdx }: { chatMessage: ChatM
|
|||
|
||||
// global state
|
||||
let isBeingEdited = false
|
||||
let setIsBeingEdited = (v: boolean) => { }
|
||||
let stagingSelections: StagingSelectionItem[] = []
|
||||
let setStagingSelections = (s: StagingSelectionItem[]) => { }
|
||||
let setIsBeingEdited = (_: boolean) => { }
|
||||
let setStagingSelections = (_: StagingSelectionItem[]) => { }
|
||||
|
||||
if (messageIdx !== undefined) {
|
||||
const _state = chatThreadsService.getCurrentMessageState(messageIdx)
|
||||
|
|
|
|||
|
|
@ -14,10 +14,6 @@ import { VoidUriState } from '../../../voidUriStateService.js';
|
|||
import { VoidQuickEditState } from '../../../quickEditStateService.js'
|
||||
import { RefreshModelStateOfProvider } from '../../../../../../../workbench/contrib/void/common/refreshModelService.js'
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
import { ServicesAccessor } from '../../../../../../../editor/browser/editorExtensions.js';
|
||||
import { IModelService } from '../../../../../../../editor/common/services/model.js';
|
||||
import { IClipboardService } from '../../../../../../../platform/clipboard/common/clipboardService.js';
|
||||
|
|
@ -47,7 +43,6 @@ import { IEnvironmentService } from '../../../../../../../platform/environment/c
|
|||
import { IConfigurationService } from '../../../../../../../platform/configuration/common/configuration.js'
|
||||
import { IPathService } from '../../../../../../../workbench/services/path/common/pathService.js'
|
||||
import { IMetricsService } from '../../../../../../../workbench/contrib/void/common/metricsService.js'
|
||||
import { URI } from '../../../../../../../base/common/uri.js'
|
||||
|
||||
|
||||
|
||||
|
|
@ -80,6 +75,13 @@ const refreshModelProviderListeners: Set<(p: RefreshableProviderName, s: Refresh
|
|||
let colorThemeState: ColorScheme
|
||||
const colorThemeStateListeners: Set<(s: ColorScheme) => void> = new Set()
|
||||
|
||||
const ctrlKZoneStreamingStateListeners: Set<(diffareaid: number, s: boolean) => void> = new Set()
|
||||
|
||||
let diffZoneStreamingState: Record<string, boolean>
|
||||
const diffZoneStreamingStateListeners: Set<(diffareaid: number, state: boolean) => void> = new Set()
|
||||
|
||||
|
||||
|
||||
// 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
|
||||
|
|
@ -163,7 +165,7 @@ export const _registerServices = (accessor: ServicesAccessor) => {
|
|||
refreshModelService.onDidChangeState((providerName) => {
|
||||
refreshModelState = refreshModelService.state
|
||||
refreshModelStateListeners.forEach(l => l(refreshModelState))
|
||||
refreshModelProviderListeners.forEach(l => l(providerName, refreshModelState))
|
||||
refreshModelProviderListeners.forEach(l => l(providerName, refreshModelState)) // no state
|
||||
})
|
||||
)
|
||||
|
||||
|
|
@ -175,6 +177,15 @@ export const _registerServices = (accessor: ServicesAccessor) => {
|
|||
})
|
||||
)
|
||||
|
||||
// no state
|
||||
disposables.push(
|
||||
editCodeService.onDidChangeCtrlKZoneStreaming(({ diffareaid }) => {
|
||||
const isStreaming = editCodeService.isCtrlKZoneStreaming({ diffareaid })
|
||||
ctrlKZoneStreamingStateListeners.forEach(l => l(diffareaid, isStreaming))
|
||||
})
|
||||
)
|
||||
|
||||
|
||||
|
||||
return disposables
|
||||
}
|
||||
|
|
@ -341,6 +352,23 @@ export const useRefreshModelListener = (listener: (providerName: RefreshableProv
|
|||
}
|
||||
|
||||
|
||||
export const useCtrlKZoneStreamingState = (listener: (diffareaid: number, s: boolean) => void) => {
|
||||
useEffect(() => {
|
||||
ctrlKZoneStreamingStateListeners.add(listener)
|
||||
return () => { ctrlKZoneStreamingStateListeners.delete(listener) }
|
||||
}, [listener])
|
||||
}
|
||||
|
||||
|
||||
export const useIsDiffZoneStreaming = (diffareaid: number) => {
|
||||
return { current: true }
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
export const useIsDark = () => {
|
||||
const [s, ss] = useState(colorThemeState)
|
||||
useEffect(() => {
|
||||
|
|
@ -355,16 +383,3 @@ export const useIsDark = () => {
|
|||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
export const useIsCtrlKZoneStreaming = (diffareaid: number) => {
|
||||
|
||||
return { current: true }
|
||||
|
||||
}
|
||||
|
||||
|
||||
export const useIsDiffZoneStreaming = (uri: URI) => {
|
||||
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in a new issue