Skip to content

Commit a63389c

Browse files
committed
Replace diff-based conflict resolution with direct string search and replacement for better reliability and error handling
1 parent 6a65646 commit a63389c

1 file changed

Lines changed: 39 additions & 33 deletions

File tree

‎packages/vscode/src/commands/apply-chat-response-command/handlers/conflict-markers-handler.ts‎

Lines changed: 39 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,11 @@
11
import * as vscode from 'vscode'
22
import * as fs from 'fs'
33
import * as path from 'path'
4-
import { createTwoFilesPatch } from 'diff'
54
import { Logger } from '@shared/utils/logger'
65
import { dictionary } from '@shared/constants/dictionary'
76
import { create_safe_path, sanitize_file_name } from '@/utils/path-sanitizer'
87
import { FileItem } from '../utils/clipboard-parser'
98
import { OriginalFileState } from '../types/original-file-state'
10-
import { apply_diff } from '../utils/diff-processor'
119
import { remove_directory_if_empty } from '../utils/file-operations'
1210

1311
type Segment =
@@ -439,6 +437,7 @@ function apply_conflict_markers_to_content(
439437
): string {
440438
let current_content = original_content
441439
const segments = parse_conflict_segments(markers_content)
440+
let cursor = 0
442441

443442
for (let i = 0; i < segments.length; i++) {
444443
const segment = segments[i]
@@ -449,40 +448,47 @@ function apply_conflict_markers_to_content(
449448
const context_before = prev && prev.type == 'common' ? prev.lines : []
450449
const context_after = next && next.type == 'common' ? next.lines : []
451450

452-
const clean = (lines: string[]) =>
453-
lines.filter((l) => {
454-
const t = l.trim()
455-
return t !== '...' && t !== '…'
456-
})
457-
458-
const before_clean = clean(context_before)
459-
const after_clean = clean(context_after)
460-
461-
const search_text = [
462-
...before_clean,
451+
const search_lines = [
452+
...context_before,
463453
...segment.original_lines,
464-
...after_clean
465-
].join('\n')
466-
const replace_text = [
467-
...before_clean,
454+
...context_after
455+
]
456+
const search_text = search_lines.join('\n')
457+
458+
const replace_lines = [
459+
...context_before,
468460
...segment.updated_lines,
469-
...after_clean
470-
].join('\n')
471-
472-
const patch = createTwoFilesPatch(
473-
'a',
474-
'b',
475-
search_text,
476-
replace_text,
477-
undefined,
478-
undefined,
479-
{ context: Number.MAX_SAFE_INTEGER }
480-
)
461+
...context_after
462+
]
463+
const replace_text = replace_lines.join('\n')
464+
465+
const index = current_content.indexOf(search_text, cursor)
466+
467+
if (index === -1) {
468+
throw new Error(
469+
`Could not find content to replace for conflict marker. Context:\n${search_text.slice(0, 100)}...`
470+
)
471+
}
472+
473+
current_content =
474+
current_content.slice(0, index) +
475+
replace_text +
476+
current_content.slice(index + search_text.length)
477+
478+
// Advance cursor to skip the replaced part, but ensure we are positioned
479+
// to match the 'context_after' which serves as 'context_before' for the next segment.
480+
const unique_replaced_lines = [
481+
...context_before,
482+
...segment.updated_lines
483+
]
484+
const unique_replaced_text = unique_replaced_lines.join('\n')
485+
486+
let advance = unique_replaced_text.length
487+
if (context_after.length > 0 && unique_replaced_lines.length > 0) {
488+
advance += 1 // Account for newline joining unique part and context_after
489+
}
481490

482-
current_content = apply_diff({
483-
original_code: current_content,
484-
diff_patch: patch
485-
})
491+
cursor = index + advance
486492
}
487493
}
488494
return current_content

0 commit comments

Comments
 (0)