From a72305819a1b028bdf34ad6b08e1eccdc41ae4ff Mon Sep 17 00:00:00 2001 From: Andrew Pareles Date: Thu, 2 Jan 2025 19:15:08 -0800 Subject: [PATCH 01/19] copy --- src/vs/workbench/contrib/void/browser/inlineDiffsService.ts | 1 - .../void/browser/react/src/void-settings-tsx/Settings.tsx | 2 +- 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/src/vs/workbench/contrib/void/browser/inlineDiffsService.ts b/src/vs/workbench/contrib/void/browser/inlineDiffsService.ts index 5ccb08ecb..ee4b4ef26 100644 --- a/src/vs/workbench/contrib/void/browser/inlineDiffsService.ts +++ b/src/vs/workbench/contrib/void/browser/inlineDiffsService.ts @@ -822,7 +822,6 @@ class InlineDiffsService extends Disposable implements IInlineDiffsService { const lastDiff = computedDiffs.pop() if (!lastDiff) { - console.log('!lastDiff') // if the writing is identical so far, display no changes originalCodeStartLine = 1 newCodeEndLine = 1 diff --git a/src/vs/workbench/contrib/void/browser/react/src/void-settings-tsx/Settings.tsx b/src/vs/workbench/contrib/void/browser/react/src/void-settings-tsx/Settings.tsx index a4835e993..f7af5b152 100644 --- a/src/vs/workbench/contrib/void/browser/react/src/void-settings-tsx/Settings.tsx +++ b/src/vs/workbench/contrib/void/browser/react/src/void-settings-tsx/Settings.tsx @@ -420,7 +420,7 @@ export const Settings = () => {

Local Providers

{/*

{`Keep your data private by hosting AI locally on your computer.`}

*/} {/*

{`Instructions:`}

*/} -

{`Void can access any model that you host locally. By default, we automatically detect your local models.`}

+

{`Void can access any model that you host locally. We automatically detect your local models by default.`}

From 2519f094cc607ad5bd282fdde21c7ebd79311744 Mon Sep 17 00:00:00 2001 From: Mathew Pareles Date: Fri, 3 Jan 2025 00:00:01 -0800 Subject: [PATCH 02/19] input and dropdown styles --- .../browser/react/src/markdown/BlockCode.tsx | 2 +- .../react/src/markdown/ChatMarkdownRender.tsx | 6 ++-- .../browser/react/src/sidebar-tsx/Sidebar.tsx | 9 +++++- .../react/src/sidebar-tsx/SidebarChat.tsx | 10 +++---- .../void/browser/react/src/util/inputs.tsx | 11 +++++-- .../void/browser/react/tailwind.config.js | 30 +++++++++++++++++-- 6 files changed, 54 insertions(+), 14 deletions(-) diff --git a/src/vs/workbench/contrib/void/browser/react/src/markdown/BlockCode.tsx b/src/vs/workbench/contrib/void/browser/react/src/markdown/BlockCode.tsx index e64c43c3e..dd0954519 100644 --- a/src/vs/workbench/contrib/void/browser/react/src/markdown/BlockCode.tsx +++ b/src/vs/workbench/contrib/void/browser/react/src/markdown/BlockCode.tsx @@ -69,7 +69,7 @@ export const BlockCode = ({ text, buttonsOnHover, language }: { text: string, bu const isSingleLine = !text.includes('\n') return (<> -
+
{buttonsOnHover === null ? null : (
{buttonsOnHover}
diff --git a/src/vs/workbench/contrib/void/browser/react/src/markdown/ChatMarkdownRender.tsx b/src/vs/workbench/contrib/void/browser/react/src/markdown/ChatMarkdownRender.tsx index ef5221f78..12656acb6 100644 --- a/src/vs/workbench/contrib/void/browser/react/src/markdown/ChatMarkdownRender.tsx +++ b/src/vs/workbench/contrib/void/browser/react/src/markdown/ChatMarkdownRender.tsx @@ -49,14 +49,14 @@ const CodeButtonsOnHover = ({ text }: { text: string }) => { return <> @@ -202,7 +202,7 @@ export const ModelDump = () => { > {/* left part is width:full */}
- {isNewProviderName ? displayInfoOfProviderName(providerName).title : ''} + {isNewProviderName ? displayInfoOfProviderName(providerName).title : ''} {modelName} {/* {`${modelName} (${providerName})`} */}
@@ -431,7 +431,7 @@ export const Settings = () => {

-

+

{/* TODO we should create UI for downloading models without user going into terminal */}
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 d339138a1..5f29d06fd 100644 --- a/src/vs/workbench/contrib/void/browser/react/tailwind.config.js +++ b/src/vs/workbench/contrib/void/browser/react/tailwind.config.js @@ -34,6 +34,7 @@ module.exports = { "void-fg-1": "var(--vscode-editor-foreground)", "void-fg-2": "var(--vscode-input-foreground)", "void-fg-3": "var(--vscode-input-placeholderForeground)", + "void-warning": "var(--vscode-charts-orange)", vscode: { From 55ec3365a209afd42592bf3c02edde92672adda5 Mon Sep 17 00:00:00 2001 From: Andrew Pareles Date: Sun, 5 Jan 2025 17:04:05 -0800 Subject: [PATCH 10/19] empty seln --- src/vs/workbench/contrib/void/browser/sidebarActions.ts | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/vs/workbench/contrib/void/browser/sidebarActions.ts b/src/vs/workbench/contrib/void/browser/sidebarActions.ts index be76d2aa8..69508e18e 100644 --- a/src/vs/workbench/contrib/void/browser/sidebarActions.ts +++ b/src/vs/workbench/contrib/void/browser/sidebarActions.ts @@ -29,6 +29,11 @@ import { VOID_OPEN_SETTINGS_ACTION_ID } from './voidSettingsPane.js'; const roundRangeToLines = (range: IRange | null | undefined) => { if (!range) return null + + // treat as no selection if selection is empty + if (range.endColumn === range.startColumn && range.endLineNumber === range.startLineNumber) + return null + // IRange is 1-indexed const endLine = range.endColumn === 1 ? range.endLineNumber - 1 : range.endLineNumber // e.g. if the user triple clicks, it selects column=0, line=line -> column=0, line=line+1 const newRange: IRange = { From b9e61bf4e2a3594827547e05edc35466de6287c8 Mon Sep 17 00:00:00 2001 From: Mathew Pareles Date: Sun, 5 Jan 2025 17:10:18 -0800 Subject: [PATCH 11/19] styles --- .../react/src/void-settings-tsx/Settings.tsx | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/src/vs/workbench/contrib/void/browser/react/src/void-settings-tsx/Settings.tsx b/src/vs/workbench/contrib/void/browser/react/src/void-settings-tsx/Settings.tsx index 279b1a22e..fa27d55a0 100644 --- a/src/vs/workbench/contrib/void/browser/react/src/void-settings-tsx/Settings.tsx +++ b/src/vs/workbench/contrib/void/browser/react/src/void-settings-tsx/Settings.tsx @@ -14,11 +14,11 @@ import { ChatMarkdownRender } from '../markdown/ChatMarkdownRender.js' const SubtleButton = ({ onClick, text, icon, disabled }: { onClick: () => void, text: string, icon: React.ReactNode, disabled: boolean }) => { - return
+ return
- + {text}
@@ -422,14 +422,14 @@ export const Settings = () => {

Local Providers

- {/*

{`Keep your data private by hosting AI locally on your computer.`}

*/} - {/*

{`Instructions:`}

*/} - {/*

{`Void can access any model that you host locally. We automatically detect your local models by default.`}

*/} -

{`Host a model locally and use it in Void. Instructions:`}

+ {/*

{`Keep your data private by hosting AI locally on your computer.`}

*/} + {/*

{`Instructions:`}

*/} + {/*

{`Void can access any model that you host locally. We automatically detect your local models by default.`}

*/} +

{`Host a model locally and use it in Void. Instructions:`}

-

+

{/* TODO we should create UI for downloading models without user going into terminal */} @@ -440,8 +440,8 @@ export const Settings = () => {

More Providers

-

{`Get access to frontier models. We recommend Anthropic or OpenAI.`}

- {/*

{`Access models like ChatGPT and Claude. We recommend using Anthropic or OpenAI as providers, or Groq as a faster alternative.`}

*/} +

{`Get access to frontier models. We recommend Anthropic or OpenAI.`}

+ {/*

{`Access models like ChatGPT and Claude. We recommend using Anthropic or OpenAI as providers, or Groq as a faster alternative.`}

*/} From 35091eb8f227bfb14b6336c5fc9df368054cc61c Mon Sep 17 00:00:00 2001 From: Mathew Pareles Date: Sun, 5 Jan 2025 17:11:10 -0800 Subject: [PATCH 12/19] change wording --- .../void/browser/react/src/void-settings-tsx/ModelDropdown.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/vs/workbench/contrib/void/browser/react/src/void-settings-tsx/ModelDropdown.tsx b/src/vs/workbench/contrib/void/browser/react/src/void-settings-tsx/ModelDropdown.tsx index fb9389c71..d0cd41b4f 100644 --- a/src/vs/workbench/contrib/void/browser/react/src/void-settings-tsx/ModelDropdown.tsx +++ b/src/vs/workbench/contrib/void/browser/react/src/void-settings-tsx/ModelDropdown.tsx @@ -97,7 +97,7 @@ const DummySelectBox = () => { size={14} className='mr-1 brightness-90' /> - Model required + Provider required
// return Date: Sun, 5 Jan 2025 18:03:36 -0800 Subject: [PATCH 13/19] ctrlK --- .../void/browser/inlineDiffsService.ts | 2 +- .../contrib/void/browser/prompt/prompts.ts | 8 +-- .../QuickEdit.tsx} | 6 +- .../QuickEditChat.tsx} | 17 ++++- .../{ctrl-k-tsx => quick-edit-tsx}/index.tsx | 4 +- .../contrib/void/browser/react/tsup.config.js | 2 +- .../contrib/void/browser/sidebarActions.ts | 72 +++++++++---------- 7 files changed, 61 insertions(+), 50 deletions(-) rename src/vs/workbench/contrib/void/browser/react/src/{ctrl-k-tsx/CtrlK.tsx => quick-edit-tsx/QuickEdit.tsx} (83%) rename src/vs/workbench/contrib/void/browser/react/src/{ctrl-k-tsx/CtrlKChat.tsx => quick-edit-tsx/QuickEditChat.tsx} (91%) rename src/vs/workbench/contrib/void/browser/react/src/{ctrl-k-tsx => quick-edit-tsx}/index.tsx (79%) diff --git a/src/vs/workbench/contrib/void/browser/inlineDiffsService.ts b/src/vs/workbench/contrib/void/browser/inlineDiffsService.ts index ee4b4ef26..a7db6e6c1 100644 --- a/src/vs/workbench/contrib/void/browser/inlineDiffsService.ts +++ b/src/vs/workbench/contrib/void/browser/inlineDiffsService.ts @@ -31,7 +31,7 @@ import { ctrlKStream_prefixAndSuffix, ctrlKStream_prompt, ctrlKStream_systemMess import { ILLMMessageService } from '../../../../platform/void/common/llmMessageService.js'; import { IPosition } from '../../../../editor/common/core/position.js'; -import { mountCtrlK } from '../browser/react/out/ctrl-k-tsx/index.js' +import { mountCtrlK } from '../browser/react/out/quick-edit-tsx/index.js' import { QuickEditPropsType } from './quickEditActions.js'; import { InputBox } from '../../../../base/browser/ui/inputbox/inputBox.js'; import { LLMMessage } from '../../../../platform/void/common/llmMessageTypes.js'; diff --git a/src/vs/workbench/contrib/void/browser/prompt/prompts.ts b/src/vs/workbench/contrib/void/browser/prompt/prompts.ts index be1f0f6cb..f65bfcbe0 100644 --- a/src/vs/workbench/contrib/void/browser/prompt/prompts.ts +++ b/src/vs/workbench/contrib/void/browser/prompt/prompts.ts @@ -361,10 +361,10 @@ Note that the SELECTION has code that comes before it. This code is indicated wi Note also that the SELECTION has code that comes after it. This code is indicated with <${sufTag}>...after<${sufTag}/>. Instructions: -1. Your OUTPUT should be a SINGLE PIECE OF CODE of the form <${midTag}>...new_selection<${midTag}/> -2. You may ONLY CHANGE the original SELECTION, and NOT the content in the <${preTag}>...<${preTag}/> or <${sufTag}>...<${sufTag}/> tags -3. Make sure all brackets in the new selection are balanced the same as in the original selection -4. Be careful not to duplicate or remove variables, comments, or other syntax by mistake +1. Your OUTPUT should be a SINGLE PIECE OF CODE of the form <${midTag}>...new_selection<${midTag}/>. Do not give any explanation before or after this. ONLY output this format, nothing more. +2. You may ONLY CHANGE the original SELECTION, and NOT the content in the <${preTag}>...<${preTag}/> or <${sufTag}>...<${sufTag}/> tags. +3. Make sure all brackets in the new selection are balanced the same as in the original selection. +4. Be careful not to duplicate or remove variables, comments, or other syntax by mistake. Complete the following: <${preTag}>${prefix} diff --git a/src/vs/workbench/contrib/void/browser/react/src/ctrl-k-tsx/CtrlK.tsx b/src/vs/workbench/contrib/void/browser/react/src/quick-edit-tsx/QuickEdit.tsx similarity index 83% rename from src/vs/workbench/contrib/void/browser/react/src/ctrl-k-tsx/CtrlK.tsx rename to src/vs/workbench/contrib/void/browser/react/src/quick-edit-tsx/QuickEdit.tsx index f10557fe4..d17574f2d 100644 --- a/src/vs/workbench/contrib/void/browser/react/src/ctrl-k-tsx/CtrlK.tsx +++ b/src/vs/workbench/contrib/void/browser/react/src/quick-edit-tsx/QuickEdit.tsx @@ -6,16 +6,16 @@ import { useEffect, useState } from 'react' import { useIsDark, useSidebarState } from '../util/services.js' import ErrorBoundary from '../sidebar-tsx/ErrorBoundary.js' -import { CtrlKChat } from './CtrlKChat.js' +import { QuickEditChat } from './QuickEditChat.js' import { QuickEditPropsType } from '../../../quickEditActions.js' -export const CtrlK = (props: QuickEditPropsType) => { +export const QuickEdit = (props: QuickEditPropsType) => { const isDark = useIsDark() return
- +
diff --git a/src/vs/workbench/contrib/void/browser/react/src/ctrl-k-tsx/CtrlKChat.tsx b/src/vs/workbench/contrib/void/browser/react/src/quick-edit-tsx/QuickEditChat.tsx similarity index 91% rename from src/vs/workbench/contrib/void/browser/react/src/ctrl-k-tsx/CtrlKChat.tsx rename to src/vs/workbench/contrib/void/browser/react/src/quick-edit-tsx/QuickEditChat.tsx index 6f4ff7c0a..6925079d5 100644 --- a/src/vs/workbench/contrib/void/browser/react/src/ctrl-k-tsx/CtrlKChat.tsx +++ b/src/vs/workbench/contrib/void/browser/react/src/quick-edit-tsx/QuickEditChat.tsx @@ -14,13 +14,14 @@ import { ButtonStop, ButtonSubmit } from '../sidebar-tsx/SidebarChat.js'; import { ModelDropdown } from '../void-settings-tsx/ModelDropdown.js'; import { X } from 'lucide-react'; -export const CtrlKChat = ({ diffareaid, onGetInputBox, onUserUpdateText, onChangeHeight, initText }: QuickEditPropsType) => { +export const QuickEditChat = ({ diffareaid, onGetInputBox, onUserUpdateText, onChangeHeight, initText }: QuickEditPropsType) => { const accessor = useAccessor() const inlineDiffsService = accessor.get('IInlineDiffsService') const sizerRef = useRef(null) const inputBoxRef: React.MutableRefObject = useRef(null); + useEffect(() => { const inputContainer = sizerRef.current if (!inputContainer) return; @@ -67,6 +68,10 @@ export const CtrlKChat = ({ diffareaid, onGetInputBox, onUserUpdateText, onChang }, [inlineDiffsService]) + const onX = useCallback(() => { + inlineDiffsService.removeCtrlKZone({ diffareaid }) + }, [inlineDiffsService, diffareaid]) + // sync init value const alreadySetRef = useRef(false) useEffect(() => { @@ -116,9 +121,9 @@ export const CtrlKChat = ({ diffareaid, onGetInputBox, onUserUpdateText, onChang @@[&_div.monaco-inputbox]:!void-outline-none`} >
-
+
{ inlineDiffsService.removeCtrlKZone({ diffareaid }) }} + onClick={onX} />
@@ -132,6 +137,12 @@ export const CtrlKChat = ({ diffareaid, onGetInputBox, onUserUpdateText, onChang onChangeText={onChangeText} onCreateInstance={useCallback((instance: InputBox) => { inputBoxRef.current = instance; + + // if presses the esc key, X + instance.element.addEventListener('keydown', (e) => { + if (e.key === 'Escape') + onX() + }) onGetInputBox(instance); instance.focus() }, [onGetInputBox])} diff --git a/src/vs/workbench/contrib/void/browser/react/src/ctrl-k-tsx/index.tsx b/src/vs/workbench/contrib/void/browser/react/src/quick-edit-tsx/index.tsx similarity index 79% rename from src/vs/workbench/contrib/void/browser/react/src/ctrl-k-tsx/index.tsx rename to src/vs/workbench/contrib/void/browser/react/src/quick-edit-tsx/index.tsx index 4d59dbca2..c3553893b 100644 --- a/src/vs/workbench/contrib/void/browser/react/src/ctrl-k-tsx/index.tsx +++ b/src/vs/workbench/contrib/void/browser/react/src/quick-edit-tsx/index.tsx @@ -4,9 +4,9 @@ *--------------------------------------------------------------------------------------------*/ import { mountFnGenerator } from '../util/mountFnGenerator.js' -import { CtrlK } from './CtrlK.js' +import { QuickEdit } from './QuickEdit.js' -export const mountCtrlK = mountFnGenerator(CtrlK) +export const mountCtrlK = mountFnGenerator(QuickEdit) diff --git a/src/vs/workbench/contrib/void/browser/react/tsup.config.js b/src/vs/workbench/contrib/void/browser/react/tsup.config.js index 2a7547a05..9070f8e15 100644 --- a/src/vs/workbench/contrib/void/browser/react/tsup.config.js +++ b/src/vs/workbench/contrib/void/browser/react/tsup.config.js @@ -9,7 +9,7 @@ export default defineConfig({ entry: [ './src2/sidebar-tsx/index.tsx', './src2/void-settings-tsx/index.tsx', - './src2/ctrl-k-tsx/index.tsx', + './src2/quick-edit-tsx/index.tsx', './src2/diff/index.tsx', ], outDir: './out', diff --git a/src/vs/workbench/contrib/void/browser/sidebarActions.ts b/src/vs/workbench/contrib/void/browser/sidebarActions.ts index 69508e18e..bd1c753ff 100644 --- a/src/vs/workbench/contrib/void/browser/sidebarActions.ts +++ b/src/vs/workbench/contrib/void/browser/sidebarActions.ts @@ -83,45 +83,45 @@ registerAction2(class extends Action2 { ) + // select whole lines if (selectionRange) { - // select whole lines editor?.setSelection({ startLineNumber: selectionRange.startLineNumber, endLineNumber: selectionRange.endLineNumber, startColumn: 1, endColumn: Number.MAX_SAFE_INTEGER }) + } + + const selectionStr = getContentInRange(model, selectionRange) + + const selection: CodeStagingSelection = !selectionRange || !selectionStr || (selectionRange.startLineNumber > selectionRange.endLineNumber) ? { + type: 'File', + fileURI: model.uri, + selectionStr: null, + range: null, + } : { + type: 'Selection', + fileURI: model.uri, + selectionStr: selectionStr, + range: selectionRange, + } - const selectionStr = getContentInRange(model, selectionRange) - - const selection: CodeStagingSelection = selectionStr === null || selectionRange.startLineNumber > selectionRange.endLineNumber ? { - type: 'File', - fileURI: model.uri, - selectionStr: null, - range: null, - } : { - type: 'Selection', - fileURI: model.uri, - selectionStr: selectionStr, - range: selectionRange, - } - - // add selection to staging - const threadHistoryService = accessor.get(IThreadHistoryService) - const currentStaging = threadHistoryService.state._currentStagingSelections - const currentStagingEltIdx = currentStaging?.findIndex(s => - s.fileURI.fsPath === model.uri.fsPath - && s.range?.startLineNumber === selection.range?.startLineNumber - && s.range?.endLineNumber === selection.range?.endLineNumber - ) - - // if matches with existing selection, overwrite - if (currentStagingEltIdx !== undefined && currentStagingEltIdx !== -1) { - threadHistoryService.setStaging([ - ...currentStaging!.slice(0, currentStagingEltIdx), - selection, - ...currentStaging!.slice(currentStagingEltIdx + 1, Infinity) - ]) - } - // if no match, add - else { - threadHistoryService.setStaging([...(currentStaging ?? []), selection]) - } + // add selection to staging + const threadHistoryService = accessor.get(IThreadHistoryService) + const currentStaging = threadHistoryService.state._currentStagingSelections + const currentStagingEltIdx = currentStaging?.findIndex(s => + s.fileURI.fsPath === model.uri.fsPath + && s.range?.startLineNumber === selection.range?.startLineNumber + && s.range?.endLineNumber === selection.range?.endLineNumber + ) + + // if matches with existing selection, overwrite + if (currentStagingEltIdx !== undefined && currentStagingEltIdx !== -1) { + threadHistoryService.setStaging([ + ...currentStaging!.slice(0, currentStagingEltIdx), + selection, + ...currentStaging!.slice(currentStagingEltIdx + 1, Infinity) + ]) + } + // if no match, add + else { + threadHistoryService.setStaging([...(currentStaging ?? []), selection]) } } From 2ba04a78a8bbc6fa1f4ec879c39c9fc0e4d54b6d Mon Sep 17 00:00:00 2001 From: Andrew Pareles Date: Sun, 5 Jan 2025 21:02:31 -0800 Subject: [PATCH 14/19] add X to ctrlK --- .../react/src/markdown/ChatMarkdownRender.tsx | 8 ++--- .../src/quick-edit-tsx/QuickEditChat.tsx | 17 +++++++---- .../react/src/sidebar-tsx/ErrorDisplay.tsx | 30 +++++++++---------- .../react/src/sidebar-tsx/SidebarChat.tsx | 9 ++---- .../src/sidebar-tsx/SidebarThreadSelector.tsx | 4 +-- .../react/src/void-settings-tsx/Settings.tsx | 17 +++++------ 6 files changed, 42 insertions(+), 43 deletions(-) diff --git a/src/vs/workbench/contrib/void/browser/react/src/markdown/ChatMarkdownRender.tsx b/src/vs/workbench/contrib/void/browser/react/src/markdown/ChatMarkdownRender.tsx index dc134d6f1..e89cb665b 100644 --- a/src/vs/workbench/contrib/void/browser/react/src/markdown/ChatMarkdownRender.tsx +++ b/src/vs/workbench/contrib/void/browser/react/src/markdown/ChatMarkdownRender.tsx @@ -49,14 +49,14 @@ const CodeButtonsOnHover = ({ text }: { text: string }) => { return <> )} {showDismiss && onDismiss && ( - )}
@@ -75,10 +75,10 @@ export const ErrorDisplay = ({ {/* Expandable Details */} {isExpanded && details && ( -
+
- Full Error: -
{details}
+ Full Error: +
{details}
)} 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 6b6e3bc37..e34209ae0 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 @@ -272,7 +272,7 @@ export const SelectedFiles = ( return ( !!selections && selections.length !== 0 && (
{selections.map((selection, i) => { @@ -311,12 +311,7 @@ export const SelectedFiles = ( {/* X button */} {type === 'staging' && { e.stopPropagation(); if (type !== 'staging') return; diff --git a/src/vs/workbench/contrib/void/browser/react/src/sidebar-tsx/SidebarThreadSelector.tsx b/src/vs/workbench/contrib/void/browser/react/src/sidebar-tsx/SidebarThreadSelector.tsx index e6adb5f22..130ccf10d 100644 --- a/src/vs/workbench/contrib/void/browser/react/src/sidebar-tsx/SidebarThreadSelector.tsx +++ b/src/vs/workbench/contrib/void/browser/react/src/sidebar-tsx/SidebarThreadSelector.tsx @@ -53,7 +53,7 @@ export const SidebarThreadSelector = () => {
{/* a list of all the past threads */} -
+
{sortedThreadIds.map((threadId) => { if (!allThreads) return <>Error: Threads not found. @@ -88,7 +88,7 @@ export const SidebarThreadSelector = () => { ) })} -
+
) diff --git a/src/vs/workbench/contrib/void/browser/react/src/void-settings-tsx/Settings.tsx b/src/vs/workbench/contrib/void/browser/react/src/void-settings-tsx/Settings.tsx index fa27d55a0..8239ef885 100644 --- a/src/vs/workbench/contrib/void/browser/react/src/void-settings-tsx/Settings.tsx +++ b/src/vs/workbench/contrib/void/browser/react/src/void-settings-tsx/Settings.tsx @@ -197,7 +197,6 @@ export const ModelDump = () => { return
{/* left part is width:full */} @@ -285,7 +284,7 @@ const ProviderSetting = ({ providerName, settingName }: { providerName: Provider }, [voidSettingsService, providerName, settingName])} multiline={false} /> - {subTextMd === undefined ? null :
+ {subTextMd === undefined ? null :
} @@ -425,13 +424,13 @@ export const Settings = () => { {/*

{`Keep your data private by hosting AI locally on your computer.`}

*/} {/*

{`Instructions:`}

*/} {/*

{`Void can access any model that you host locally. We automatically detect your local models by default.`}

*/} -

{`Host a model locally and use it in Void. Instructions:`}

+

{`Void can access any model that you host locally. We automatically detect your local models by default.`}

-

-

-

-

-

+

+

+

+

+

{/* TODO we should create UI for downloading models without user going into terminal */}
@@ -440,7 +439,7 @@ export const Settings = () => {

More Providers

-

{`Get access to frontier models. We recommend Anthropic or OpenAI.`}

+

{`Void can also access models from Anthropic, OpenAI, OpenRouter, and more.`}

{/*

{`Access models like ChatGPT and Claude. We recommend using Anthropic or OpenAI as providers, or Groq as a faster alternative.`}

*/} From dd133d2cd5eb131e02d095fb09c6fc9b81cdbe61 Mon Sep 17 00:00:00 2001 From: Andrew Pareles Date: Sun, 5 Jan 2025 21:27:16 -0800 Subject: [PATCH 15/19] ctrlK roundRange --- .../contrib/void/browser/quickEditActions.ts | 3 ++- .../react/src/quick-edit-tsx/QuickEditChat.tsx | 4 ++-- .../browser/react/src/sidebar-tsx/Sidebar.tsx | 2 +- .../void/browser/react/src/util/inputs.tsx | 8 ++++---- .../src/void-settings-tsx/ModelDropdown.tsx | 1 + .../contrib/void/browser/sidebarActions.ts | 16 +++++++++------- 6 files changed, 19 insertions(+), 15 deletions(-) diff --git a/src/vs/workbench/contrib/void/browser/quickEditActions.ts b/src/vs/workbench/contrib/void/browser/quickEditActions.ts index 39461b188..285e21d29 100644 --- a/src/vs/workbench/contrib/void/browser/quickEditActions.ts +++ b/src/vs/workbench/contrib/void/browser/quickEditActions.ts @@ -11,6 +11,7 @@ import { IMetricsService } from '../../../../platform/void/common/metricsService import { ICodeEditorService } from '../../../../editor/browser/services/codeEditorService.js'; import { IInlineDiffsService } from './inlineDiffsService.js'; import { InputBox } from '../../../../base/browser/ui/inputbox/inputBox.js'; +import { roundRangeToLines } from './sidebarActions.js'; export type QuickEditPropsType = { @@ -54,7 +55,7 @@ registerAction2(class extends Action2 { if (!editor) return; const model = editor.getModel() if (!model) return; - const selection = editor.getSelection() + const selection = roundRangeToLines(editor.getSelection(), { emptySelectionBehavior: 'line' }) if (!selection) return; 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 6d66c5a3c..26bbc9f95 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 @@ -146,9 +146,9 @@ export const QuickEditChat = ({ diffareaid, onGetInputBox, onUserUpdateText, onC
- + diff --git a/src/vs/workbench/contrib/void/browser/react/src/sidebar-tsx/Sidebar.tsx b/src/vs/workbench/contrib/void/browser/react/src/sidebar-tsx/Sidebar.tsx index b259a728a..4a5f23b10 100644 --- a/src/vs/workbench/contrib/void/browser/react/src/sidebar-tsx/Sidebar.tsx +++ b/src/vs/workbench/contrib/void/browser/react/src/sidebar-tsx/Sidebar.tsx @@ -39,7 +39,7 @@ export const Sidebar = ({ className }: { className: string }) => { sidebarStateService.setState({ currentTab: tabs[(index + 1) % tabs.length] as any }) }}>clickme {tab} */} -
+
diff --git a/src/vs/workbench/contrib/void/browser/react/src/util/inputs.tsx b/src/vs/workbench/contrib/void/browser/react/src/util/inputs.tsx index 6319c1f02..029e00001 100644 --- a/src/vs/workbench/contrib/void/browser/react/src/util/inputs.tsx +++ b/src/vs/workbench/contrib/void/browser/react/src/util/inputs.tsx @@ -197,11 +197,12 @@ export const VoidCheckBox = ({ label, value, onClick, className }: { label: stri } -export const VoidSelectBox = ({ onChangeSelection, onCreateInstance, selectBoxRef, options }: { +export const VoidSelectBox = ({ onChangeSelection, onCreateInstance, selectBoxRef, options, className }: { onChangeSelection: (value: T) => void; onCreateInstance?: ((instance: SelectBox) => void | IDisposable[]); selectBoxRef?: React.MutableRefObject; options: readonly { text: string, value: T }[]; + className?:string; }) => { const accessor = useAccessor() const contextViewProvider = accessor.get('IContextViewService') @@ -209,10 +210,9 @@ export const VoidSelectBox = ({ onChangeSelection, onCreateInstance, selectB let containerRef = useRef(null); return { containerRef.current = container diff --git a/src/vs/workbench/contrib/void/browser/react/src/void-settings-tsx/ModelDropdown.tsx b/src/vs/workbench/contrib/void/browser/react/src/void-settings-tsx/ModelDropdown.tsx index d0cd41b4f..1a3bd7343 100644 --- a/src/vs/workbench/contrib/void/browser/react/src/void-settings-tsx/ModelDropdown.tsx +++ b/src/vs/workbench/contrib/void/browser/react/src/void-settings-tsx/ModelDropdown.tsx @@ -32,6 +32,7 @@ const ModelSelectBox = ({ options, featureName }: { options: ModelOption[], feat let weChangedText = false return { if (weChangedText) return diff --git a/src/vs/workbench/contrib/void/browser/sidebarActions.ts b/src/vs/workbench/contrib/void/browser/sidebarActions.ts index bd1c753ff..b2a4df915 100644 --- a/src/vs/workbench/contrib/void/browser/sidebarActions.ts +++ b/src/vs/workbench/contrib/void/browser/sidebarActions.ts @@ -26,13 +26,17 @@ import { VOID_OPEN_SETTINGS_ACTION_ID } from './voidSettingsPane.js'; // ---------- Register commands and keybindings ---------- -const roundRangeToLines = (range: IRange | null | undefined) => { +export const roundRangeToLines = (range: IRange | null | undefined, options: { emptySelectionBehavior: 'null' | 'line' }) => { if (!range) return null // treat as no selection if selection is empty - if (range.endColumn === range.startColumn && range.endLineNumber === range.startLineNumber) - return null + if (range.endColumn === range.startColumn && range.endLineNumber === range.startLineNumber) { + if (options.emptySelectionBehavior === 'null') + return null + else if (options.emptySelectionBehavior === 'line') + return { startLineNumber: range.startLineNumber, startColumn: 1, endLineNumber: range.startLineNumber, endColumn: 1 } + } // IRange is 1-indexed const endLine = range.endColumn === 1 ? range.endLineNumber - 1 : range.endLineNumber // e.g. if the user triple clicks, it selects column=0, line=line -> column=0, line=line+1 @@ -77,10 +81,8 @@ registerAction2(class extends Action2 { stateService.fireFocusChat() const editor = editorService.getActiveCodeEditor() - const selectionRange = roundRangeToLines( - // accessor.get(IEditorService).activeTextEditorControl?.getSelection() - editor?.getSelection() - ) + // accessor.get(IEditorService).activeTextEditorControl?.getSelection() + const selectionRange = roundRangeToLines(editor?.getSelection(), { emptySelectionBehavior: 'null' }) // select whole lines From f19e579ce9b6485ebb8d11775b965fe68017e4dd Mon Sep 17 00:00:00 2001 From: Andrew Pareles Date: Mon, 6 Jan 2025 01:19:27 -0800 Subject: [PATCH 16/19] extract code works! ignore etc --- .../platform/void/common/voidSettingsTypes.ts | 2 +- .../void/browser/autocompleteService.ts | 4 +- .../browser/helpers/extractCodeFromResult.ts | 18 +-- .../void/browser/inlineDiffsService.ts | 25 +++- .../contrib/void/browser/prompt/prompts.ts | 28 ++-- .../react/src/void-settings-tsx/Settings.tsx | 122 ++++++++++++------ 6 files changed, 136 insertions(+), 63 deletions(-) diff --git a/src/vs/platform/void/common/voidSettingsTypes.ts b/src/vs/platform/void/common/voidSettingsTypes.ts index e4878e6ff..3c9b9da05 100644 --- a/src/vs/platform/void/common/voidSettingsTypes.ts +++ b/src/vs/platform/void/common/voidSettingsTypes.ts @@ -204,7 +204,7 @@ export const displayInfoOfProviderName = (providerName: ProviderName): DisplayIn } else if (providerName === 'openAICompatible') { return { - title: 'Other', + title: 'OpenAI-Compatible', } } else if (providerName === 'gemini') { diff --git a/src/vs/workbench/contrib/void/browser/autocompleteService.ts b/src/vs/workbench/contrib/void/browser/autocompleteService.ts index 3bd4d955f..bbefb748a 100644 --- a/src/vs/workbench/contrib/void/browser/autocompleteService.ts +++ b/src/vs/workbench/contrib/void/browser/autocompleteService.ts @@ -17,7 +17,7 @@ import { IEditorService } from '../../../services/editor/common/editorService.js import { isCodeEditor } from '../../../../editor/browser/editorBrowser.js'; import { EditorResourceAccessor } from '../../../common/editor.js'; import { IModelService } from '../../../../editor/common/services/model.js'; -import { extractCodeFromResult } from './helpers/extractCodeFromResult.js'; +import { extractCodeFromRegular } from './helpers/extractCodeFromResult.js'; // The extension this was called from is here - https://github.com/voideditor/void/blob/autocomplete/extensions/void/src/extension/extension.ts @@ -652,7 +652,7 @@ export class AutocompleteService extends Disposable implements IAutocompleteServ // newAutocompletion.abortRef = { current: () => { } } newAutocompletion.status = 'finished' // newAutocompletion.promise = undefined - newAutocompletion.insertText = postprocessResult(extractCodeFromResult(fullText)) + newAutocompletion.insertText = postprocessResult(extractCodeFromRegular(fullText)) resolve(newAutocompletion.insertText) diff --git a/src/vs/workbench/contrib/void/browser/helpers/extractCodeFromResult.ts b/src/vs/workbench/contrib/void/browser/helpers/extractCodeFromResult.ts index 2573dae4a..6ac12fd1f 100644 --- a/src/vs/workbench/contrib/void/browser/helpers/extractCodeFromResult.ts +++ b/src/vs/workbench/contrib/void/browser/helpers/extractCodeFromResult.ts @@ -4,9 +4,8 @@ *--------------------------------------------------------------------------------------------*/ - - -export const extractArtificialFIMCodeFromResult = ({ text, preTag, sufTag, midTag }: { text: string, preTag: string, sufTag: string, midTag: string }) => { +// modelWasTrainedOnFIM should be false here +export const extractCodeFromFIM = ({ text, midTag, modelWasTrainedOnFIM }: { text: string, midTag: string, modelWasTrainedOnFIM: false }) => { /* desired matches ` @@ -39,22 +38,25 @@ export const extractArtificialFIMCodeFromResult = ({ text, preTag, sufTag, midTa [optional ` | `` | ```] */ - const regex = /[\s\S]*?(?:`{1,3}\s*([a-zA-Z_]+[\w]*)?[\s\S]*?)?([\s\S]*?)(?:|`{1,3}|$)/; - + // const regex = /[\s\S]*?(?:`{1,3}\s*([a-zA-Z_]+[\w]*)?[\s\S]*?)?([\s\S]*?)(?:<\/MID>|`{1,3}|$)/; + const regex = new RegExp( + `[\\s\\S]*?(?:\`{1,3}\\s*([a-zA-Z_]+[\\w]*)?[\\s\\S]*?)?<${midTag}>([\\s\\S]*?)(?:|\`{1,3}|$)`, + '' + ); const match = text.match(regex); if (match) { const [_, languageName, codeBetweenMidTags] = match; - return [languageName, codeBetweenMidTags] + return [languageName, codeBetweenMidTags] as const } else { - return [undefined, extractCodeFromResult(text)] + return [undefined, extractCodeFromRegular(text)] as const } } -export const extractCodeFromResult = (result: string) => { +export const extractCodeFromRegular = (result: string) => { // Match either: // 1. ```language\n``` // 2. `````` diff --git a/src/vs/workbench/contrib/void/browser/inlineDiffsService.ts b/src/vs/workbench/contrib/void/browser/inlineDiffsService.ts index a7db6e6c1..40f4391d5 100644 --- a/src/vs/workbench/contrib/void/browser/inlineDiffsService.ts +++ b/src/vs/workbench/contrib/void/browser/inlineDiffsService.ts @@ -27,7 +27,7 @@ import * as dom from '../../../../base/browser/dom.js'; import { Widget } from '../../../../base/browser/ui/widget.js'; import { URI } from '../../../../base/common/uri.js'; import { IConsistentEditorItemService, IConsistentItemService } from './helperServices/consistentItemService.js'; -import { ctrlKStream_prefixAndSuffix, ctrlKStream_prompt, ctrlKStream_systemMessage, ctrlLStream_prompt, ctrlLStream_systemMessage } from './prompt/prompts.js'; +import { ctrlKStream_prefixAndSuffix, ctrlKStream_prompt, ctrlKStream_systemMessage, ctrlLStream_prompt, ctrlLStream_systemMessage, defaultFimTags } from './prompt/prompts.js'; import { ILLMMessageService } from '../../../../platform/void/common/llmMessageService.js'; import { IPosition } from '../../../../editor/common/core/position.js'; @@ -36,6 +36,7 @@ import { QuickEditPropsType } from './quickEditActions.js'; import { InputBox } from '../../../../base/browser/ui/inputbox/inputBox.js'; import { LLMMessage } from '../../../../platform/void/common/llmMessageTypes.js'; import { IModelContentChangedEvent } from '../../../../editor/common/textModelEvents.js'; +import { extractCodeFromFIM, extractCodeFromRegular } from './helpers/extractCodeFromResult.js'; const configOfBG = (color: Color) => { return { dark: color, light: color, hcDark: color, hcLight: color, } @@ -1043,6 +1044,10 @@ class InlineDiffsService extends Disposable implements IInlineDiffsService { // this._deleteDiffArea(ctrlKZone) // } + // TODO ctrl+K case should be replaced with an actual check for model.isFIM + const modelWasTrainedOnFIM = featureName === 'Ctrl+K' ? false : false + const modelFimTags = defaultFimTags + const adding: Omit = { type: 'DiffZone', originalCode, @@ -1071,7 +1076,7 @@ class InlineDiffsService extends Disposable implements IInlineDiffsService { } else if (featureName === 'Ctrl+K') { const { prefix, suffix } = ctrlKStream_prefixAndSuffix({ fullFileStr: currentFileStr, startLine, endLine }) - const userContent = ctrlKStream_prompt({ selection: originalCode, userMessage, prefix, suffix }) + const userContent = ctrlKStream_prompt({ selection: originalCode, userMessage, prefix, suffix, modelWasTrainedOnFIM, fimTags: modelFimTags }) console.log('PREFIX:\n', prefix) console.log('SUFFIX:\n', suffix) console.log('USER CONTENT:\n', userContent) @@ -1102,17 +1107,29 @@ class InlineDiffsService extends Disposable implements IInlineDiffsService { // refresh now in case onText takes a while to get 1st message this._refreshStylesAndDiffsInURI(uri) + + const extractText = (fullText: string) => { + if (featureName === 'Ctrl+K') { + const [_, textSoFar] = extractCodeFromFIM({ text: fullText, midTag: modelFimTags.midTag, modelWasTrainedOnFIM }) + return textSoFar + } + else if (featureName === 'Ctrl+L') { + return extractCodeFromRegular(fullText) + } + throw 1 + } + streamRequestIdRef.current = this._llmMessageService.sendLLMMessage({ featureName, logging: { loggingName: `startApplying - ${featureName}` }, messages, onText: ({ newText, fullText }) => { - this._writeDiffZoneLLMText(diffZone, fullText, latestCurrentFileEnd, latestOriginalFileStart) + this._writeDiffZoneLLMText(diffZone, extractText(fullText), latestCurrentFileEnd, latestOriginalFileStart) this._refreshStylesAndDiffsInURI(uri) }, onFinalMessage: ({ fullText }) => { // at the end, re-write whole thing to make sure no sync errors - this._writeText(uri, fullText, + this._writeText(uri, extractText(fullText), { startLineNumber: diffZone.startLine, startColumn: 1, endLineNumber: diffZone.endLine, endColumn: Number.MAX_SAFE_INTEGER }, // 1-indexed { shouldRealignDiffAreas: false } ) diff --git a/src/vs/workbench/contrib/void/browser/prompt/prompts.ts b/src/vs/workbench/contrib/void/browser/prompt/prompts.ts index f65bfcbe0..f27597446 100644 --- a/src/vs/workbench/contrib/void/browser/prompt/prompts.ts +++ b/src/vs/workbench/contrib/void/browser/prompt/prompts.ts @@ -324,13 +324,25 @@ export const ctrlKStream_prefixAndSuffix = ({ fullFileStr, startLine, endLine }: } -export const ctrlKStream_prompt = ({ selection, prefix, suffix, userMessage }: { selection: string, prefix: string, suffix: string, userMessage: string, }) => { - const modelWasTrainedOnFIM = false + +export type FimTagsType = { + preTag: string, + sufTag: string, + midTag: string +} +export const defaultFimTags: FimTagsType = { + preTag: 'BEFORE', + sufTag: 'AFTER', + midTag: 'SELECTION', +} + +export const ctrlKStream_prompt = ({ selection, prefix, suffix, userMessage, modelWasTrainedOnFIM, fimTags }: { selection: string, prefix: string, suffix: string, userMessage: string, modelWasTrainedOnFIM: boolean, fimTags: FimTagsType }) => { + const { preTag, sufTag, midTag } = fimTags if (modelWasTrainedOnFIM) { - const preTag = 'PRE' - const sufTag = 'SUF' - const midTag = 'MID' + // const preTag = 'PRE' + // const sufTag = 'SUF' + // const midTag = 'MID' return `\ <${preTag}> /* Original Selection: @@ -343,9 +355,9 @@ ${prefix} } // prompt the model artifically on how to do FIM else { - const preTag = 'BEFORE' - const sufTag = 'AFTER' - const midTag = 'SELECTION' + // const preTag = 'BEFORE' + // const sufTag = 'AFTER' + // const midTag = 'SELECTION' return `\ The user is selecting this code as their SELECTION: \`\`\` diff --git a/src/vs/workbench/contrib/void/browser/react/src/void-settings-tsx/Settings.tsx b/src/vs/workbench/contrib/void/browser/react/src/void-settings-tsx/Settings.tsx index 8239ef885..f8d07f754 100644 --- a/src/vs/workbench/contrib/void/browser/react/src/void-settings-tsx/Settings.tsx +++ b/src/vs/workbench/contrib/void/browser/react/src/void-settings-tsx/Settings.tsx @@ -9,7 +9,7 @@ import { ProviderName, SettingName, displayInfoOfSettingName, providerNames, Voi import ErrorBoundary from '../sidebar-tsx/ErrorBoundary.js' import { VoidCheckBox, VoidInputBox, VoidSelectBox, VoidSwitch } from '../util/inputs.js' import { useAccessor, useIsDark, useRefreshModelListener, useRefreshModelState, useSettingsState } from '../util/services.js' -import { X, RefreshCw, Loader2, Check } from 'lucide-react' +import { X, RefreshCw, Loader2, Check, MoveRight } from 'lucide-react' import { ChatMarkdownRender } from '../markdown/ChatMarkdownRender.js' const SubtleButton = ({ onClick, text, icon, disabled }: { onClick: () => void, text: string, icon: React.ReactNode, disabled: boolean }) => { @@ -360,6 +360,7 @@ export const VoidProviderSettings = ({ providerNames }: { providerNames: Provide // })} // // } +type TabName = 'models' | 'general' export const VoidFeatureFlagSettings = () => { const accessor = useAccessor() @@ -383,12 +384,85 @@ export const VoidFeatureFlagSettings = () => { } +export const FeaturesTab = () => { + return <> +

Local Providers

+ {/*

{`Keep your data private by hosting AI locally on your computer.`}

*/} + {/*

{`Instructions:`}

*/} + {/*

{`Void can access any model that you host locally. We automatically detect your local models by default.`}

*/} +

{`Void can access any model that you host locally. We automatically detect your local models by default.`}

+
+ + + + + + {/* TODO we should create UI for downloading models without user going into terminal */} +
+ + + + + +

Providers

+

{`Void can access models from Anthropic, OpenAI, OpenRouter, and more.`}

+ {/*

{`Access models like ChatGPT and Claude. We recommend using Anthropic or OpenAI as providers, or Groq as a faster alternative.`}

*/} + + + + +

Models

+ + + + + + + +} + + + + + + +const OneClickSwitch = () => { + +} + + +const GeneralTab = () => { + return <> + {/* */} + + {/* keyboard shortcuts */} + +

General Settings

+

{`VS Code's built-in settings.`}

+ +

Keyboard Settings

+

{`Void can access models from Anthropic, OpenAI, OpenRouter, and more.`}

+ + +

One-click Switch

+ + Transfer your VS Code settings to Void. + +

Theme

+ + +

Rules for AI

+ + + +} + // full settings export const Settings = () => { const isDark = useIsDark() - const [tab, setTab] = useState<'models' | 'features'>('models') + const [tab, setTab] = useState('models') return
@@ -407,9 +481,9 @@ export const Settings = () => { - {/* */} +
{/* separator */} @@ -420,43 +494,11 @@ export const Settings = () => {
-

Local Providers

- {/*

{`Keep your data private by hosting AI locally on your computer.`}

*/} - {/*

{`Instructions:`}

*/} - {/*

{`Void can access any model that you host locally. We automatically detect your local models by default.`}

*/} -

{`Void can access any model that you host locally. We automatically detect your local models by default.`}

-
-

-

-

-

-

- {/* TODO we should create UI for downloading models without user going into terminal */} -
- - - - - -

More Providers

-

{`Void can also access models from Anthropic, OpenAI, OpenRouter, and more.`}

- {/*

{`Access models like ChatGPT and Claude. We recommend using Anthropic or OpenAI as providers, or Groq as a faster alternative.`}

*/} - - - - -

Models

- - - - - - +
-
-

{ setTab('features') }}>Features

- {/* */} +
+
From bb7e69b20bc61694d5e5e9ba8a669aa6a599dabb Mon Sep 17 00:00:00 2001 From: Andrew Pareles Date: Mon, 6 Jan 2025 01:43:54 -0800 Subject: [PATCH 17/19] small fix for realigning --- src/vs/workbench/contrib/void/browser/inlineDiffsService.ts | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/vs/workbench/contrib/void/browser/inlineDiffsService.ts b/src/vs/workbench/contrib/void/browser/inlineDiffsService.ts index 40f4391d5..05b8c3d0f 100644 --- a/src/vs/workbench/contrib/void/browser/inlineDiffsService.ts +++ b/src/vs/workbench/contrib/void/browser/inlineDiffsService.ts @@ -823,6 +823,7 @@ class InlineDiffsService extends Disposable implements IInlineDiffsService { const lastDiff = computedDiffs.pop() if (!lastDiff) { + // console.log('!lastDiff') // if the writing is identical so far, display no changes originalCodeStartLine = 1 newCodeEndLine = 1 @@ -842,7 +843,8 @@ class InlineDiffsService extends Disposable implements IInlineDiffsService { const newCodeTop = llmText.split('\n').slice(0, (newCodeEndLine - 1) + 1).join('\n') const oldFileBottom = diffZone.originalCode.split('\n').slice((originalCodeStartLine - 1) + 1, Infinity).join('\n') - const newCode = `${newCodeTop}\n${oldFileBottom}` + // oriignalCode[1 + line...Infinity]. Must make sure 1 + line < originalCode.length. This is another way to check: + const newCode = (newCodeTop && oldFileBottom) ? `${newCodeTop}\n${oldFileBottom}` : (oldFileBottom || newCodeTop) this._writeText(uri, newCode, { startLineNumber: diffZone.startLine, startColumn: 1, endLineNumber: diffZone.endLine, endColumn: Number.MAX_SAFE_INTEGER, }, // 1-indexed @@ -1128,6 +1130,7 @@ class InlineDiffsService extends Disposable implements IInlineDiffsService { this._refreshStylesAndDiffsInURI(uri) }, onFinalMessage: ({ fullText }) => { + // console.log('DONE! FULL TEXT\n', extractText(fullText), diffZone.startLine, diffZone.endLine) // at the end, re-write whole thing to make sure no sync errors this._writeText(uri, extractText(fullText), { startLineNumber: diffZone.startLine, startColumn: 1, endLineNumber: diffZone.endLine, endColumn: Number.MAX_SAFE_INTEGER }, // 1-indexed From f96d320ce061fff8d9645eca0de0c966c0398fe2 Mon Sep 17 00:00:00 2001 From: Andrew Pareles Date: Mon, 6 Jan 2025 02:02:48 -0800 Subject: [PATCH 18/19] fix tricky reject bug --- .../contrib/void/browser/inlineDiffsService.ts | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/src/vs/workbench/contrib/void/browser/inlineDiffsService.ts b/src/vs/workbench/contrib/void/browser/inlineDiffsService.ts index 05b8c3d0f..2f85ffcd7 100644 --- a/src/vs/workbench/contrib/void/browser/inlineDiffsService.ts +++ b/src/vs/workbench/contrib/void/browser/inlineDiffsService.ts @@ -1298,8 +1298,18 @@ class InlineDiffsService extends Disposable implements IInlineDiffsService { // B| <-- endLine (we want to delete this whole line) // C else if (diff.type === 'insertion') { - writeText = '' - toRange = { startLineNumber: diff.startLine, startColumn: 1, endLineNumber: diff.endLine + 1, endColumn: 1 } // 1-indexed + // console.log('REJECTING:', diff) + // handle the case where the insertion was a newline at end of diffarea (applying to the next line doesnt work because it doesnt exist, vscode just doesnt delete the correct # of newlines) + if (diff.endLine === diffArea.endLine) { + // delete the line before instead of after + writeText = '' + toRange = { startLineNumber: diff.startLine - 1, startColumn: Number.MAX_SAFE_INTEGER, endLineNumber: diff.endLine, endColumn: 1 } // 1-indexed + } + else { + writeText = '' + toRange = { startLineNumber: diff.startLine, startColumn: 1, endLineNumber: diff.endLine + 1, endColumn: 1 } // 1-indexed + } + } // if it was an edit, just edit the range // (this image applies to writeText and toRange, not newOriginalCode) From 4e392bee8ee9bde7fff8bfb03566e621b37cfffb Mon Sep 17 00:00:00 2001 From: Andrew Pareles Date: Mon, 6 Jan 2025 22:25:41 -0800 Subject: [PATCH 19/19] start adding icons for copying files and folders in the explorer --- .../files/browser/views/explorerViewer.ts | 38 ++++++++++++++----- .../files/test/browser/explorerView.test.ts | 7 +++- 2 files changed, 34 insertions(+), 11 deletions(-) diff --git a/src/vs/workbench/contrib/files/browser/views/explorerViewer.ts b/src/vs/workbench/contrib/files/browser/views/explorerViewer.ts index 975f494cb..216cff20c 100644 --- a/src/vs/workbench/contrib/files/browser/views/explorerViewer.ts +++ b/src/vs/workbench/contrib/files/browser/views/explorerViewer.ts @@ -289,6 +289,7 @@ export interface IFileTemplateData { readonly templateDisposables: DisposableStore; readonly elementDisposables: DisposableStore; readonly label: IResourceLabel; + readonly voidLabels: IResourceLabel; readonly container: HTMLElement; readonly contribs: IExplorerFileContribution[]; currentContext?: ExplorerItem; @@ -347,15 +348,24 @@ export class FilesRenderer implements ICompressibleTreeRenderer { + // console.log('ON CLICK', templateData.currentContext?.children) + // }) + const voidLabels = this.labels.create(voidButtonsContainer, { supportHighlights: false, supportIcons: false, }); + voidLabels.element.textContent = 'hi333' + const label = templateDisposables.add(this.labels.create(container, { supportHighlights: true })); templateDisposables.add(label.onDidRender(() => { - try { - if (templateData.currentContext) { - this.updateWidth(templateData.currentContext); - } - } catch (e) { - // noop since the element might no longer be in the tree, no update of width necessary - } + try { if (templateData.currentContext) this.updateWidth(templateData.currentContext); } + catch (e) { /* noop since the element might no longer be in the tree, no update of width necessary*/ } })); const contribs = explorerFileContribRegistry.create(this.instantiationService, container, templateDisposables); @@ -365,10 +375,12 @@ export class FilesRenderer implements ICompressibleTreeRenderer, index: number, templateData: IFileTemplateData): void { const stat = node.element; templateData.currentContext = stat; @@ -382,8 +394,7 @@ export class FilesRenderer implements ICompressibleTreeRenderer c.setResource(undefined)); @@ -477,6 +488,13 @@ export class FilesRenderer implements ICompressibleTreeRenderer { label: { container: label, onDidRender: emitter.event - } + }, + voidLabels: { + container: label, + onDidRender: emitter.event + }, + }, 1, false); ds.add(navigationController);