diff --git a/src/core/todo-transformer.test.ts b/src/core/todo-transformer.test.ts index 9b6f6a8..c396422 100644 --- a/src/core/todo-transformer.test.ts +++ b/src/core/todo-transformer.test.ts @@ -10,6 +10,7 @@ import { collectTodoBlockLines, removeTodoBlock, moveTodoBlock, + insertTodoAtBeginning, } from './todo-transformer'; describe('toggleTodo', () => { @@ -414,3 +415,21 @@ describe('moveTodoBlock', () => { expect(result).toBe('- [ ] B\n - B1\n - B2\n- [ ] A\n- [ ] C'); }); }); + +describe('insertTodoAtBeginning', () => { + it('should insert at the beginning of file content', () => { + const content = 'Line 1\nLine 2'; + const result = insertTodoAtBeginning(content, '- [ ] New todo'); + expect(result).toBe('- [ ] New todo\nLine 1\nLine 2'); + }); + + it('should handle empty file', () => { + const result = insertTodoAtBeginning('', '- [ ] New todo'); + expect(result).toBe('- [ ] New todo'); + }); + + it('should handle file with only whitespace', () => { + const result = insertTodoAtBeginning('\n\n', '- [ ] New todo'); + expect(result).toBe('- [ ] New todo\n\n\n'); + }); +}); diff --git a/src/core/todo-transformer.ts b/src/core/todo-transformer.ts index d9095dc..0ba591b 100644 --- a/src/core/todo-transformer.ts +++ b/src/core/todo-transformer.ts @@ -49,6 +49,16 @@ export function removeTodoLine(content: string, lineNumber: number): string { return lines.join('\n'); } +/** + * Insert a todo line at the beginning of the content. + */ +export function insertTodoAtBeginning(content: string, todoLine: string): string { + if (!content) { + return todoLine; + } + return todoLine + '\n' + content; +} + /** * Insert a todo line at the end of the content. * Handles files with/without trailing newlines. diff --git a/src/modals/heading-select-modal.ts b/src/modals/heading-select-modal.ts index 8876559..b5cd252 100644 --- a/src/modals/heading-select-modal.ts +++ b/src/modals/heading-select-modal.ts @@ -2,7 +2,7 @@ import { App, FuzzySuggestModal, TFile, HeadingCache } from 'obsidian'; import type { TodoItem } from '../core/types'; import { removeTodoBlock, - insertTodoAtEnd, + insertTodoAtBeginning, insertTodoUnderHeading, collectTodoBlockLines, } from '../core/todo-transformer'; @@ -30,24 +30,21 @@ export class HeadingSelectModal extends FuzzySuggestModal { this.sourceFile = sourceFile; this.targetFile = targetFile; this.headings = headings; - this.setPlaceholder('Select a heading (or end of file)...'); + this.setPlaceholder('Select a heading...'); } getItems(): HeadingOption[] { const items: HeadingOption[] = []; - // Add "End of file" option first items.push({ heading: null, - displayText: 'End of file', + displayText: 'Beginning of file', }); - // Add all headings for (const heading of this.headings) { - const indent = ' '.repeat(heading.level - 1); items.push({ heading, - displayText: `${indent}${'#'.repeat(heading.level)} ${heading.heading}`, + displayText: heading.heading, }); } @@ -92,11 +89,10 @@ export class HeadingSelectModal extends FuzzySuggestModal { ); }); } else { - // End of file + // Beginning of file await this.app.vault.process(this.targetFile, (content) => { - // Reconstruct block as a single string const blockContent = blockLines.join('\n'); - return insertTodoAtEnd(content, blockContent); + return insertTodoAtBeginning(content, blockContent); }); } } diff --git a/src/modals/note-select-modal.ts b/src/modals/note-select-modal.ts index 9afc44c..9417058 100644 --- a/src/modals/note-select-modal.ts +++ b/src/modals/note-select-modal.ts @@ -1,7 +1,7 @@ import { App, FuzzySuggestModal, TFile } from 'obsidian'; import type { TodoItem } from '../core/types'; import { HeadingSelectModal } from './heading-select-modal'; -import { removeTodoBlock, insertTodoAtEnd, collectTodoBlockLines } from '../core/todo-transformer'; +import { removeTodoBlock, insertTodoAtBeginning, collectTodoBlockLines } from '../core/todo-transformer'; export class NoteSelectModal extends FuzzySuggestModal { private todo: TodoItem; @@ -37,7 +37,7 @@ export class NoteSelectModal extends FuzzySuggestModal { headings ).open(); } else { - // No headings - move directly to end of file + // No headings - move directly to beginning of file await this.moveTodo(file); } } @@ -61,9 +61,8 @@ export class NoteSelectModal extends FuzzySuggestModal { }); } else { await this.app.vault.process(targetFile, (content) => { - // Reconstruct block as a single string const blockContent = blockLines.join('\n'); - return insertTodoAtEnd(content, blockContent); + return insertTodoAtBeginning(content, blockContent); }); } }