Compare commits

...

1 Commits

Author SHA1 Message Date
8fe38af7b3 Update headings list to display plain text, and add option to insert at beginning
Some checks failed
Node.js build / build (20.x) (push) Failing after 5m48s
Node.js build / build (22.x) (push) Failing after 5m45s
2026-02-20 16:16:30 -08:00
4 changed files with 38 additions and 14 deletions

View File

@@ -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');
});
});

View File

@@ -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.

View File

@@ -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<HeadingOption> {
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<HeadingOption> {
);
});
} 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);
});
}
}

View File

@@ -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<TFile> {
private todo: TodoItem;
@@ -37,7 +37,7 @@ export class NoteSelectModal extends FuzzySuggestModal<TFile> {
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<TFile> {
});
} 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);
});
}
}