diff --git a/src/vs/workbench/contrib/void/browser/react/src/markdown/ApplyBlockHoverButtons.tsx b/src/vs/workbench/contrib/void/browser/react/src/markdown/ApplyBlockHoverButtons.tsx index f412c1af..9e54b85d 100644 --- a/src/vs/workbench/contrib/void/browser/react/src/markdown/ApplyBlockHoverButtons.tsx +++ b/src/vs/workbench/contrib/void/browser/react/src/markdown/ApplyBlockHoverButtons.tsx @@ -10,7 +10,7 @@ import { isFeatureNameDisabled } from '../../../../common/voidSettingsTypes.js' import { URI } from '../../../../../../../base/common/uri.js' import { FileSymlink, LucideIcon, RotateCw, Terminal } from 'lucide-react' import { Check, X, Square, Copy, Play, } from 'lucide-react' -import { getBasename, ListableToolItem, ToolChildrenWrapper } from '../sidebar-tsx/SidebarChat.js' +import { getBasename, ListableToolItem, voidOpenFileFn, ToolChildrenWrapper } from '../sidebar-tsx/SidebarChat.js' import { PlacesType, VariantType } from 'react-tooltip' enum CopyButtonText { @@ -109,7 +109,7 @@ export const JumpToFileButton = ({ uri, ...props }: { uri: URI | 'current' } & R { - commandService.executeCommand('vscode.open', uri, { preview: true }) + voidOpenFileFn(uri, accessor) }} {...tooltipPropsForApplyBlock({ tooltipName: 'Go to file' })} {...props} @@ -441,7 +441,7 @@ export const BlockCodeApplyWrapper = ({ name={{getBasename(uri.fsPath)}} isSmall={true} showDot={false} - onClick={() => { commandService.executeCommand('vscode.open', uri, { preview: true }) }} + onClick={() => { voidOpenFileFn(uri, accessor) }} /> : {language} 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 3f6a9882..ede1708b 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 @@ -9,12 +9,12 @@ import { marked, MarkedToken, Token } from 'marked' import { convertToVscodeLang, detectLanguage } from '../../../../common/helpers/languageHelpers.js' import { BlockCodeApplyWrapper } from './ApplyBlockHoverButtons.js' import { useAccessor } from '../util/services.js' -import { ScrollType } from '../../../../../../../editor/common/editorCommon.js' import { URI } from '../../../../../../../base/common/uri.js' import { isAbsolute } from '../../../../../../../base/common/path.js' import { separateOutFirstLine } from '../../../../common/helpers/util.js' import { BlockCode } from '../util/inputs.js' import { CodespanLocationLink } from '../../../../common/chatThreadServiceTypes.js' +import { voidOpenFileFn } from '../sidebar-tsx/SidebarChat.js' export type ChatMessageLocation = { @@ -134,27 +134,10 @@ const CodespanWithLink = ({ text, rawText, chatMessageLocation }: { text: string const onClick = () => { - if (!link) return; - const selection = link.selection - - // open the file - commandService.executeCommand('vscode.open', link.uri).then(() => { - - // select the text - setTimeout(() => { - if (!selection) return; - - const editor = editorService.getActiveCodeEditor() - if (!editor) return; - - editor.setSelection(selection) - editor.revealRange(selection, ScrollType.Immediate) - - }, 50) // needed when document was just opened and needs to initialize - - }) + // Use the updated voidOpenFileFn to open the file and handle selection + voidOpenFileFn(link.uri, accessor, { selection: link.selection, }); } return { } + +// Open file utility function +export const voidOpenFileFn = ( + uri: URI, + accessor: ReturnType, + options?: { selection?: { startLineNumber: number; startColumn: number; endLineNumber: number; endColumn: number }, } +) => { + const commandService = accessor.get('ICommandService') + const editorService = accessor.get('ICodeEditorService') + + const selection = options?.selection + + // open the file + commandService.executeCommand('vscode.open', uri).then(() => { + + // select the text + setTimeout(() => { + if (!selection) return; + + const editor = editorService.getActiveCodeEditor() + if (!editor) return; + + editor.setSelection(selection) + editor.revealRange(selection, ScrollType.Immediate) + + }, 50) // needed when document was just opened and needs to initialize + + }) + +}; + + export const SelectedFiles = ( { type, selections, setSelections, showProspectiveSelections, messageIdx, }: | { type: 'past', selections: StagingSelectionItem[]; setSelections?: undefined, showProspectiveSelections?: undefined, messageIdx: number, } @@ -641,10 +675,7 @@ export const SelectedFiles = ( } else if (selection.type === 'File') { // open files - commandService.executeCommand('vscode.open', selection.uri, { - preview: true, - // preserveFocus: false, - }); + voidOpenFileFn(selection.uri, accessor); const wasAddedAsCurrentFile = selection.state.wasAddedAsCurrentFile if (wasAddedAsCurrentFile) { @@ -658,10 +689,7 @@ export const SelectedFiles = ( } } else if (selection.type === 'CodeSelection') { - commandService.executeCommand('vscode.open', selection.uri, { - preview: true, - // TODO!!! open in range - }); + voidOpenFileFn(selection.uri, accessor); } else if (selection.type === 'Folder') { // TODO!!! reveal in tree @@ -714,6 +742,7 @@ type ToolHeaderParams = { icon?: React.ReactNode; title: React.ReactNode; desc1: React.ReactNode; + desc1OnClick?: () => void; desc2?: React.ReactNode; isError?: boolean; info?: string; @@ -733,6 +762,7 @@ const ToolHeaderWrapper = ({ icon, title, desc1, + desc1OnClick, desc1Info, desc2, numResults, @@ -754,37 +784,51 @@ const ToolHeaderWrapper = ({ const isDropdown = children !== undefined // null ALLOWS dropdown const isClickable = !!(isDropdown || onClick) + const isDesc1Clickable = !!desc1OnClick + + const desc1HTML = {desc1} + return (
{/* header */}
{/* left */} -
+ {/* title eg "> Edited File" */} +
{ - if (isDropdown) { setIsOpen(v => !v); } - if (onClick) { onClick(); } - }} - > - {isDropdown && ( { + if (isDropdown) { setIsOpen(v => !v); } + if (onClick) { onClick(); } + }} + > + {isDropdown && ()} - {title} - {desc1} + />)} + {title} + + {!isDesc1Clickable && desc1HTML} +
+ {isDesc1Clickable && desc1HTML}
{/* right */} @@ -850,7 +894,8 @@ const EditTool = ({ toolMessage, threadId, messageIdx, content }: Parameters voidOpenFileFn(params.uri, accessor) + const componentParams: ToolHeaderParams = { title, desc1, desc1OnClick, desc1Info, isError, icon, isRejected, } if (toolMessage.type === 'running_now' || toolMessage.type === 'tool_request') { componentParams.children = @@ -859,7 +904,7 @@ const EditTool = ({ toolMessage, threadId, messageIdx, content }: Parameters - componentParams.desc2 = + // JumpToFileButton removed in favor of FileLinkText } else if (toolMessage.type === 'success' || toolMessage.type === 'rejected' || toolMessage.type === 'tool_error') { // add apply box @@ -1365,12 +1410,12 @@ const getTitle = (toolMessage: Pick): { - desc1: string, + desc1: React.ReactNode, desc1Info?: string, } => { if (!_toolParams) { - return { desc1: '' }; + return { desc1: '', }; } const x = { @@ -1790,7 +1835,7 @@ const toolNameToComponent: { [T in ToolName]: { resultWrapper: ResultWrapper, if (toolMessage.type === 'success') { const { result } = toolMessage - componentParams.onClick = () => { commandService.executeCommand('vscode.open', params.uri, { preview: true }) } + componentParams.onClick = () => { voidOpenFileFn(params.uri, accessor) } if (result.hasNextPage && params.pageNumber === 1) // first page componentParams.desc2 = `(truncated after ${Math.round(MAX_FILE_CHARS_PAGE) / 1000}k)` else if (params.pageNumber > 1) // subsequent pages @@ -1798,7 +1843,7 @@ const toolNameToComponent: { [T in ToolName]: { resultWrapper: ResultWrapper, } else if (toolMessage.type === 'tool_error') { const { result } = toolMessage - componentParams.desc2 = + // JumpToFileButton removed in favor of FileLinkText componentParams.bottomChildren = {result} @@ -1889,7 +1934,7 @@ const toolNameToComponent: { [T in ToolName]: { resultWrapper: ResultWrapper, name={`${child.name}${child.isDirectory ? '/' : ''}`} className='w-full overflow-auto' onClick={() => { - commandService.executeCommand('vscode.open', child.uri, { preview: true }) + voidOpenFileFn(child.uri, accessor) // commandService.executeCommand('workbench.view.explorer'); // open in explorer folders view instead // explorerService.select(child.uri, true); }} @@ -1940,7 +1985,7 @@ const toolNameToComponent: { [T in ToolName]: { resultWrapper: ResultWrapper, {result.uris.map((uri, i) => ( { commandService.executeCommand('vscode.open', uri, { preview: true }) }} + onClick={() => { voidOpenFileFn(uri, accessor) }} />))} {result.hasNextPage && @@ -1995,7 +2040,7 @@ const toolNameToComponent: { [T in ToolName]: { resultWrapper: ResultWrapper, {result.uris.map((uri, i) => ( { commandService.executeCommand('vscode.open', uri, { preview: true }) }} + onClick={() => { voidOpenFileFn(uri, accessor) }} />))} {result.hasNextPage && @@ -2085,7 +2130,7 @@ const toolNameToComponent: { [T in ToolName]: { resultWrapper: ResultWrapper, if (toolMessage.type === 'success') { const { result } = toolMessage - componentParams.onClick = () => { commandService.executeCommand('vscode.open', params.uri, { preview: true }) } + componentParams.onClick = () => { voidOpenFileFn(params.uri, accessor) } if (result.lintErrors) componentParams.children = else @@ -2094,7 +2139,7 @@ const toolNameToComponent: { [T in ToolName]: { resultWrapper: ResultWrapper, } else if (toolMessage.type === 'tool_error') { const { result } = toolMessage - if (params) componentParams.desc2 = + // JumpToFileButton removed in favor of FileLinkText componentParams.bottomChildren = {result} @@ -2126,14 +2171,14 @@ const toolNameToComponent: { [T in ToolName]: { resultWrapper: ResultWrapper, if (toolMessage.type === 'success') { const { result } = toolMessage - componentParams.onClick = () => { commandService.executeCommand('vscode.open', params.uri, { preview: true }) } + componentParams.onClick = () => { voidOpenFileFn(params.uri, accessor) } } else if (toolMessage.type === 'rejected') { - componentParams.onClick = () => { commandService.executeCommand('vscode.open', params.uri, { preview: true }) } + componentParams.onClick = () => { voidOpenFileFn(params.uri, accessor) } } else if (toolMessage.type === 'tool_error') { const { result } = toolMessage - if (params) { componentParams.onClick = () => { commandService.executeCommand('vscode.open', params.uri, { preview: true }) } } + if (params) { componentParams.onClick = () => { voidOpenFileFn(params.uri, accessor) } } componentParams.bottomChildren = {result} @@ -2168,14 +2213,14 @@ const toolNameToComponent: { [T in ToolName]: { resultWrapper: ResultWrapper, if (toolMessage.type === 'success') { const { result } = toolMessage - componentParams.onClick = () => { commandService.executeCommand('vscode.open', params.uri, { preview: true }) } + componentParams.onClick = () => { voidOpenFileFn(params.uri, accessor) } } else if (toolMessage.type === 'rejected') { - componentParams.onClick = () => { commandService.executeCommand('vscode.open', params.uri, { preview: true }) } + componentParams.onClick = () => { voidOpenFileFn(params.uri, accessor) } } else if (toolMessage.type === 'tool_error') { const { result } = toolMessage - if (params) { componentParams.onClick = () => { commandService.executeCommand('vscode.open', params.uri, { preview: true }) } } + if (params) { componentParams.onClick = () => { voidOpenFileFn(params.uri, accessor) } } componentParams.bottomChildren = {result} @@ -2184,11 +2229,11 @@ const toolNameToComponent: { [T in ToolName]: { resultWrapper: ResultWrapper, } else if (toolMessage.type === 'running_now') { const { result } = toolMessage - componentParams.onClick = () => { commandService.executeCommand('vscode.open', params.uri, { preview: true }) } + componentParams.onClick = () => { voidOpenFileFn(params.uri, accessor) } } else if (toolMessage.type === 'tool_request') { const { result } = toolMessage - componentParams.onClick = () => { commandService.executeCommand('vscode.open', params.uri, { preview: true }) } + componentParams.onClick = () => { voidOpenFileFn(params.uri, accessor) } } return @@ -2558,7 +2603,7 @@ const CommandBarInChat = () => { const fileNameHTML =
commandService.executeCommand('vscode.open', uri, { preview: true })} + onClick={() => voidOpenFileFn(uri, accessor)} > {/* */} {basename} @@ -2683,6 +2728,9 @@ const CommandBarInChat = () => { const EditToolSoFar = ({ toolCallSoFar, }: { toolCallSoFar: RawToolCallObj }) => { + + const accessor = useAccessor() + const uri = toolCallSoFar.rawParams.uri ? URI.file(toolCallSoFar.rawParams.uri) : undefined const title = titleOfToolName[toolCallSoFar.name].proposed @@ -2695,11 +2743,13 @@ const EditToolSoFar = ({ toolCallSoFar, }: { toolCallSoFar: RawToolCallObj }) => + const desc1OnClick = () => { uri && voidOpenFileFn(uri, accessor) } + // If URI has not been specified return } + desc1OnClick={desc1OnClick} >