mirror of
https://github.com/voideditor/void
synced 2026-05-24 09:58:23 +00:00
command bar state + accept/reject all
This commit is contained in:
parent
159d52a716
commit
f3451d5077
6 changed files with 184 additions and 82 deletions
|
|
@ -1226,8 +1226,6 @@ class EditCodeService extends Disposable implements IEditCodeService {
|
|||
|
||||
// treat like full file, unless linkedCtrlKZone was provided in which case use its diff's range
|
||||
|
||||
|
||||
|
||||
const startLine = linkedCtrlKZone ? linkedCtrlKZone.startLine : 1
|
||||
const endLine = linkedCtrlKZone ? linkedCtrlKZone.endLine : model.getLineCount()
|
||||
const range = { startLineNumber: startLine, startColumn: 1, endLineNumber: endLine, endColumn: Number.MAX_SAFE_INTEGER }
|
||||
|
|
@ -1291,7 +1289,16 @@ class EditCodeService extends Disposable implements IEditCodeService {
|
|||
|
||||
|
||||
|
||||
|
||||
private _uriIsStreaming(uri: URI) {
|
||||
const diffAreas = this.diffAreasOfURI[uri.fsPath]
|
||||
if (!diffAreas) return false
|
||||
for (const diffareaid of diffAreas) {
|
||||
const diffArea = this.diffAreaOfId[diffareaid]
|
||||
if (diffArea?.type !== 'DiffZone') continue
|
||||
if (diffArea._streamState.isStreaming) return true
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
|
||||
private async _initializeWriteoverStream(opts: StartApplyingOpts): Promise<[DiffZone, Promise<void>] | undefined> {
|
||||
|
|
@ -1358,7 +1365,8 @@ class EditCodeService extends Disposable implements IEditCodeService {
|
|||
}
|
||||
else { throw new Error(`featureName ${from} is invalid`) }
|
||||
|
||||
|
||||
// if URI is already streaming, return (should never happen, caller is responsible for checking)
|
||||
if (this._uriIsStreaming(uri)) return
|
||||
|
||||
// start diffzone
|
||||
const res = this._startStreamingDiffZone({
|
||||
|
|
@ -1526,6 +1534,9 @@ class EditCodeService extends Disposable implements IEditCodeService {
|
|||
{ role: 'user', content: userMessageContent },
|
||||
]
|
||||
|
||||
// if URI is already streaming, return (should never happen, caller is responsible for checking)
|
||||
if (this._uriIsStreaming(uri)) return
|
||||
|
||||
// start diffzone
|
||||
const res = this._startStreamingDiffZone({
|
||||
uri,
|
||||
|
|
|
|||
|
|
@ -10,7 +10,7 @@
|
|||
import React, { ButtonHTMLAttributes, FormEvent, FormHTMLAttributes, Fragment, KeyboardEvent, useCallback, useEffect, useMemo, useRef, useState } from 'react';
|
||||
|
||||
|
||||
import { useAccessor, useSidebarState, useChatThreadsState, useChatThreadsStreamState, useSettingsState, useActiveURI } from '../util/services.js';
|
||||
import { useAccessor, useSidebarState, useChatThreadsState, useChatThreadsStreamState, useSettingsState, useActiveURI, useCommandBarState } from '../util/services.js';
|
||||
|
||||
import { ChatMarkdownRender, ChatMessageLocation, getApplyBoxId } from '../markdown/ChatMarkdownRender.js';
|
||||
import { URI } from '../../../../../../../base/common/uri.js';
|
||||
|
|
@ -762,6 +762,50 @@ const ToolHeaderWrapper = ({
|
|||
};
|
||||
|
||||
|
||||
|
||||
|
||||
const SimplifiedToolHeader = ({
|
||||
title,
|
||||
children,
|
||||
}: {
|
||||
title: string;
|
||||
children?: React.ReactNode;
|
||||
}) => {
|
||||
const [isOpen, setIsOpen] = useState(false);
|
||||
const isDropdown = children !== undefined;
|
||||
return (
|
||||
<div>
|
||||
<div className="w-full">
|
||||
{/* header */}
|
||||
<div
|
||||
className={`select-none flex items-center min-h-[24px] ${isDropdown ? 'cursor-pointer' : ''}`}
|
||||
onClick={() => {
|
||||
if (isDropdown) { setIsOpen(v => !v); }
|
||||
}}
|
||||
>
|
||||
{isDropdown && (
|
||||
<ChevronRight
|
||||
className={`text-void-fg-3 mr-0.5 h-4 w-4 flex-shrink-0 transition-transform duration-100 ease-[cubic-bezier(0.4,0,0.2,1)] ${isOpen ? 'rotate-90' : ''}`}
|
||||
/>
|
||||
)}
|
||||
<div className="flex items-center w-full overflow-hidden">
|
||||
<span className="text-void-fg-3">{title}</span>
|
||||
</div>
|
||||
</div>
|
||||
{/* children */}
|
||||
{<div
|
||||
className={`overflow-hidden transition-all duration-200 ease-in-out ${isOpen ? 'opacity-100' : 'max-h-0 opacity-0'} text-void-fg-4`}
|
||||
>
|
||||
{children}
|
||||
</div>}
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
const UserMessageComponent = ({ chatMessage, messageIdx, isCommitted }: { chatMessage: ChatMessage & { role: 'user' }, messageIdx: number, isCommitted: boolean, }) => {
|
||||
|
||||
const accessor = useAccessor()
|
||||
|
|
@ -1812,6 +1856,34 @@ const ChatBubble = ({ chatMessage, isCommitted, messageIdx, isLast, chatIsRunnin
|
|||
}
|
||||
|
||||
|
||||
|
||||
|
||||
const CommandBarInChat = () => {
|
||||
const { state: commandBarState, sortedURIs: sortedCommandBarURIs } = useCommandBarState()
|
||||
const [isExpanded, setIsExpanded] = useState(false)
|
||||
|
||||
const accessor = useAccessor()
|
||||
const commandService = accessor.get('ICommandService')
|
||||
|
||||
if (!sortedCommandBarURIs || sortedCommandBarURIs.length === 0) {
|
||||
return null
|
||||
}
|
||||
|
||||
return (
|
||||
<SimplifiedToolHeader title={'Changes'}>
|
||||
{sortedCommandBarURIs.map((uri, i) => (
|
||||
<ListableToolItem
|
||||
key={i}
|
||||
name={getBasename(uri.fsPath)}
|
||||
onClick={() => { commandService.executeCommand('vscode.open', uri, { preview: true }) }}
|
||||
/>
|
||||
))}
|
||||
</SimplifiedToolHeader>
|
||||
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
export const SidebarChat = () => {
|
||||
const textAreaRef = useRef<HTMLTextAreaElement | null>(null)
|
||||
const textAreaFnsRef = useRef<TextAreaFns | null>(null)
|
||||
|
|
|
|||
|
|
@ -45,13 +45,22 @@ const VoidCommandBar = ({ uri, editor }: VoidCommandBarProps) => {
|
|||
const { state: commandBarState, sortedURIs: sortedCommandBarURIs } = useCommandBarState()
|
||||
|
||||
|
||||
// latestUriIdx is used to remember place in leftRight
|
||||
const _latestValidUriIdxRef = useRef<number | null>(null)
|
||||
|
||||
// changes if the user clicks left/right or if the user goes on a uri with changes
|
||||
const [currUriIdx, setUriIdx] = useState<number | null>(null)
|
||||
// i is the current index of the URI in sortedCommandBarURIs
|
||||
const i_ = sortedCommandBarURIs.findIndex(e => e.fsPath === uri?.fsPath)
|
||||
const currFileIdx = i_ === -1 ? null : i_
|
||||
useEffect(() => {
|
||||
const i = sortedCommandBarURIs.findIndex(e => e.fsPath === uri?.fsPath)
|
||||
if (i !== -1) { setUriIdx(i) }
|
||||
}, [sortedCommandBarURIs, uri])
|
||||
if (currFileIdx !== null) _latestValidUriIdxRef.current = currFileIdx
|
||||
}, [currFileIdx])
|
||||
|
||||
const uriIdxInStepper = currFileIdx !== null ? currFileIdx // use currFileIdx if it exists, else use latestNotNullUriIdxRef
|
||||
: _latestValidUriIdxRef.current === null ? null
|
||||
: _latestValidUriIdxRef.current < sortedCommandBarURIs.length ? _latestValidUriIdxRef.current
|
||||
: null
|
||||
|
||||
|
||||
|
||||
const getNextDiffIdx = (step: 1 | -1) => {
|
||||
// check undefined
|
||||
|
|
@ -74,14 +83,12 @@ const VoidCommandBar = ({ uri, editor }: VoidCommandBarProps) => {
|
|||
const diffid = sortedDiffIds[idx]
|
||||
const diff = editCodeService.diffOfId[diffid]
|
||||
const range = { startLineNumber: diff.startLine, endLineNumber: diff.startLine, startColumn: 1, endColumn: 1 };
|
||||
editor.revealRange(range, ScrollType.Immediate)
|
||||
editor.revealRangeInCenter(range, ScrollType.Immediate)
|
||||
commandBarService.setDiffIdx(uri, idx)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
const getNextUriIdx = (step: 1 | -1) => {
|
||||
return stepIdx(currUriIdx, sortedCommandBarURIs.length, step)
|
||||
return stepIdx(uriIdxInStepper, sortedCommandBarURIs.length, step)
|
||||
}
|
||||
const goToURIIdx = async (idx: number | null) => {
|
||||
if (idx === null) return
|
||||
|
|
@ -101,13 +108,12 @@ const VoidCommandBar = ({ uri, editor }: VoidCommandBarProps) => {
|
|||
setTimeout(() => {
|
||||
// check undefined
|
||||
if (!uri) return
|
||||
const s = commandBarState[uri.fsPath]
|
||||
const s = commandBarService.stateOfURI[uri.fsPath]
|
||||
if (!s) return
|
||||
const { diffIdx } = s
|
||||
goToDiffIdx(diffIdx)
|
||||
}, 50)
|
||||
|
||||
}, [uri])
|
||||
}, [uri, commandBarService])
|
||||
|
||||
|
||||
const currDiffIdx = uri ? commandBarState[uri.fsPath]?.diffIdx ?? null : null
|
||||
|
|
@ -115,11 +121,6 @@ const VoidCommandBar = ({ uri, editor }: VoidCommandBarProps) => {
|
|||
const sortedDiffZoneIds = uri ? commandBarState[uri.fsPath]?.sortedDiffZoneIds ?? [] : []
|
||||
|
||||
|
||||
const nextDiffIdx = getNextDiffIdx(1)
|
||||
const prevDiffIdx = getNextDiffIdx(-1)
|
||||
const nextURIIdx = getNextUriIdx(1)
|
||||
const prevURIIdx = getNextUriIdx(-1)
|
||||
|
||||
const isAChangeInThisFile = sortedDiffIds.length !== 0
|
||||
const isADiffZoneInThisFile = sortedDiffZoneIds.length !== 0
|
||||
const isADiffZoneInAnyFile = sortedCommandBarURIs.length !== 0
|
||||
|
|
@ -127,14 +128,13 @@ const VoidCommandBar = ({ uri, editor }: VoidCommandBarProps) => {
|
|||
const streamState = uri ? commandBarService.getStreamState(uri) : null
|
||||
const showAcceptRejectAll = streamState === 'idle-has-changes'
|
||||
|
||||
|
||||
if (!isADiffZoneInAnyFile) { // no changes for the user to accept
|
||||
return null
|
||||
}
|
||||
|
||||
const nextDiffIdx = getNextDiffIdx(1)
|
||||
const prevDiffIdx = getNextDiffIdx(-1)
|
||||
const nextURIIdx = getNextUriIdx(1)
|
||||
const prevURIIdx = getNextUriIdx(-1)
|
||||
|
||||
const upDownDisabled = prevDiffIdx === null || nextDiffIdx === null
|
||||
const leftRightDisabled = prevURIIdx === null || currUriIdx === null
|
||||
const leftRightDisabled = prevURIIdx === null || nextURIIdx === null
|
||||
|
||||
const upButton = <button
|
||||
className={`
|
||||
|
|
@ -205,18 +205,6 @@ const VoidCommandBar = ({ uri, editor }: VoidCommandBarProps) => {
|
|||
>→</button>
|
||||
|
||||
|
||||
const filesDescription = (isADiffZoneInThisFile ?
|
||||
currUriIdx !== null && sortedCommandBarURIs.length !== 0 &&
|
||||
`File ${currUriIdx + 1} of ${sortedCommandBarURIs.length}`
|
||||
: `${sortedCommandBarURIs.length} file${sortedCommandBarURIs.length === 1 ? '' : 's'} changed`
|
||||
);
|
||||
|
||||
const changesDescription = (isADiffZoneInThisFile ?
|
||||
isAChangeInThisFile ?
|
||||
`Diff ${(currDiffIdx ?? 0) + 1} of ${sortedDiffIds.length}`
|
||||
: `No changes`
|
||||
: ''
|
||||
);
|
||||
|
||||
// accept/reject if current URI has changes
|
||||
const onAcceptAll = () => {
|
||||
|
|
@ -231,6 +219,8 @@ const VoidCommandBar = ({ uri, editor }: VoidCommandBarProps) => {
|
|||
}
|
||||
|
||||
|
||||
if (!isADiffZoneInAnyFile) return null
|
||||
|
||||
const acceptAllButton = <button
|
||||
className='pointer-events-auto text-nowrap'
|
||||
onClick={onAcceptAll}
|
||||
|
|
@ -264,6 +254,10 @@ const VoidCommandBar = ({ uri, editor }: VoidCommandBarProps) => {
|
|||
Reject File
|
||||
</button>
|
||||
|
||||
const acceptRejectAllButtons = <div className="flex items-center gap-1 text-sm">
|
||||
{acceptAllButton}
|
||||
{rejectAllButton}
|
||||
</div>
|
||||
|
||||
// const closeCommandBar = useCallback(() => {
|
||||
// commandService.executeCommand('void.hideCommandBar');
|
||||
|
|
@ -283,41 +277,43 @@ const VoidCommandBar = ({ uri, editor }: VoidCommandBarProps) => {
|
|||
// >x
|
||||
// </button>
|
||||
|
||||
const gridLayout = <div className="flex flex-col gap-1">
|
||||
{/* First row */}
|
||||
{filesDescription &&
|
||||
<div className={`flex items-center ${leftRightDisabled ? 'opacity-50' : ''}`}>
|
||||
{leftButton}
|
||||
<div className="w-px h-3 bg-void-border-3 mx-0.5 shadow-sm"></div> {/* Divider */}
|
||||
{rightButton}
|
||||
<div className="w-px h-3 bg-void-border-3 mx-0.5 shadow-sm"></div> {/* Divider */}
|
||||
<div className="text-xs mx-2">{filesDescription}</div>
|
||||
</div>
|
||||
}
|
||||
const leftRightUpDownButtons = <div className='p-1 gap-1 flex flex-col items-start bg-void-bg-2 rounded shadow-md border border-void-border-2'>
|
||||
<div className="flex flex-col gap-1">
|
||||
{/* Changes in file */}
|
||||
{isADiffZoneInThisFile &&
|
||||
<div className={`flex items-center ${upDownDisabled ? 'opacity-50' : ''}`}>
|
||||
{downButton}
|
||||
{upButton}
|
||||
<div className="text-xs mx-1 w-fit">
|
||||
{isAChangeInThisFile ?
|
||||
`Diff ${(currDiffIdx ?? 0) + 1} of ${sortedDiffIds.length}`
|
||||
: `No changes`
|
||||
}
|
||||
</div>
|
||||
</div>
|
||||
}
|
||||
|
||||
{/* Second row */}
|
||||
{changesDescription &&
|
||||
<div className={`flex items-center ${upDownDisabled ? 'opacity-50' : ''}`}>
|
||||
{upButton}
|
||||
<div className="w-px h-3 bg-void-border-3 mx-0.5 shadow-sm"></div> {/* Divider */}
|
||||
{downButton}
|
||||
<div className="w-px h-3 bg-void-border-3 mx-0.5 shadow-sm"></div> {/* Divider */}
|
||||
<div className="text-xs mx-2">{changesDescription}</div>
|
||||
</div>
|
||||
}
|
||||
{/* Files */}
|
||||
{isADiffZoneInAnyFile &&
|
||||
<div className={`flex items-center ${leftRightDisabled ? 'opacity-50' : ''}`}>
|
||||
{leftButton}
|
||||
{/* <div className="w-px h-3 bg-void-border-3 mx-0.5 shadow-sm"></div> */}
|
||||
{rightButton}
|
||||
{/* <div className="w-px h-3 bg-void-border-3 mx-0.5 shadow-sm"></div> */}
|
||||
<div className="text-xs mx-1 w-fit">
|
||||
{currFileIdx !== null ?
|
||||
`File ${currFileIdx + 1} of ${sortedCommandBarURIs.length}`
|
||||
: `${sortedCommandBarURIs.length} file${sortedCommandBarURIs.length === 1 ? '' : 's'} changed`
|
||||
}
|
||||
</div>
|
||||
</div>
|
||||
}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
return <div className='pointer-events-auto flex flex-col gap-2 mx-2'>
|
||||
{showAcceptRejectAll &&
|
||||
<div className="flex gap-1 text-sm">
|
||||
{acceptAllButton}
|
||||
{rejectAllButton}
|
||||
</div>
|
||||
}
|
||||
<div className='px-2 pt-1 pb-1 gap-1 flex flex-col items-start bg-void-bg-1 rounded shadow-md border border-void-border-1'>
|
||||
{gridLayout}
|
||||
{/* {oldLayout} */}
|
||||
</div>
|
||||
return <div className={`flex flex-col gap-y-2 mx-2 pointer-events-auto`}>
|
||||
{showAcceptRejectAll && acceptRejectAllButtons}
|
||||
{leftRightUpDownButtons}
|
||||
|
||||
</div>
|
||||
}
|
||||
|
|
|
|||
|
|
@ -12,6 +12,7 @@ import { ToolCallParams, ToolDirectoryItem, ToolName, ToolResultType } from '../
|
|||
import { IVoidModelService } from '../common/voidModelService.js'
|
||||
import { EndOfLinePreference } from '../../../../editor/common/model.js'
|
||||
import { basename } from '../../../../base/common/path.js'
|
||||
import { IVoidCommandBarService } from './voidCommandBarService.js'
|
||||
|
||||
|
||||
// tool use for AI
|
||||
|
|
@ -193,6 +194,7 @@ export class ToolsService implements IToolsService {
|
|||
@IVoidModelService voidModelService: IVoidModelService,
|
||||
@IEditCodeService editCodeService: IEditCodeService,
|
||||
@ITerminalToolService private readonly terminalToolService: ITerminalToolService,
|
||||
@IVoidCommandBarService private readonly commandBarService: IVoidCommandBarService,
|
||||
) {
|
||||
|
||||
const queryBuilder = instantiationService.createInstance(QueryBuilder);
|
||||
|
|
@ -348,6 +350,9 @@ export class ToolsService implements IToolsService {
|
|||
|
||||
edit: async ({ uri, changeDescription }) => {
|
||||
await voidModelService.initializeModel(uri)
|
||||
if (this.commandBarService.getStreamState(uri) === 'streaming') {
|
||||
throw new Error(`The Apply model was already running. This can happen if two agents try editing the same file at the same time. Please try again in a moment.`)
|
||||
}
|
||||
const res = await editCodeService.startApplying({
|
||||
uri,
|
||||
applyStr: changeDescription,
|
||||
|
|
|
|||
|
|
@ -31,7 +31,11 @@ export interface IVoidCommandBarService {
|
|||
onDidChangeActiveURI: Event<{ uri: URI | null }>;
|
||||
|
||||
getStreamState: (uri: URI) => 'streaming' | 'idle-has-changes' | 'idle-no-changes';
|
||||
setDiffIdx(uri: URI, newIdx: number | null): void
|
||||
setDiffIdx(uri: URI, newIdx: number | null): void;
|
||||
|
||||
acceptOrRejectAllFiles(opts: { behavior: 'reject' | 'accept' }): void;
|
||||
anyFileIsStreaming(): boolean;
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -64,7 +68,7 @@ export class VoidCommandBarService extends Disposable implements IVoidCommandBar
|
|||
// depends on uri -> diffZone -> {streaming, diffs}
|
||||
public stateOfURI: { [uri: string]: CommandBarStateType } = {}
|
||||
public sortedURIs: URI[] = [] // keys of state (depends on diffZones in the uri)
|
||||
private readonly _hooks = new Set<URI>() // uriFsPaths
|
||||
private readonly _listenToTheseURIs = new Set<URI>() // uriFsPaths
|
||||
|
||||
// Emits when a URI's stream state changes between idle, streaming, and acceptRejectAll
|
||||
private readonly _onDidChangeState = new Emitter<{ uri: URI }>();
|
||||
|
|
@ -76,7 +80,6 @@ export class VoidCommandBarService extends Disposable implements IVoidCommandBar
|
|||
private readonly _onDidChangeActiveURI = new Emitter<{ uri: URI | null }>();
|
||||
readonly onDidChangeActiveURI = this._onDidChangeActiveURI.event;
|
||||
|
||||
|
||||
constructor(
|
||||
@IInstantiationService private readonly _instantiationService: IInstantiationService,
|
||||
@ICodeEditorService private readonly _codeEditorService: ICodeEditorService,
|
||||
|
|
@ -91,7 +94,7 @@ export class VoidCommandBarService extends Disposable implements IVoidCommandBar
|
|||
// do not add listeners to the same model twice - important, or will see duplicates
|
||||
if (registeredModelURIs.has(model.uri.fsPath)) return
|
||||
registeredModelURIs.add(model.uri.fsPath)
|
||||
this._hooks.add(model.uri)
|
||||
this._listenToTheseURIs.add(model.uri)
|
||||
}
|
||||
// initialize all existing models + initialize when a new model mounts
|
||||
this._modelService.getModels().forEach(model => { initializeModel(model) })
|
||||
|
|
@ -117,7 +120,7 @@ export class VoidCommandBarService extends Disposable implements IVoidCommandBar
|
|||
// mount the command bar
|
||||
const d1 = this._instantiationService.createInstance(AcceptRejectAllFloatingWidget, { editor });
|
||||
disposablesOfEditorId[id].push(d1);
|
||||
const d2 = editor.onDidChangeModel((e) => { if (e?.newModelUrl?.scheme === 'file') updateActiveURI() })
|
||||
const d2 = editor.onWillChangeModel((e) => { if (e?.newModelUrl?.scheme === 'file') updateActiveURI() })
|
||||
disposablesOfEditorId[id].push(d2);
|
||||
}
|
||||
const onCodeEditorRemove = (editor: ICodeEditor) => {
|
||||
|
|
@ -133,7 +136,7 @@ export class VoidCommandBarService extends Disposable implements IVoidCommandBar
|
|||
|
||||
// state updaters
|
||||
this._register(this._editCodeService.onDidAddOrDeleteDiffZones(e => {
|
||||
for (const uri of this._hooks) {
|
||||
for (const uri of this._listenToTheseURIs) {
|
||||
if (e.uri.fsPath !== uri.fsPath) continue
|
||||
// --- sortedURIs: delete if empty, add if not in state yet
|
||||
const diffZones = this._getDiffZonesOnURI(uri)
|
||||
|
|
@ -173,7 +176,7 @@ export class VoidCommandBarService extends Disposable implements IVoidCommandBar
|
|||
|
||||
}))
|
||||
this._register(this._editCodeService.onDidChangeDiffsInDiffZone(e => {
|
||||
for (const uri of this._hooks) {
|
||||
for (const uri of this._listenToTheseURIs) {
|
||||
if (e.uri.fsPath !== uri.fsPath) continue
|
||||
// --- sortedURIs: no change
|
||||
// --- state:
|
||||
|
|
@ -191,7 +194,7 @@ export class VoidCommandBarService extends Disposable implements IVoidCommandBar
|
|||
}
|
||||
}))
|
||||
this._register(this._editCodeService.onDidChangeStreamingInDiffZone(e => {
|
||||
for (const uri of this._hooks) {
|
||||
for (const uri of this._listenToTheseURIs) {
|
||||
if (e.uri.fsPath !== uri.fsPath) continue
|
||||
// --- sortedURIs: no change
|
||||
// --- state:
|
||||
|
|
@ -342,6 +345,21 @@ export class VoidCommandBarService extends Disposable implements IVoidCommandBar
|
|||
}
|
||||
|
||||
|
||||
anyFileIsStreaming() {
|
||||
return this.sortedURIs.some(uri => this.getStreamState(uri) === 'streaming')
|
||||
}
|
||||
|
||||
acceptOrRejectAllFiles(opts: { behavior: 'reject' | 'accept' }) {
|
||||
const { behavior } = opts
|
||||
// if anything is streaming, do nothing
|
||||
const anyIsStreaming = this.anyFileIsStreaming()
|
||||
if (anyIsStreaming) return
|
||||
for (const uri of this.sortedURIs) {
|
||||
this._editCodeService.acceptOrRejectAllDiffAreas({ uri, behavior, removeCtrlKs: false })
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
registerSingleton(IVoidCommandBarService, VoidCommandBarService, InstantiationType.Delayed); // delayed is needed here :(
|
||||
|
|
|
|||
|
|
@ -19,9 +19,9 @@ export const tripleTick = ['```', '```']
|
|||
const changesExampleContent = `\
|
||||
// ... existing code ...
|
||||
// {{change 1}}
|
||||
// // ... existing code ...
|
||||
// ... existing code ...
|
||||
// {{change 2}}
|
||||
// // ... existing code ...
|
||||
// ... existing code ...
|
||||
// {{change 3}}
|
||||
// ... existing code ...`
|
||||
|
||||
|
|
|
|||
Loading…
Reference in a new issue