@@ -312,13 +312,18 @@ const apply_diff_patch = (
312312 replace_chunks . pop ( )
313313 }
314314
315- // Add the final search block to the searchReplaceBlocks
316- // This is crucial for diffs that only have deletions
317- search_replace_blocks . push (
318- new SearchBlock ( search_chunks , replace_chunks , - 1 )
319- )
315+ if ( search_chunks . length != 0 || replace_chunks . length != 0 ) // Don't add search or replace blocks if empty
316+ {
317+ // Add the final search block to the searchReplaceBlocks
318+ // This is crucial for diffs that only have deletions
319+ search_replace_blocks . push (
320+ new SearchBlock ( search_chunks , replace_chunks , - 1 )
321+ )
322+ }
320323 }
321324
325+ //print_debug(original_code_lines, original_code_lines_normalized, patch_lines_normalized, search_replace_blocks);
326+
322327 // === Work through search and replace blocks finding start of search block ===
323328 let previous_found_index = 0
324329 for ( let i = 0 ; i < search_replace_blocks . length ; i ++ ) {
@@ -346,28 +351,53 @@ const apply_diff_patch = (
346351
347352 // console.log('Chunk string: ' + chunk_string);
348353
349- // Check if the chunk matches the search string
350- if ( chunk_string == search_string ) {
351- // Check if found index is greater than the previous found index
352- if ( previous_found_index >= chunk [ 0 ] . key ) {
353- // This should never happen
354- throw new Error ( 'Found index is less than previous found index' )
355- }
356-
357- // Store the index of the first line of the search block
358- search_replace_block . search_block_start_index = chunk [ 0 ] . key
354+ // If we have no search lines and only replace lines and our previous found index is 0
355+ // assume we are at the start of the file and set the search block start index to 0
356+ // This is a special case when a patch hunk starts with one or more + lines and no context lines
357+ if ( search_replace_block . search_lines . length == 0 && previous_found_index == 0 )
358+ {
359+ search_replace_block . search_block_start_index = - 1 // insert at the start of the file
359360 found = true
360-
361- previous_found_index = chunk [ 0 ] . key // Update the previous index
362-
363- //console.log('Found search block at line ' + chunk[0].key);
364- break
361+ }
362+ else
363+ {
364+ // Create a chunk of lines from originalCodeLinesNormalized
365+ const chunk = original_code_lines_normalized . slice (
366+ j ,
367+ j + search_replace_block . search_lines . length
368+ )
369+
370+ const chunk_string = chunk . map ( ( line ) => line . value ) . join ( '' )
371+
372+ //console.log('Chunk string: ' + chunk_string);
373+ //console.log('Previous found index: ' + previous_found_index);
374+ //console.log('Chunk: ' + JSON.stringify(chunk, null, 2));
375+
376+ // Check if the chunk matches the search string
377+ if ( chunk_string == search_string ) {
378+ // Check if found index is greater than the previous found index
379+ if ( previous_found_index > chunk [ 0 ] . key ) {
380+ // This should never happen
381+ throw new Error ( 'Found index is less than previous found index' )
382+ }
383+
384+ // Store the index of the first line of the search block
385+ search_replace_block . search_block_start_index = chunk [ 0 ] . key
386+ found = true
387+
388+ previous_found_index = chunk [ 0 ] . key // Update the previous index
389+
390+ //console.log('Found search block at line ' + chunk[0].key);
391+ break
392+ }
365393 }
366394 }
367395
368- // If not found, set the search_block_start_index to -1
396+ // If not found, set the search_block_start_index to -2
369397 if ( ! found ) {
370- const error_message = `Search block not found: ${ search_string } `
398+ search_replace_block . search_block_start_index = - 2 // Not found
399+
400+ const error_message = `Search block not found: ${ search_string } `
371401 Logger . error ( {
372402 function_name : 'apply_diff_patch' ,
373403 message : error_message
@@ -386,7 +416,7 @@ const apply_diff_patch = (
386416 // === Apply the search and replace blocks ===
387417 // Get all blocks with a valid start index
388418 const valid_blocks = search_replace_blocks . filter (
389- ( block ) => block . get_start_index ( ) !== - 1
419+ ( block ) => block . get_start_index ( ) !== - 2
390420 )
391421
392422 // Sort blocks by descending index
@@ -396,7 +426,7 @@ const apply_diff_patch = (
396426
397427 // Iterrate over the valid blocks and apply them
398428 for ( const block of valid_blocks ) {
399- const start_index = block . get_start_index ( )
429+ const start_index = block . get_start_index ( ) == - 1 ? 0 : block . get_start_index ( ) // When -1, insert at the start of the file
400430 const search_count = block . get_search_count ( )
401431 const replacement_content = block . replace_lines // These are original lines
402432
0 commit comments