Skip to content

Commit bda1944

Browse files
committed
Enable diff parsing to use file paths specified in preceding XML file tags when processing subsequent raw diff code blocks
1 parent 4013f07 commit bda1944

4 files changed

Lines changed: 70 additions & 3 deletions

File tree

‎packages/vscode/src/commands/apply-chat-response-command/utils/clipboard-parser/clipboard-parser.spec.ts‎

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -974,6 +974,23 @@ describe('clipboard-parser', () => {
974974
)
975975
})
976976

977+
it('parses a diff patch where the file path is specified using an XML tag preceding the diff block', () => {
978+
const test_case = 'diff-with-xml-file-path'
979+
const text = load_test_case_file(test_case, `${test_case}.txt`)
980+
const result = parse_response({
981+
response: text,
982+
is_single_root_folder_workspace: true
983+
})
984+
985+
expect(result.type).toBe('patches')
986+
expect(result.patches).toHaveLength(1)
987+
988+
expect(result.patches![0].file_path).toBe('src/index.ts')
989+
expect(result.patches![0].content).toBe(
990+
load_test_case_file(test_case, 'file-1.txt')
991+
)
992+
})
993+
977994
it('parses diff correctly when content contains nested backticks', () => {
978995
const test_case = 'diff-inner-backticks'
979996
const text = load_test_case_file(test_case, `${test_case}.txt`)

‎packages/vscode/src/commands/apply-chat-response-command/utils/clipboard-parser/extract-diff-patches/extract-diffs.ts‎

Lines changed: 42 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -337,9 +337,31 @@ const extract_all_code_block_patches = (params: {
337337
const files_with_diffs = new Set<string>()
338338
const diff_block_patches = new Map<number, Diff[]>()
339339

340-
for (const block of code_blocks) {
341-
if (block.type === 'diff' || block.type === 'patch') {
340+
for (let i = 0; i < code_blocks.length; i++) {
341+
const block = code_blocks[i]
342+
if (block.type == 'diff' || block.type == 'patch') {
343+
let file_path_hint: string | undefined
344+
if (i > 0) {
345+
const prev_block_lines = lines.slice(
346+
code_blocks[i - 1].start + 1,
347+
code_blocks[i - 1].end
348+
)
349+
const xml_path_regex = /<file\s+path=["']([^"']+)["']/
350+
const non_empty_lines = prev_block_lines.filter((l) => l.trim() != '')
351+
if (non_empty_lines.length === 1) {
352+
const match = non_empty_lines[0].match(xml_path_regex)
353+
if (match && match[1]) {
354+
file_path_hint = match[1]
355+
}
356+
}
357+
}
342358
const block_lines = lines.slice(block.start + 1, block.end)
359+
if (file_path_hint) {
360+
const { from_path, to_path } = extract_paths_from_lines(block_lines)
361+
if (!from_path && !to_path) {
362+
block_lines.unshift(`--- /dev/null`, `+++ b/${file_path_hint}`)
363+
}
364+
}
343365
const parsed_patches = parse_multiple_raw_patches({
344366
all_lines: block_lines,
345367
is_single_root: params.is_single_root
@@ -355,11 +377,28 @@ const extract_all_code_block_patches = (params: {
355377
}
356378

357379
// Process each found code block in order of appearance.
358-
for (const block of code_blocks) {
380+
for (let i = 0; i < code_blocks.length; i++) {
381+
const block = code_blocks[i]
359382
const block_lines = lines.slice(block.start + 1, block.end) // Exclude the ``` lines
360383
if (block.type == 'diff' || block.type == 'patch') {
361384
patches.push(...(diff_block_patches.get(block.start) || []))
362385
} else {
386+
// Check if this block was a hint for the next block.
387+
if (i < code_blocks.length - 1) {
388+
const next_block = code_blocks[i + 1]
389+
if (next_block.type === 'diff' || next_block.type === 'patch') {
390+
const xml_path_regex = /<file\s+path=["']([^"']+)["']/
391+
const non_empty_lines = block_lines.filter((l) => l.trim() !== '')
392+
if (non_empty_lines.length === 1) {
393+
const match = non_empty_lines[0].match(xml_path_regex)
394+
if (match && match[1]) {
395+
// This was a hint for the next block, so we should skip processing it as a file content block.
396+
continue
397+
}
398+
}
399+
}
400+
}
401+
363402
// Check if there's a comment line before the code block with a file path
364403
let file_path_hint: string | undefined
365404
let workspace_hint: string | undefined
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
```markdown
2+
<file path="src/index.ts" new>
3+
```
4+
```diff
5+
@@ -0,0 +1,1 @@
6+
+console.log('hello')
7+
```
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
--- /dev/null
2+
+++ b/src/index.ts
3+
@@ -0,0 +1,1 @@
4+
+console.log('hello')

0 commit comments

Comments
 (0)