Remove drag and drop entirely
This commit is contained in:
@@ -1,3 +1,5 @@
|
||||
import { parseIndentLevel } from './todo-parser';
|
||||
|
||||
/**
|
||||
* Regex pattern for markdown todo checkboxes (for toggling).
|
||||
*/
|
||||
@@ -165,21 +167,22 @@ export function indentTodoLines(todoLines: string[], indentDelta: number): strin
|
||||
}
|
||||
|
||||
/**
|
||||
* Insert a todo line under a specific heading.
|
||||
* Insert a todo line (or block of lines) under a specific heading.
|
||||
* @param content - The file content
|
||||
* @param headingLineNumber - The line number of the heading (0-based)
|
||||
* @param todoLine - The todo line to insert
|
||||
* @param todoLine - The todo line(s) to insert (single string or array of strings)
|
||||
* @param nextHeadingLineNumber - Optional line number of the next heading (for section boundary)
|
||||
* @param addBlankLine - Whether to add a blank line between the heading and the todo
|
||||
*/
|
||||
export function insertTodoUnderHeading(
|
||||
content: string,
|
||||
headingLineNumber: number,
|
||||
todoLine: string,
|
||||
todoLine: string | string[],
|
||||
nextHeadingLineNumber?: number,
|
||||
addBlankLine = false
|
||||
): string {
|
||||
const lines = content.split('\n');
|
||||
const todoLines = Array.isArray(todoLine) ? todoLine : [todoLine];
|
||||
|
||||
// Determine where to insert
|
||||
let insertPosition: number;
|
||||
@@ -197,14 +200,104 @@ export function insertTodoUnderHeading(
|
||||
|
||||
if (alreadyHasBlank) {
|
||||
// Insert after the existing blank line
|
||||
lines.splice(headingLineNumber + 2, 0, todoLine);
|
||||
lines.splice(headingLineNumber + 2, 0, ...todoLines);
|
||||
} else {
|
||||
// Insert blank line + todo
|
||||
lines.splice(insertPosition, 0, '', todoLine);
|
||||
// Insert blank line + todos
|
||||
lines.splice(insertPosition, 0, '', ...todoLines);
|
||||
}
|
||||
} else {
|
||||
lines.splice(insertPosition, 0, todoLine);
|
||||
lines.splice(insertPosition, 0, ...todoLines);
|
||||
}
|
||||
|
||||
return lines.join('\n');
|
||||
}
|
||||
|
||||
/**
|
||||
* Collect all line numbers that belong to a todo's block (by indentation).
|
||||
* A line is part of the block if its indentation is greater than the todo's.
|
||||
* Stops at blank line or line with same/lesser indentation.
|
||||
*/
|
||||
export function collectTodoBlockLines(content: string, todoLineNumber: number): number[] {
|
||||
const lines = content.split('\n');
|
||||
const todoLine = lines[todoLineNumber];
|
||||
if (!todoLine) return [];
|
||||
|
||||
const todoIndent = parseIndentLevel(todoLine);
|
||||
const blockLines: number[] = [];
|
||||
|
||||
for (let i = todoLineNumber + 1; i < lines.length; i++) {
|
||||
const line = lines[i]!;
|
||||
|
||||
// Stop at blank line
|
||||
if (line.trim() === '') {
|
||||
break;
|
||||
}
|
||||
|
||||
// Stop at same or lesser indentation
|
||||
if (parseIndentLevel(line) <= todoIndent) {
|
||||
break;
|
||||
}
|
||||
|
||||
blockLines.push(i);
|
||||
}
|
||||
|
||||
return blockLines;
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove a todo and all its block lines (children, nested content, etc.).
|
||||
*/
|
||||
export function removeTodoBlock(content: string, todoLineNumber: number): string {
|
||||
const blockLines = collectTodoBlockLines(content, todoLineNumber);
|
||||
const allLineNumbers = [todoLineNumber, ...blockLines].sort((a, b) => a - b);
|
||||
const lines = content.split('\n');
|
||||
|
||||
// Remove in reverse to preserve indices
|
||||
for (let i = allLineNumbers.length - 1; i >= 0; i--) {
|
||||
lines.splice(allLineNumbers[i]!, 1);
|
||||
}
|
||||
|
||||
return lines.join('\n');
|
||||
}
|
||||
|
||||
/**
|
||||
* Move a todo block to a new position with optional indentation adjustment.
|
||||
* Auto-detects all lines in the block by indentation.
|
||||
* @param indentDelta - Positive = indent, negative = outdent
|
||||
*/
|
||||
export function moveTodoBlock(
|
||||
content: string,
|
||||
todoLineNumber: number,
|
||||
targetLineNumber: number,
|
||||
indentDelta = 0
|
||||
): string {
|
||||
const blockLines = collectTodoBlockLines(content, todoLineNumber);
|
||||
const allLineNumbers = [todoLineNumber, ...blockLines].sort((a, b) => a - b);
|
||||
const lines = content.split('\n');
|
||||
|
||||
// Extract lines to move
|
||||
let movedLines = allLineNumbers.map((ln) => lines[ln]!);
|
||||
|
||||
// Apply indentation if needed
|
||||
if (indentDelta !== 0) {
|
||||
movedLines = indentTodoLines(movedLines, indentDelta);
|
||||
}
|
||||
|
||||
// Remove original lines (in reverse to preserve indices)
|
||||
for (let i = allLineNumbers.length - 1; i >= 0; i--) {
|
||||
lines.splice(allLineNumbers[i]!, 1);
|
||||
}
|
||||
|
||||
// Adjust target position for removed lines
|
||||
let adjustedTarget = targetLineNumber;
|
||||
for (const ln of allLineNumbers) {
|
||||
if (ln < targetLineNumber) {
|
||||
adjustedTarget--;
|
||||
}
|
||||
}
|
||||
|
||||
// Insert at adjusted target
|
||||
lines.splice(adjustedTarget, 0, ...movedLines);
|
||||
|
||||
return lines.join('\n');
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user