mirror of
https://github.com/pacnpal/Roo-Code.git
synced 2025-12-21 12:51:17 -05:00
Stop appending newlines to files when applying diffs
This commit is contained in:
@@ -124,15 +124,16 @@ export class DiffViewProvider {
|
|||||||
edit.delete(document.uri, new vscode.Range(this.streamedLines.length, 0, document.lineCount, 0))
|
edit.delete(document.uri, new vscode.Range(this.streamedLines.length, 0, document.lineCount, 0))
|
||||||
await vscode.workspace.applyEdit(edit)
|
await vscode.workspace.applyEdit(edit)
|
||||||
}
|
}
|
||||||
// Add empty last line if original content had one
|
// Preserve empty last line if original content had one
|
||||||
const hasEmptyLastLine = this.originalContent?.endsWith("\n")
|
const hasEmptyLastLine = this.originalContent?.endsWith("\n")
|
||||||
if (hasEmptyLastLine) {
|
if (hasEmptyLastLine && !accumulatedContent.endsWith("\n")) {
|
||||||
const accumulatedLines = accumulatedContent.split("\n")
|
|
||||||
if (accumulatedLines[accumulatedLines.length - 1] !== "") {
|
|
||||||
accumulatedContent += "\n"
|
accumulatedContent += "\n"
|
||||||
}
|
}
|
||||||
}
|
// Apply the final content
|
||||||
// Clear all decorations at the end (before applying final edit)
|
const finalEdit = new vscode.WorkspaceEdit()
|
||||||
|
finalEdit.replace(document.uri, new vscode.Range(0, 0, document.lineCount, 0), accumulatedContent)
|
||||||
|
await vscode.workspace.applyEdit(finalEdit)
|
||||||
|
// Clear all decorations at the end (after applying final edit)
|
||||||
this.fadedOverlayController.clear()
|
this.fadedOverlayController.clear()
|
||||||
this.activeLineController.clear()
|
this.activeLineController.clear()
|
||||||
}
|
}
|
||||||
|
|||||||
100
src/integrations/editor/__tests__/DiffViewProvider.test.ts
Normal file
100
src/integrations/editor/__tests__/DiffViewProvider.test.ts
Normal file
@@ -0,0 +1,100 @@
|
|||||||
|
import { DiffViewProvider } from '../DiffViewProvider';
|
||||||
|
import * as vscode from 'vscode';
|
||||||
|
|
||||||
|
// Mock vscode
|
||||||
|
jest.mock('vscode', () => ({
|
||||||
|
workspace: {
|
||||||
|
applyEdit: jest.fn(),
|
||||||
|
},
|
||||||
|
window: {
|
||||||
|
createTextEditorDecorationType: jest.fn(),
|
||||||
|
},
|
||||||
|
WorkspaceEdit: jest.fn().mockImplementation(() => ({
|
||||||
|
replace: jest.fn(),
|
||||||
|
delete: jest.fn(),
|
||||||
|
})),
|
||||||
|
Range: jest.fn(),
|
||||||
|
Position: jest.fn(),
|
||||||
|
Selection: jest.fn(),
|
||||||
|
TextEditorRevealType: {
|
||||||
|
InCenter: 2,
|
||||||
|
},
|
||||||
|
}));
|
||||||
|
|
||||||
|
// Mock DecorationController
|
||||||
|
jest.mock('../DecorationController', () => ({
|
||||||
|
DecorationController: jest.fn().mockImplementation(() => ({
|
||||||
|
setActiveLine: jest.fn(),
|
||||||
|
updateOverlayAfterLine: jest.fn(),
|
||||||
|
clear: jest.fn(),
|
||||||
|
})),
|
||||||
|
}));
|
||||||
|
|
||||||
|
describe('DiffViewProvider', () => {
|
||||||
|
let diffViewProvider: DiffViewProvider;
|
||||||
|
const mockCwd = '/mock/cwd';
|
||||||
|
let mockWorkspaceEdit: { replace: jest.Mock; delete: jest.Mock };
|
||||||
|
|
||||||
|
beforeEach(() => {
|
||||||
|
jest.clearAllMocks();
|
||||||
|
mockWorkspaceEdit = {
|
||||||
|
replace: jest.fn(),
|
||||||
|
delete: jest.fn(),
|
||||||
|
};
|
||||||
|
(vscode.WorkspaceEdit as jest.Mock).mockImplementation(() => mockWorkspaceEdit);
|
||||||
|
|
||||||
|
diffViewProvider = new DiffViewProvider(mockCwd);
|
||||||
|
// Mock the necessary properties and methods
|
||||||
|
(diffViewProvider as any).relPath = 'test.txt';
|
||||||
|
(diffViewProvider as any).activeDiffEditor = {
|
||||||
|
document: {
|
||||||
|
uri: { fsPath: `${mockCwd}/test.txt` },
|
||||||
|
getText: jest.fn(),
|
||||||
|
lineCount: 10,
|
||||||
|
},
|
||||||
|
selection: {
|
||||||
|
active: { line: 0, character: 0 },
|
||||||
|
anchor: { line: 0, character: 0 },
|
||||||
|
},
|
||||||
|
edit: jest.fn().mockResolvedValue(true),
|
||||||
|
revealRange: jest.fn(),
|
||||||
|
};
|
||||||
|
(diffViewProvider as any).activeLineController = { setActiveLine: jest.fn(), clear: jest.fn() };
|
||||||
|
(diffViewProvider as any).fadedOverlayController = { updateOverlayAfterLine: jest.fn(), clear: jest.fn() };
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('update method', () => {
|
||||||
|
it('should preserve empty last line when original content has one', async () => {
|
||||||
|
(diffViewProvider as any).originalContent = 'Original content\n';
|
||||||
|
await diffViewProvider.update('New content', true);
|
||||||
|
|
||||||
|
expect(mockWorkspaceEdit.replace).toHaveBeenCalledWith(
|
||||||
|
expect.anything(),
|
||||||
|
expect.anything(),
|
||||||
|
'New content\n'
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should not add extra newline when accumulated content already ends with one', async () => {
|
||||||
|
(diffViewProvider as any).originalContent = 'Original content\n';
|
||||||
|
await diffViewProvider.update('New content\n', true);
|
||||||
|
|
||||||
|
expect(mockWorkspaceEdit.replace).toHaveBeenCalledWith(
|
||||||
|
expect.anything(),
|
||||||
|
expect.anything(),
|
||||||
|
'New content\n'
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should not add newline when original content does not end with one', async () => {
|
||||||
|
(diffViewProvider as any).originalContent = 'Original content';
|
||||||
|
await diffViewProvider.update('New content', true);
|
||||||
|
|
||||||
|
expect(mockWorkspaceEdit.replace).toHaveBeenCalledWith(
|
||||||
|
expect.anything(),
|
||||||
|
expect.anything(),
|
||||||
|
'New content'
|
||||||
|
);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
Reference in New Issue
Block a user