@@ -8,6 +8,9 @@ import { getLogger } from '../../shared/logger/logger'
88import vscode from 'vscode'
99import { fs } from '../../shared/fs/fs'
1010import { Writable } from 'stream'
11+ import { Change , diffLines } from 'diff'
12+ import { getDiffMarkdown } from '../../shared/utilities/diffUtils'
13+ import { getLanguageForFilePath } from '../../shared/utilities/textDocumentUtilities'
1114
1215interface BaseParams {
1316 path : string
@@ -69,114 +72,40 @@ export class FsWrite {
6972 }
7073 }
7174
72- // TODO: Refactor the fsWrite.ts file "queueDescription" method to use existing diffLines and diff library to get the diff preview. or reuse existing diff view logic in cwchat. This will be part of next PR.
73- private showStrReplacePreview ( oldStr : string , newStr : string ) : string {
74- // Split both strings into arrays of lines
75- const oldStrLines = oldStr . split ( '\n' )
76- const newStrLines = newStr . split ( '\n' )
77- let result = ''
78-
79- // If strings are identical, return empty string
80- if ( oldStr === newStr ) {
81- return result
82- }
83-
84- let oldLineIndex = 0
85- let newLineIndex = 0
86- // Loop through both arrays until we've processed all lines
87- while ( oldLineIndex < oldStrLines . length || newLineIndex < newStrLines . length ) {
88- if (
89- oldLineIndex < oldStrLines . length &&
90- newLineIndex < newStrLines . length &&
91- oldStrLines [ oldLineIndex ] === newStrLines [ newLineIndex ]
92- ) {
93- // Line is unchanged - prefix with space
94- result += ` ${ oldStrLines [ oldLineIndex ] } \n`
95- oldLineIndex ++
96- newLineIndex ++
97- } else {
98- // Line is different
99- if ( oldLineIndex < oldStrLines . length ) {
100- // Remove line - prefix with minus
101- result += `- ${ oldStrLines [ oldLineIndex ] } \n`
102- oldLineIndex ++
103- }
104- if ( newLineIndex < newStrLines . length ) {
105- // Add line - prefix with plus
106- result += `+ ${ newStrLines [ newLineIndex ] } \n`
107- newLineIndex ++
108- }
109- }
110- }
111-
112- return result
113- }
114-
115- private async showInsertPreview ( path : string , insertLine : number , newStr : string ) : Promise < string > {
116- const fileContent = await fs . readFileText ( path )
117- const lines = fileContent . split ( '\n' )
118- const startLine = Math . max ( 0 , insertLine - 2 )
119- const endLine = Math . min ( lines . length , insertLine + 3 )
120-
121- const contextLines : string [ ] = [ ]
122-
123- // Add lines before insertion point
124- for ( let index = startLine ; index < insertLine ; index ++ ) {
125- contextLines . push ( ` ${ lines [ index ] } ` )
126- }
127-
128- // Add the new line with a '+' prefix
129- contextLines . push ( `+ ${ newStr } ` )
130-
131- // Add lines after insertion point
132- for ( let index = insertLine ; index < endLine ; index ++ ) {
133- contextLines . push ( ` ${ lines [ index ] } ` )
134- }
75+ public async queueDescription ( updates : Writable ) : Promise < void > {
76+ const sanitizedPath = sanitizePath ( this . params . path )
77+ const changes = await this . getDiffChanges ( )
78+ const language = await getLanguageForFilePath ( sanitizedPath )
13579
136- return contextLines . join ( '\n' )
80+ const diff = getDiffMarkdown ( changes , language )
81+ updates . write ( diff )
82+ updates . end ( )
13783 }
13884
139- private async showAppendPreview ( sanitizedPath : string , newStr : string ) {
140- const fileContent = await fs . readFileText ( sanitizedPath )
141- const needsNewline = fileContent . length !== 0 && ! fileContent . endsWith ( '\n' )
142-
143- let contentToAppend = newStr
144- if ( needsNewline ) {
145- contentToAppend = '\n' + contentToAppend
85+ public async getDiffChanges ( ) : Promise < Change [ ] > {
86+ const sanitizedPath = sanitizePath ( this . params . path )
87+ let newContent
88+ let oldContent
89+ try {
90+ oldContent = await fs . readFileText ( sanitizedPath )
91+ } catch ( err ) {
92+ oldContent = ''
14693 }
147-
148- // Get the last 3 lines from existing content for better UX
149- const lines = fileContent . split ( '\n' )
150- const linesForContext = lines . slice ( - 3 )
151-
152- return `${ linesForContext . join ( '\n' ) } \n+ ${ contentToAppend . trim ( ) } `
153- }
154-
155- public async queueDescription ( updates : Writable ) : Promise < void > {
15694 switch ( this . params . command ) {
15795 case 'create' :
158- updates . write ( `\`\`\`diff-typescript
159- ${ '+' + this . params . fileText ?. replace ( / \n / g, '\n+' ) }
160- ` )
96+ newContent = this . getCreateCommandText ( this . params )
16197 break
16298 case 'strReplace' :
163- updates . write ( `\`\`\`diff-typescript
164- ${ this . showStrReplacePreview ( this . params . oldStr , this . params . newStr ) }
165- \`\`\`
166- ` )
99+ newContent = await this . getStrReplaceContent ( this . params , sanitizedPath )
167100 break
168101 case 'insert' :
169- updates . write ( `\`\`\`diff-typescript
170- ${ await this . showInsertPreview ( this . params . path , this . params . insertLine , this . params . newStr ) }
171- \`\`\`` )
102+ newContent = await this . getInsertContent ( this . params , sanitizedPath )
172103 break
173104 case 'append' :
174- updates . write ( `\`\`\`diff-typescript
175- ${ await this . showAppendPreview ( this . params . path , this . params . newStr ) }
176- \`\`\`` )
105+ newContent = await this . getAppendContent ( this . params , sanitizedPath )
177106 break
178107 }
179- updates . end ( )
108+ return diffLines ( oldContent , newContent )
180109 }
181110
182111 public async validate ( ) : Promise < void > {
@@ -224,6 +153,11 @@ ${await this.showAppendPreview(this.params.path, this.params.newStr)}
224153 }
225154
226155 private async handleStrReplace ( params : StrReplaceParams , sanitizedPath : string ) : Promise < void > {
156+ const newContent = await this . getStrReplaceContent ( params , sanitizedPath )
157+ await fs . writeFile ( sanitizedPath , newContent )
158+ }
159+
160+ private async getStrReplaceContent ( params : StrReplaceParams , sanitizedPath : string ) : Promise < string > {
227161 const fileContent = await fs . readFileText ( sanitizedPath )
228162
229163 const matches = [ ...fileContent . matchAll ( new RegExp ( this . escapeRegExp ( params . oldStr ) , 'g' ) ) ]
@@ -235,11 +169,15 @@ ${await this.showAppendPreview(this.params.path, this.params.newStr)}
235169 throw new Error ( `${ matches . length } occurrences of oldStr were found when only 1 is expected` )
236170 }
237171
238- const newContent = fileContent . replace ( params . oldStr , params . newStr )
239- await fs . writeFile ( sanitizedPath , newContent )
172+ return fileContent . replace ( params . oldStr , params . newStr )
240173 }
241174
242175 private async handleInsert ( params : InsertParams , sanitizedPath : string ) : Promise < void > {
176+ const newContent = await this . getInsertContent ( params , sanitizedPath )
177+ await fs . writeFile ( sanitizedPath , newContent )
178+ }
179+
180+ private async getInsertContent ( params : InsertParams , sanitizedPath : string ) : Promise < string > {
243181 const fileContent = await fs . readFileText ( sanitizedPath )
244182 const lines = fileContent . split ( '\n' )
245183
@@ -252,11 +190,15 @@ ${await this.showAppendPreview(this.params.path, this.params.newStr)}
252190 } else {
253191 newContent = [ ...lines . slice ( 0 , insertLine ) , params . newStr , ...lines . slice ( insertLine ) ] . join ( '\n' )
254192 }
193+ return newContent
194+ }
255195
196+ private async handleAppend ( params : AppendParams , sanitizedPath : string ) : Promise < void > {
197+ const newContent = await this . getAppendContent ( params , sanitizedPath )
256198 await fs . writeFile ( sanitizedPath , newContent )
257199 }
258200
259- private async handleAppend ( params : AppendParams , sanitizedPath : string ) : Promise < void > {
201+ private async getAppendContent ( params : AppendParams , sanitizedPath : string ) : Promise < string > {
260202 const fileContent = await fs . readFileText ( sanitizedPath )
261203 const needsNewline = fileContent . length !== 0 && ! fileContent . endsWith ( '\n' )
262204
@@ -265,8 +207,7 @@ ${await this.showAppendPreview(this.params.path, this.params.newStr)}
265207 contentToAppend = '\n' + contentToAppend
266208 }
267209
268- const newContent = fileContent + contentToAppend
269- await fs . writeFile ( sanitizedPath , newContent )
210+ return fileContent + contentToAppend
270211 }
271212
272213 private getCreateCommandText ( params : CreateParams ) : string {
0 commit comments