fix(frontend): preserve edit file trailing context
This commit is contained in:
parent
f661dc6456
commit
6c368d2aa0
@ -298,19 +298,19 @@ function renderEditFile(result: any, args: any): string {
|
|||||||
const newText = rep.new_string || '';
|
const newText = rep.new_string || '';
|
||||||
const detail = details[idx] || {};
|
const detail = details[idx] || {};
|
||||||
const contexts = Array.isArray(detail.contexts) ? detail.contexts : [];
|
const contexts = Array.isArray(detail.contexts) ? detail.contexts : [];
|
||||||
|
const oldLines = oldText ? oldText.split('\n') : [];
|
||||||
|
const newLines = newText ? newText.split('\n') : [];
|
||||||
const buildPairRows = (context?: any) => {
|
const buildPairRows = (context?: any) => {
|
||||||
const rows: any[] = [];
|
const rows: any[] = [];
|
||||||
const startLineCandidate = Number(context?.old_start_line ?? detail.matched_lines?.[0]);
|
const startLineCandidate = Number(context?.old_start_line ?? detail.matched_lines?.[0]);
|
||||||
const startLine = Number.isFinite(startLineCandidate) ? startLineCandidate : null;
|
const startLine = Number.isFinite(startLineCandidate) ? startLineCandidate : null;
|
||||||
if (oldText) {
|
if (oldText) {
|
||||||
const oldLines = oldText.split('\n');
|
|
||||||
oldLines.forEach((line: string, lineIdx: number) => {
|
oldLines.forEach((line: string, lineIdx: number) => {
|
||||||
rows.push({ lineNo: startLine === null ? null : startLine + lineIdx, marker: '-', text: line, className: 'diff-remove' });
|
rows.push({ lineNo: startLine === null ? null : startLine + lineIdx, marker: '-', text: line, className: 'diff-remove' });
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
if (newText) {
|
if (newText) {
|
||||||
const newLines = newText.split('\n');
|
|
||||||
newLines.forEach((line: string, lineIdx: number) => {
|
newLines.forEach((line: string, lineIdx: number) => {
|
||||||
rows.push({ lineNo: startLine === null ? null : startLine + lineIdx, marker: '+', text: line, className: 'diff-add' });
|
rows.push({ lineNo: startLine === null ? null : startLine + lineIdx, marker: '+', text: line, className: 'diff-add' });
|
||||||
});
|
});
|
||||||
@ -337,12 +337,24 @@ function renderEditFile(result: any, args: any): string {
|
|||||||
rawAfterLines.length >= 2 && String(rawAfterLines[rawAfterLines.length - 1]?.text ?? '') === ''
|
rawAfterLines.length >= 2 && String(rawAfterLines[rawAfterLines.length - 1]?.text ?? '') === ''
|
||||||
? rawAfterLines.slice(0, -1)
|
? rawAfterLines.slice(0, -1)
|
||||||
: rawAfterLines;
|
: rawAfterLines;
|
||||||
|
|
||||||
|
// 编辑后新增/删除行数不同会导致后续行号偏移,after context 需按新文件位置重新编号
|
||||||
|
const contextOldStartLine = Number(context?.old_start_line ?? detail.matched_lines?.[0]);
|
||||||
|
const contextOldEndLine = Number(context?.old_end_line ?? contextOldStartLine);
|
||||||
|
const oldLineCount = Number.isFinite(contextOldStartLine) && Number.isFinite(contextOldEndLine)
|
||||||
|
? Math.max(1, contextOldEndLine - contextOldStartLine + 1)
|
||||||
|
: Math.max(1, (oldText ? oldText.split('\n').length : 1));
|
||||||
|
const newLineCount = newText === '' ? 0 : newText.split('\n').length;
|
||||||
|
const afterContextOffset = newLineCount - oldLineCount;
|
||||||
|
|
||||||
beforeLines.forEach((item: any) => {
|
beforeLines.forEach((item: any) => {
|
||||||
rows.push({ lineNo: Number(item.line), marker: ' ', text: String(item.text ?? ''), className: '' });
|
rows.push({ lineNo: Number(item.line), marker: ' ', text: String(item.text ?? ''), className: '' });
|
||||||
});
|
});
|
||||||
rows.push(...buildPairRows(context));
|
rows.push(...buildPairRows(context));
|
||||||
afterLines.forEach((item: any) => {
|
afterLines.forEach((item: any) => {
|
||||||
rows.push({ lineNo: Number(item.line), marker: ' ', text: String(item.text ?? ''), className: '' });
|
const rawLineNo = Number(item.line);
|
||||||
|
const lineNo = Number.isFinite(rawLineNo) ? rawLineNo + afterContextOffset : rawLineNo;
|
||||||
|
rows.push({ lineNo, marker: ' ', text: String(item.text ?? ''), className: '' });
|
||||||
});
|
});
|
||||||
const numberedRows = rows.filter((row) => typeof row.lineNo === 'number' && Number.isFinite(row.lineNo));
|
const numberedRows = rows.filter((row) => typeof row.lineNo === 'number' && Number.isFinite(row.lineNo));
|
||||||
hunks.push({
|
hunks.push({
|
||||||
@ -375,14 +387,8 @@ function renderEditFile(result: any, args: any): string {
|
|||||||
const markerOrder: Record<string, number> = { ' ': 0, '-': 1, '+': 2 };
|
const markerOrder: Record<string, number> = { ' ': 0, '-': 1, '+': 2 };
|
||||||
mergedHunks.forEach((hunk, hunkIdx) => {
|
mergedHunks.forEach((hunk, hunkIdx) => {
|
||||||
if (hunkIdx > 0) renderDiffLine(null, ' ', '⋮', 'diff-separator');
|
if (hunkIdx > 0) renderDiffLine(null, ' ', '⋮', 'diff-separator');
|
||||||
const changedLines = new Set(
|
|
||||||
hunk.rows
|
|
||||||
.filter((row: any) => (row.marker === '-' || row.marker === '+') && typeof row.lineNo === 'number')
|
|
||||||
.map((row: any) => row.lineNo)
|
|
||||||
);
|
|
||||||
const seenContextLines = new Set<number>();
|
const seenContextLines = new Set<number>();
|
||||||
hunk.rows
|
const filteredRows = hunk.rows
|
||||||
.filter((row: any) => !(row.marker === ' ' && changedLines.has(row.lineNo)))
|
|
||||||
.filter((row: any) => {
|
.filter((row: any) => {
|
||||||
if (row.marker !== ' ' || typeof row.lineNo !== 'number') return true;
|
if (row.marker !== ' ' || typeof row.lineNo !== 'number') return true;
|
||||||
if (seenContextLines.has(row.lineNo)) return false;
|
if (seenContextLines.has(row.lineNo)) return false;
|
||||||
@ -400,8 +406,8 @@ function renderEditFile(result: any, args: any): string {
|
|||||||
// 上下文行或跨类型:按行号优先
|
// 上下文行或跨类型:按行号优先
|
||||||
const lineDelta = (a.lineNo ?? Number.MAX_SAFE_INTEGER) - (b.lineNo ?? Number.MAX_SAFE_INTEGER);
|
const lineDelta = (a.lineNo ?? Number.MAX_SAFE_INTEGER) - (b.lineNo ?? Number.MAX_SAFE_INTEGER);
|
||||||
return lineDelta || (markerOrder[a.marker] ?? 9) - (markerOrder[b.marker] ?? 9);
|
return lineDelta || (markerOrder[a.marker] ?? 9) - (markerOrder[b.marker] ?? 9);
|
||||||
})
|
});
|
||||||
.forEach((row: any) => renderDiffLine(row.lineNo, row.marker, row.text, row.className));
|
filteredRows.forEach((row: any) => renderDiffLine(row.lineNo, row.marker, row.text, row.className));
|
||||||
});
|
});
|
||||||
html += '</div>';
|
html += '</div>';
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user