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 detail = details[idx] || {};
|
||||
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 rows: any[] = [];
|
||||
const startLineCandidate = Number(context?.old_start_line ?? detail.matched_lines?.[0]);
|
||||
const startLine = Number.isFinite(startLineCandidate) ? startLineCandidate : null;
|
||||
if (oldText) {
|
||||
const oldLines = oldText.split('\n');
|
||||
oldLines.forEach((line: string, lineIdx: number) => {
|
||||
rows.push({ lineNo: startLine === null ? null : startLine + lineIdx, marker: '-', text: line, className: 'diff-remove' });
|
||||
});
|
||||
}
|
||||
|
||||
if (newText) {
|
||||
const newLines = newText.split('\n');
|
||||
newLines.forEach((line: string, lineIdx: number) => {
|
||||
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.slice(0, -1)
|
||||
: 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) => {
|
||||
rows.push({ lineNo: Number(item.line), marker: ' ', text: String(item.text ?? ''), className: '' });
|
||||
});
|
||||
rows.push(...buildPairRows(context));
|
||||
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));
|
||||
hunks.push({
|
||||
@ -375,14 +387,8 @@ function renderEditFile(result: any, args: any): string {
|
||||
const markerOrder: Record<string, number> = { ' ': 0, '-': 1, '+': 2 };
|
||||
mergedHunks.forEach((hunk, hunkIdx) => {
|
||||
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>();
|
||||
hunk.rows
|
||||
.filter((row: any) => !(row.marker === ' ' && changedLines.has(row.lineNo)))
|
||||
const filteredRows = hunk.rows
|
||||
.filter((row: any) => {
|
||||
if (row.marker !== ' ' || typeof row.lineNo !== 'number') return true;
|
||||
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);
|
||||
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>';
|
||||
}
|
||||
|
||||
Loading…
Reference in New Issue
Block a user