1- import React , { useCallback , useMemo , useState } from "react" ;
1+ import React , { useCallback , useMemo } from "react" ;
22import {
33 type CreateTextDocToolCall ,
44 type RawTextDocTool ,
@@ -12,20 +12,16 @@ import {
1212 isUpdateTextDocToolCall ,
1313 parseRawTextDocToolCall ,
1414} from "./types" ;
15- import { Box , Button , Card , Flex } from "@radix-ui/themes" ;
15+ import { Box , Card , Flex } from "@radix-ui/themes" ;
1616import { TruncateLeft } from "../Text" ;
1717import { Link } from "../Link" ;
1818import { useEventsBusForIDE } from "../../hooks/useEventBusForIDE" ;
1919import { Markdown } from "../Markdown" ;
2020import { filename } from "../../utils/filename" ;
2121import styles from "./Texdoc.module.css" ;
22- import { createPatch } from "diff" ;
2322import classNames from "classnames" ;
24- import { useAppSelector } from "../../hooks" ;
25- import { selectCanPaste } from "../../features/Chat" ;
26- import { toolsApi } from "../../services/refact" ;
27- import { ErrorCallout } from "../Callout" ;
28- import { isRTKResponseErrorWithDetailMessage } from "../../utils" ;
23+ import { useCopyToClipboard } from "../../hooks/useCopyToClipboard" ;
24+ import { Reveal } from "../Reveal" ;
2925
3026export const TextDocTool : React . FC < { toolCall : RawTextDocTool } > = ( {
3127 toolCall,
@@ -56,64 +52,14 @@ export const TextDocTool: React.FC<{ toolCall: RawTextDocTool }> = ({
5652const TextDocHeader : React . FC < {
5753 toolCall : TextDocToolCall ;
5854} > = ( { toolCall } ) => {
59- const { openFile, diffPasteBack, sendToolEditToIde } = useEventsBusForIDE ( ) ;
60- const [ requestDryRun , dryRunResult ] = toolsApi . useDryRunForEditToolMutation ( ) ;
61- const [ errorMessage , setErrorMessage ] = useState < string > ( "" ) ;
62- const canPaste = useAppSelector ( selectCanPaste ) ;
55+ const { openFile } = useEventsBusForIDE ( ) ;
6356
64- const clearErrorMessage = useCallback ( ( ) => setErrorMessage ( "" ) , [ ] ) ;
6557 // move this
6658 const handleOpenFile = useCallback ( ( ) => {
6759 if ( ! toolCall . function . arguments . path ) return ;
6860 openFile ( { file_name : toolCall . function . arguments . path } ) ;
6961 } , [ openFile , toolCall . function . arguments . path ] ) ;
7062
71- const handleReplace = useCallback (
72- ( content : string ) => {
73- diffPasteBack ( content ) ;
74- } ,
75- [ diffPasteBack ] ,
76- ) ;
77-
78- const replaceContent = useMemo ( ( ) => {
79- if ( isCreateTextDocToolCall ( toolCall ) )
80- return toolCall . function . arguments . content ;
81- if ( isUpdateTextDocToolCall ( toolCall ) )
82- return toolCall . function . arguments . replacement ;
83- return null ;
84- } , [ toolCall ] ) ;
85-
86- const handleApplyToolResult = useCallback ( ( ) => {
87- requestDryRun ( {
88- toolName : toolCall . function . name ,
89- toolArgs : toolCall . function . arguments ,
90- } )
91- . then ( ( results ) => {
92- if ( results . data ) {
93- sendToolEditToIde ( toolCall . function . arguments . path , results . data ) ;
94- } else if ( isRTKResponseErrorWithDetailMessage ( results ) ) {
95- setErrorMessage ( results . error . data . detail ) ;
96- }
97- } )
98- . catch ( ( error : unknown ) => {
99- if (
100- error &&
101- typeof error === "object" &&
102- "message" in error &&
103- typeof error . message === "string"
104- ) {
105- setErrorMessage ( error . message ) ;
106- } else {
107- setErrorMessage ( "Error with patch: " + JSON . stringify ( error ) ) ;
108- }
109- } ) ;
110- } , [
111- requestDryRun ,
112- sendToolEditToIde ,
113- toolCall . function . arguments ,
114- toolCall . function . name ,
115- ] ) ;
116-
11763 return (
11864 < Card size = "1" variant = "surface" mt = "4" className = { styles . textdoc__header } >
11965 < Flex gap = "2" py = "2" pl = "2" justify = "between" >
@@ -128,31 +74,7 @@ const TextDocHeader: React.FC<{
12874 { toolCall . function . arguments . path }
12975 </ Link >
13076 </ TruncateLeft > { " " }
131- < div style = { { flexGrow : 1 } } />
132- < Button
133- size = "1"
134- onClick = { handleApplyToolResult }
135- disabled = { dryRunResult . isLoading }
136- title = { `Apply` }
137- >
138- ➕ Apply
139- </ Button >
140- { replaceContent && (
141- < Button
142- size = "1"
143- onClick = { ( ) => handleReplace ( replaceContent ) }
144- disabled = { dryRunResult . isLoading || ! canPaste }
145- title = "Replace the current selection in the ide."
146- >
147- ➕ Replace Selection
148- </ Button >
149- ) }
15077 </ Flex >
151- { errorMessage && (
152- < ErrorCallout onClick = { clearErrorMessage } timeout = { 5000 } >
153- { errorMessage }
154- </ ErrorCallout >
155- ) }
15678 </ Card >
15779 ) ;
15880} ;
@@ -166,11 +88,17 @@ const CreateTextDoc: React.FC<{
16688 "```" + extension + "\n" + toolCall . function . arguments . content + "\n```"
16789 ) ;
16890 } , [ toolCall . function . arguments . content , toolCall . function . arguments . path ] ) ;
91+ const handleCopy = useCopyToClipboard ( ) ;
92+
93+ const lineCount = useMemo ( ( ) => code . split ( "\n" ) . length , [ code ] ) ;
94+
16995 return (
17096 // TODO: move this box up a bit, or make it generic
17197 < Box className = { styles . textdoc } >
17298 < TextDocHeader toolCall = { toolCall } />
173- < Markdown > { code } </ Markdown >
99+ < Reveal isRevealingCode defaultOpen = { lineCount < 9 } >
100+ < Markdown onCopyClick = { handleCopy } > { code } </ Markdown >
101+ </ Reveal >
174102 </ Box >
175103 ) ;
176104} ;
@@ -191,11 +119,20 @@ const ReplaceTextDoc: React.FC<{
191119 toolCall . function . arguments . path ,
192120 toolCall . function . arguments . replacement ,
193121 ] ) ;
122+
123+ const copyToClipBoard = useCopyToClipboard ( ) ;
124+ const handleCopy = useCallback ( ( ) => {
125+ copyToClipBoard ( toolCall . function . arguments . replacement ) ;
126+ } , [ copyToClipBoard , toolCall . function . arguments . replacement ] ) ;
127+
128+ const lineCount = useMemo ( ( ) => code . split ( "\n" ) . length , [ code ] ) ;
194129 return (
195130 // TODO: move this box up a bit, or make it generic
196131 < Box className = { styles . textdoc } >
197132 < TextDocHeader toolCall = { toolCall } />
198- < Markdown > { code } </ Markdown >
133+ < Reveal isRevealingCode defaultOpen = { lineCount < 9 } >
134+ < Markdown onCopyClick = { handleCopy } > { code } </ Markdown >
135+ </ Reveal >
199136 </ Box >
200137 ) ;
201138} ;
@@ -219,37 +156,43 @@ const UpdateRegexTextDoc: React.FC<{
219156 toolCall . function . arguments . replacement ,
220157 ] ) ;
221158
159+ const lineCount = useMemo ( ( ) => code . split ( "\n" ) . length , [ code ] ) ;
160+
222161 return (
223162 < Box className = { styles . textdoc } >
224163 < TextDocHeader toolCall = { toolCall } />
225- < Markdown > { code } </ Markdown >
164+ < Reveal isRevealingCode defaultOpen = { lineCount < 9 } >
165+ < Markdown > { code } </ Markdown >
166+ </ Reveal >
226167 </ Box >
227168 ) ;
228169} ;
229170
230171const UpdateTextDoc : React . FC < {
231172 toolCall : UpdateTextDocToolCall ;
232173} > = ( { toolCall } ) => {
233- const diff = useMemo ( ( ) => {
234- const patch = createPatch (
235- toolCall . function . arguments . path ,
236- toolCall . function . arguments . old_str ,
237- toolCall . function . arguments . replacement ,
174+ const code = useMemo ( ( ) => {
175+ const extension = getFileExtension ( toolCall . function . arguments . path ) ;
176+ return (
177+ "```" +
178+ extension +
179+ "\n" +
180+ toolCall . function . arguments . replacement +
181+ "\n```"
238182 ) ;
239-
240- return "```diff\n" + patch + "\n```" ;
241183 } , [
242- toolCall . function . arguments . replacement ,
243- toolCall . function . arguments . old_str ,
244184 toolCall . function . arguments . path ,
185+ toolCall . function . arguments . replacement ,
245186 ] ) ;
246- // TODO: don't use markdown for this, it's two bright
187+
188+ const lineCount = useMemo ( ( ) => code . split ( "\n" ) . length , [ code ] ) ;
189+
247190 return (
248191 < Box className = { classNames ( styles . textdoc , styles . textdoc__update ) } >
249192 < TextDocHeader toolCall = { toolCall } />
250- < Box className = { classNames ( styles . textdoc__diffbox ) } >
251- < Markdown useInlineStyles = { false } > { diff } </ Markdown >
252- </ Box >
193+ < Reveal isRevealingCode defaultOpen = { lineCount < 9 } >
194+ < Markdown useInlineStyles = { false } > { code } </ Markdown >
195+ </ Reveal >
253196 </ Box >
254197 ) ;
255198} ;
0 commit comments