From 842d38866994ba2e05efd76588c287df97ce2591 Mon Sep 17 00:00:00 2001 From: mp Date: Sat, 14 Dec 2024 20:39:46 -0800 Subject: [PATCH] multiple selections --- .../react/src/sidebar-tsx/SidebarChat.tsx | 168 ++++++++++-------- .../void/browser/react/tailwind.config.js | 13 +- .../contrib/void/browser/registerActions.ts | 17 +- .../contrib/void/browser/registerThreads.ts | 9 +- 4 files changed, 124 insertions(+), 83 deletions(-) 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 6ac2126c..f45c0e9c 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 @@ -22,6 +22,7 @@ import { OnError, ServiceSendLLMMessageParams } from '../../../../../../../platf import { getCmdKey } from '../../../getCmdKey.js' import { HistoryInputBox, InputBox } from '../../../../../../../base/browser/ui/inputbox/inputBox.js'; import { VoidInputBox } from './inputs.js'; +import { ModelSelectionOfFeature } from './ModelSelectionSettings.js'; const IconX = ({ size, className = '' }: { size: number, className?: string }) => { @@ -111,7 +112,7 @@ export const SelectedFiles = ( return ( !!selections && selections.length !== 0 && ( -
+
{selections.map((selection, i) => ( {/* selected file summary */} @@ -131,16 +132,19 @@ export const SelectedFiles = ( }} > - {/* file name */} - {getBasename(selection.fileURI.fsPath)} + + {/* file name */} + {getBasename(selection.fileURI.fsPath)} + {/* selection range */} + {selection.selectionStr !== null ? ` (${selection.range.startLineNumber}-${selection.range.endLineNumber})` : ''} + {/* type of selection */} - {selection.selectionStr ? 'Selection' : 'File'} - + {selection.selectionStr !== null ? 'Selection' : 'File'} {/* X button */} {type === 'staging' && // hoveredIdx === i - { if (type !== 'staging') return; setStaging([...selections.slice(0, i), ...selections.slice(i + 1)]) @@ -151,7 +155,7 @@ export const SelectedFiles = ( }
{/* selection full text */} - {type === 'staging' && selection.selectionStr && selectionIsOpened[i] && + {selection.selectionStr && selectionIsOpened[i] && { // state of current message const [instructions, setInstructions] = useState('') // the user's instructions const onChangeText = useCallback((newStr: string) => { setInstructions(newStr) }, [setInstructions]) - const isDisabled = !instructions + const isDisabled = !instructions.trim() const formRef = useRef(null) @@ -352,10 +356,12 @@ export const SidebarChat = () => { const selections = threadsState._currentStagingSelections + const previousMessages = currentThread?.messages ?? [] + return <>
{/* previous messages */} - {currentThread !== null && currentThread?.messages.map((message, i) => + {previousMessages.map((message, i) => )} @@ -363,79 +369,95 @@ export const SidebarChat = () => {
+ {/* input box */} -
{ if (e.key === 'Enter' && !e.shiftKey) onSubmit(e) }} - - onSubmit={(e) => { - console.log('submit!') - onSubmit(e) - }} > - {/* top row */} -
- {/* selections */} - {(selections && selections.length !== 0) && - - } + { + if (e.key === 'Enter' && !e.shiftKey) { + onSubmit(e) + } + }} + onSubmit={(e) => { + console.log('submit!') + onSubmit(e) + }} + > + {/* top row */} +
+ {/* selections */} + {(selections && selections.length !== 0) && + + } - {/* error message */} - {latestError === null ? null : - { setLatestError(null) }} - showDismiss={true} + {/* error message */} + {latestError === null ? null : + { setLatestError(null) }} + showDismiss={true} + /> + } +
+ + {/* middle row */} +
+ {/* text input */} + - } -
+
- {/* middle row */} -
- {/* text input */} - -
+ {/* bottom row */} +
+ {/* submit options */} +
+ +
- {/* bottom row */} -
- {/* submit / stop button */} - {isLoading ? - // stop button - - : - // submit button (up arrow) - - } -
+ {/* submit / stop button */} + {isLoading ? + // stop button + + : + // submit button (up arrow) + + } +
- - - -
+ +
} diff --git a/src/vs/workbench/contrib/void/browser/react/tailwind.config.js b/src/vs/workbench/contrib/void/browser/react/tailwind.config.js index 94923827..b0cef210 100644 --- a/src/vs/workbench/contrib/void/browser/react/tailwind.config.js +++ b/src/vs/workbench/contrib/void/browser/react/tailwind.config.js @@ -10,7 +10,7 @@ module.exports = { extend: { colors: { vscode: { - // see https://code.visualstudio.com/api/references/theme-color + // see: https://code.visualstudio.com/api/extension-guides/webview#theming-webview-content // base colors "fg": "var(--vscode-foreground)", @@ -53,6 +53,17 @@ module.exports = { "input-validation-warning-fg": "inputValidation-var(--vscode-warningForeground)", "input-validation-warning-border": "inputValidation-var(--vscode-warningBorder)", + // command center colors (the top bar) + "commandcenter-fg": "commandCenter.foreground", + "commandcenter-active-fg": "commandCenter.activeForeground", + "commandcenter-bg": "commandCenter.background", + "commandcenter-active-bg": "commandCenter.activeBackground", + "commandcenter-border": "commandCenter.border", + "commandcenter-inactive-fg": "commandCenter.inactiveForeground", + "commandcenter-inactive-border": "commandCenter.inactiveBorder", + "commandcenter-active-border": "commandCenter.activeBorder", + "commandcenter-debugging-bg": "commandCenter.debuggingBackground", + // badge colors "badge-fg": "var(--vscode-badge-foreground)", "badge-bg": "var(--vscode-badge-background)", diff --git a/src/vs/workbench/contrib/void/browser/registerActions.ts b/src/vs/workbench/contrib/void/browser/registerActions.ts index e0054e45..d46f6bb4 100644 --- a/src/vs/workbench/contrib/void/browser/registerActions.ts +++ b/src/vs/workbench/contrib/void/browser/registerActions.ts @@ -69,22 +69,27 @@ registerAction2(class extends Action2 { stateService.setState({ isHistoryOpen: false, currentTab: 'chat' }) stateService.fireFocusChat() + const selectionRange = roundRangeToLines( + accessor.get(IEditorService).activeTextEditorControl?.getSelection() + ) + // add selection const threadHistoryService = accessor.get(IThreadHistoryService) const currentStaging = threadHistoryService.state._currentStagingSelections - const currentStagingEltIdx = currentStaging?.findIndex(s => s.fileURI.fsPath === model.uri.fsPath) - - // if there exists a selection with this URI, replace it - const selectionRange = roundRangeToLines( - accessor.get(IEditorService).activeTextEditorControl?.getSelection() + const currentStagingEltIdx = currentStaging?.findIndex(s => + s.fileURI.fsPath === model.uri.fsPath + && s.range?.startLineNumber === selectionRange?.startLineNumber + && s.range?.endLineNumber === selectionRange?.endLineNumber ) if (selectionRange) { const selection: CodeStagingSelection = { selectionStr: getContentInRange(model, selectionRange), - fileURI: model.uri + fileURI: model.uri, + range: selectionRange, } + // overwrite selections that match with this one (compares by `fileURI` and line numbers in `range`) if (currentStagingEltIdx !== undefined && currentStagingEltIdx !== -1) { threadHistoryService.setStaging([ ...currentStaging!.slice(0, currentStagingEltIdx), diff --git a/src/vs/workbench/contrib/void/browser/registerThreads.ts b/src/vs/workbench/contrib/void/browser/registerThreads.ts index 851b5de7..797d1d23 100644 --- a/src/vs/workbench/contrib/void/browser/registerThreads.ts +++ b/src/vs/workbench/contrib/void/browser/registerThreads.ts @@ -11,17 +11,20 @@ import { IStorageService, StorageScope, StorageTarget } from '../../../../platfo import { URI } from '../../../../base/common/uri.js'; import { Emitter, Event } from '../../../../base/common/event.js'; import { IAutocompleteService } from './registerAutocomplete.js'; +import { IRange } from '../../../../editor/common/core/range.js'; export type CodeSelection = { - selectionStr: string | null; fileURI: URI; - content: string; // TODO remove this + selectionStr: string | null; + content: string; // TODO remove this (replace `selectionStr` with `content`) + range: IRange; } // if selectionStr is null, it means to use the entire file at send time export type CodeStagingSelection = { - selectionStr: string | null; fileURI: URI; + selectionStr: string | null; + range: IRange; }