* fix: DiffViewProvider line boundary validation and content concatenation
Two bugs in DiffViewProvider caused file editing failures:
1. **Line boundary validation errors (#8423, #8429)**
JetBrains hosts using gRPC strictly validate line numbers. When
truncateDocument() was called with a line number >= document line count,
it caused "truncateDocument INTERNAL: Wrong line" errors. This occurred
when new content had >= lines than the original, making truncation
unnecessary but still attempted.
2. **Content concatenation on final update**
When replacing content without a trailing newline, the old content at
line N+1 was concatenated to the new content. For example, writing
"Hello World" to a file containing "line1\nline2\n" resulted in
"Hello Worldline2" instead of just "Hello World".
1. Added `getDocumentLineCount()` abstract method to all DiffViewProvider
implementations to query the current document line count.
2. Added `safelyTruncateDocument()` private helper that validates line
numbers before calling truncateDocument():
```typescript
private async safelyTruncateDocument(lineNumber: number): Promise<void> {
const lineCount = await this.getDocumentLineCount()
if (lineNumber < lineCount) {
await this.truncateDocument(lineNumber)
}
}
```
3. Extended the replacement range on final update to cover the entire
document, preventing content concatenation:
```typescript
const endLine = isFinal
? await this.getDocumentLineCount()
: currentLine + 1
```
- src/integrations/editor/DiffViewProvider.ts
- Added abstract getDocumentLineCount() method
- Added safelyTruncateDocument() boundary validation helper
- Modified update() to extend final replacement range
- src/hosts/vscode/VscodeDiffViewProvider.ts
- Implemented getDocumentLineCount() using editor.document.lineCount
- src/hosts/external/ExternalDiffviewProvider.ts
- Implemented getDocumentLineCount() by counting lines from getDocumentText()
- src/integrations/editor/FileEditProvider.ts
- Implemented getDocumentLineCount() from documentContent
- src/integrations/editor/__tests__/DiffViewProvider.test.ts (new)
- Added 4 unit tests for boundary validation and concatenation fix
Fixes#8423, #8429
* fix: preserve trailing newlines in file edits
Trailing newlines were being incorrectly stripped during file edits due to
trimEnd() calls in handlers. This caused files to lose their final newline
even when the original file had one.
Changes:
- Remove trimEnd() from WriteToFileToolHandler and ApplyPatchHandler that
was stripping trailing newlines before content reached the editor
- Remove dead code in DiffViewProvider.update() that tried to restore
newlines after the document was already written
- Add trailing newline fix-up in VscodeDiffViewProvider to handle VS Code's
applyEdit sometimes normalizing newlines on full-document replacements
- Fix FileEditProvider.replaceText() to preserve trailing newlines when
replacing to end of document
* fix: preserve trailing newlines in diff text ops
Align splitLines with JS split behavior and keep trailing
newline segments when replacing to end of document to avoid
dropping final line breaks.