diff --git a/extensions/void/package.json b/extensions/void/package.json index e1d147c1..ea73322c 100644 --- a/extensions/void/package.json +++ b/extensions/void/package.json @@ -47,7 +47,7 @@ "icon": "$(history)" }, { - "command": "void.openSettings", + "command": "void.toggleSettings", "title": "Void settings", "icon": "$(settings-gear)" } @@ -95,7 +95,7 @@ "group": "navigation" }, { - "command": "void.openSettings", + "command": "void.toggleSettings", "when": "view == 'void.viewnumberone'", "group": "navigation" } diff --git a/extensions/void/src/DisplayChangesProvider.ts b/extensions/void/src/DisplayChangesProvider.ts index 4166d5b4..9394b410 100644 --- a/extensions/void/src/DisplayChangesProvider.ts +++ b/extensions/void/src/DisplayChangesProvider.ts @@ -28,7 +28,7 @@ export class DisplayChangesProvider implements vscode.CodeLensProvider { // used internally by vscode public provideCodeLenses(document: vscode.TextDocument, token: vscode.CancellationToken): vscode.ProviderResult { const docUriStr = document.uri.toString() - return this._diffsOfDocument[docUriStr].flatMap(diff => diff.lenses) + return this._diffsOfDocument[docUriStr]?.flatMap(diff => diff.lenses) ?? [] } // declared by us, registered with vscode.languages.registerCodeLensProvider() diff --git a/extensions/void/src/extension.ts b/extensions/void/src/extension.ts index f42074b8..de2c699a 100644 --- a/extensions/void/src/extension.ts +++ b/extensions/void/src/extension.ts @@ -54,10 +54,6 @@ export function activate(context: vscode.ExtensionContext) { displayChangesProvider.rejectDiff(params) })); - context.subscriptions.push(vscode.commands.registerCommand('void.openSettings', async () => { - vscode.commands.executeCommand('workbench.action.openSettings', '@ext:void.void'); - })); - // 5. Receive messages from sidebar webviewProvider.webview.then( webview => { @@ -69,6 +65,9 @@ export function activate(context: vscode.ExtensionContext) { context.subscriptions.push(vscode.commands.registerCommand('void.toggleThreadSelector', async () => { webview.postMessage({ type: 'toggleThreadSelector' } satisfies MessageToSidebar) })) + context.subscriptions.push(vscode.commands.registerCommand('void.toggleSettings', async () => { + webview.postMessage({ type: 'toggleSettings' } satisfies MessageToSidebar) + })); // Receive messages in the extension from the sidebar webview (messages are sent using `postMessage`) webview.onDidReceiveMessage(async (m: MessageFromSidebar) => { diff --git a/extensions/void/src/shared_types.ts b/extensions/void/src/shared_types.ts index eed9d07b..a1e3122e 100644 --- a/extensions/void/src/shared_types.ts +++ b/extensions/void/src/shared_types.ts @@ -46,6 +46,7 @@ type MessageToSidebar = ( | { type: 'allThreads', threads: ChatThreads } | { type: 'startNewThread' } | { type: 'toggleThreadSelector' } + | { type: 'toggleSettings' } ) // sidebar -> editor diff --git a/extensions/void/src/sidebar/Sidebar.tsx b/extensions/void/src/sidebar/Sidebar.tsx index c24510be..36029f01 100644 --- a/extensions/void/src/sidebar/Sidebar.tsx +++ b/extensions/void/src/sidebar/Sidebar.tsx @@ -25,6 +25,14 @@ const Sidebar = () => { setTab('threadSelector') }) + // if they toggled settings + useOnVSCodeMessage('toggleSettings', (m) => { + if (tab === 'settings') + setTab('chat') + else + setTab('settings') + }) + // Receive messages from the VSCode extension useEffect(() => { diff --git a/extensions/void/src/sidebar/SidebarSettings.tsx b/extensions/void/src/sidebar/SidebarSettings.tsx index dfb5918e..700ed1da 100644 --- a/extensions/void/src/sidebar/SidebarSettings.tsx +++ b/extensions/void/src/sidebar/SidebarSettings.tsx @@ -1,19 +1,70 @@ import React, { useState } from "react"; -import { useVoidConfig } from "./contextForConfig"; +import { configFields, useVoidConfig, VoidConfigField } from "./contextForConfig"; + + +const SettingOfFieldAndParam = ({ field, param }: { field: VoidConfigField, param: string }) => { + const { voidConfig, partialVoidConfig, voidConfigInfo, setConfigParam } = useVoidConfig() + + const [val, setVal] = useState(partialVoidConfig[field]?.[param]) + + const { enumArr } = voidConfigInfo[field][param] + + const updateState = (e: React.ChangeEvent) => { setVal(e.target.value); }; + const commitConfigParam = () => { if (val) setConfigParam(field, param, val); }; + + + // string + if (enumArr === undefined) { + return ( +
+ + +
+ ) + } + // enum + else { + return ( +
+ + +
+ ) + } +} export const SidebarSettings = () => { - const { voidConfig, setConfigParam } = useVoidConfig() + const { voidConfig, voidConfigInfo } = useVoidConfig() + const current_field = voidConfig.default['whichApi'] as VoidConfigField + const params = Object.keys(voidConfigInfo[current_field]) - - // only show the settings relevant to the current field - - // voidConfig.default.whichApi - - - return null - + return ( +
+ {params.map((param) => ( + + ))} +
+ ) } - diff --git a/extensions/void/src/sidebar/contextForConfig.tsx b/extensions/void/src/sidebar/contextForConfig.tsx index f2e86a7f..14b1cce7 100644 --- a/extensions/void/src/sidebar/contextForConfig.tsx +++ b/extensions/void/src/sidebar/contextForConfig.tsx @@ -17,8 +17,8 @@ const configString = (description: string, defaultVal: string) => { } } - -const configFields = [ +// fields you can customize (don't forget 'default' - it isn't included here!) +export const configFields = [ 'anthropic', 'openAI', 'greptile', @@ -253,17 +253,18 @@ const voidConfigInfo: Record< // this is the type that comes with metadata like desc, default val, etc type VoidConfigInfo = typeof voidConfigInfo +export type VoidConfigField = keyof typeof voidConfigInfo // typeof configFields[number] // this is the type that specifies the user's actual config export type PartialVoidConfig = { [K in keyof typeof voidConfigInfo]?: { - [P in keyof typeof voidConfigInfo[K]]?: string + [P in keyof typeof voidConfigInfo[K]]?: typeof voidConfigInfo[K][P]['defaultVal'] } } export type VoidConfig = { [K in keyof typeof voidConfigInfo]: { - [P in keyof typeof voidConfigInfo[K]]: string + [P in keyof typeof voidConfigInfo[K]]: typeof voidConfigInfo[K][P]['defaultVal'] } } @@ -271,7 +272,7 @@ export type VoidConfig = { const getVoidConfig = (currentConfig: PartialVoidConfig): VoidConfig => { const config = {} as PartialVoidConfig - for (let field of configFields) { + for (let field of [...configFields, 'default'] as const) { config[field] = {} for (let prop in voidConfigInfo[field]) { config[field][prop] = currentConfig[field]?.[prop] || voidConfigInfo[field][prop].defaultVal @@ -296,16 +297,20 @@ const useInstantState = (initVal: T) => { +type SetConfigParamType = (field: K, param: keyof VoidConfigInfo[K], newVal: string) => void + type ConfigValueType = { voidConfig: VoidConfig, - setConfigParam: (field: K, param: keyof VoidConfigInfo[K], newVal: string) => void + voidConfigInfo: VoidConfigInfo, + partialVoidConfig: PartialVoidConfig, + setConfigParam: SetConfigParamType } const ConfigContext = createContext(undefined as unknown as ConfigValueType) export function ConfigProvider({ children }: { children: ReactNode }) { - const [partialVoidConfig, setPartialVoidConfig] = useInstantState({}) // only used internally here, and to communicate with the extension + const [partialVoidConfig, setPartialVoidConfig] = useInstantState({}) // the user's selections const [voidConfig, setVoidConfig] = useState(defaultVoidConfig) @@ -323,6 +328,8 @@ export function ConfigProvider({ children }: { children: ReactNode }) { return ( { const newPartialConfig: PartialVoidConfig = { ...partialVoidConfig.current, diff --git a/extensions/void/src/sidebar/getVscodeApi.ts b/extensions/void/src/sidebar/getVscodeApi.ts index ffe8a18c..80f29ff0 100644 --- a/extensions/void/src/sidebar/getVscodeApi.ts +++ b/extensions/void/src/sidebar/getVscodeApi.ts @@ -12,7 +12,8 @@ const onetimeCallbacks: { [C in Command]: ((res: any) => void)[] } = { "partialVoidConfig": [], "startNewThread": [], "allThreads": [], - "toggleThreadSelector": [] + "toggleThreadSelector": [], + "toggleSettings": [], } // messageType -> id -> res @@ -22,7 +23,8 @@ const callbacks: { [C in Command]: { [id: string]: ((res: any) => void) } } = { "partialVoidConfig": {}, "startNewThread": {}, "allThreads": {}, - "toggleThreadSelector": {} + "toggleThreadSelector": {}, + "toggleSettings": {}, }