Skip to content

Commit e7cbbf2

Browse files
authored
fix: preserve insert-at-end order for non-newline captures (#1120)
1 parent 8bb8ed4 commit e7cbbf2

File tree

2 files changed

+34
-3
lines changed

2 files changed

+34
-3
lines changed

src/formatters/captureChoiceFormatter-frontmatter.test.ts

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -478,6 +478,28 @@ describe('CaptureChoiceFormatter insert after end-of-section spacing', () => {
478478
expect(second).toBe(['Target', 'Existing', 'One', '', 'Two', '', ''].join('\n'));
479479
});
480480

481+
it('preserves insertion order when format has no trailing newline and EOF blanks exist', async () => {
482+
const { formatter, file } = createFormatter();
483+
const choice = createInsertAfterChoice('# H');
484+
const initial = ['# H', 'A', '', ''].join('\n');
485+
486+
const first = await formatter.formatContentWithFile(
487+
'X',
488+
choice,
489+
initial,
490+
file,
491+
);
492+
493+
const second = await formatter.formatContentWithFile(
494+
'Y',
495+
choice,
496+
first,
497+
file,
498+
);
499+
500+
expect(second).toBe(['# H', 'A', 'X', 'Y'].join('\n'));
501+
});
502+
481503
it('does not change behavior when insert-at-end is disabled', async () => {
482504
const { formatter, file } = createFormatter();
483505
const choice = createInsertAfterChoice('# Journal', { insertAtEnd: false });

src/formatters/captureChoiceFormatter.ts

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -266,7 +266,8 @@ export class CaptureChoiceFormatter extends CompleteFormatter {
266266
private findInsertAfterPositionAtSectionEnd(
267267
lines: string[],
268268
sectionEndIndex: number,
269-
body: string,
269+
fileContent: string,
270+
insertedText: string,
270271
): number {
271272
if (sectionEndIndex < 0) return sectionEndIndex;
272273

@@ -284,10 +285,16 @@ export class CaptureChoiceFormatter extends CompleteFormatter {
284285
return sectionEndIndex;
285286
}
286287

288+
// For entries without trailing newline, keep insertion anchored at the
289+
// section end so repeated captures preserve order.
290+
if (!insertedText.endsWith("\n")) {
291+
return sectionEndIndex;
292+
}
293+
287294
// split("\n") keeps a trailing empty string when content ends in "\n".
288295
// We keep one trailing slot so the next insertion preserves capture spacing
289296
// without introducing an extra blank line before the inserted text.
290-
if (body.endsWith("\n")) {
297+
if (fileContent.endsWith("\n")) {
291298
return Math.max(sectionEndIndex, position - 1);
292299
}
293300

@@ -334,6 +341,7 @@ export class CaptureChoiceFormatter extends CompleteFormatter {
334341
fileContentLines,
335342
endOfSectionIndex ?? fileContentLines.length - 1,
336343
this.fileContent,
344+
formatted,
337345
);
338346
} else {
339347
const blankLineMode =
@@ -470,8 +478,9 @@ export class CaptureChoiceFormatter extends CompleteFormatter {
470478
fileContentLines,
471479
endOfSectionIndex ?? fileContentLines.length - 1,
472480
this.fileContent,
481+
insertAfterLineAndFormatted,
473482
);
474-
}
483+
}
475484

476485
const newFileContent = this.insertTextAfterPositionInBody(
477486
insertAfterLineAndFormatted,

0 commit comments

Comments
 (0)