DoneDrop
pendingby Gnan Deep Rathan K
Automatically moves completed tasks to the bottom of their lists.
DoneDrop
An Obsidian plugin that automatically moves completed tasks to the bottom of their lists.
Features
- Auto-sort: Completed tasks (
- [x]) are moved to the bottom of their indentation level. - Recursive: Handles nested sub-tasks correctly.
- Interactive: Works in both Live Preview (Editor) and Reading Mode.
Architecture Flow
The following diagram illustrates how the plugin handles events from different sources (Editor, Reading Mode, File System) and processes them using the core sorting logic.
graph TD
%% Styling
classDef obsidian fill:#2c3e50,stroke:#ecf0f1,stroke-width:2px,color:#ecf0f1;
classDef plugin fill:#8e44ad,stroke:#9b59b6,stroke-width:2px,color:#fff;
classDef logic fill:#27ae60,stroke:#2ecc71,stroke-width:2px,color:#fff;
classDef data fill:#e67e22,stroke:#d35400,stroke-width:2px,color:#fff;
subgraph Obsidian["Obsidian Environment"]
UserEditor["User Types (Live Preview)"]:::obsidian
UserReading["User Clicks Checkbox (Reading Mode)"]:::obsidian
VaultModify["File Modified (Sync/External)"]:::obsidian
end
subgraph Main["Plugin Controller (main.ts)"]
OnEditorChange["onEditorChange(editor)"]:::plugin
OnPostProcess["onMarkdownPostProcess(html)"]:::plugin
OnFileModify["onFileModify(file)"]:::plugin
HandleSort{"handleSort(file)"}:::plugin
ApplyEditor["Apply via Editor API\n(Preserves Cursor)"]:::plugin
ApplyVault["Apply via Vault API\n(Direct Write)"]:::plugin
end
subgraph Core["Core Logic (src/sorter.ts)"]
Sorter["TaskSorter.sort(text)"]:::logic
Parser["parseBlocks()"]:::logic
TreeSort["sortBlocksRecursively()"]:::logic
Stringifier["stringifyBlocks()"]:::logic
BlockTree["TaskBlock Tree"]:::data
end
%% Live Preview Flow
UserEditor --> |Event: editor-change| OnEditorChange
OnEditorChange --> |Debounce 1s| Sorter
%% Reading Mode Flow
UserReading --> |DOM Click Event| OnPostProcess
OnPostProcess --> |Delay 200ms| HandleSort
%% File System Flow
VaultModify --> |Event: modify| OnFileModify
OnFileModify --> HandleSort
%% Handling Logic
HandleSort --> |Check Open Editors| IsOpen{Is Open in Source Mode?}:::plugin
IsOpen -- Yes --> ApplyEditor
IsOpen -- No --> ApplyVault
%% Core Sorting Process
Sorter --> Parser
Parser --> |Create| BlockTree
BlockTree --> TreeSort
TreeSort --> |Sort Children| TreeSort
TreeSort --> Stringifier
Stringifier --> |Return Sorted Text| Sorter
%% Application
Sorter --> ApplyEditor
Sorter --> ApplyVault
ApplyEditor --> |Update View| UserEditor
ApplyVault --> |Update File| VaultModify
Development
- Run
npm installto install dependencies. - Run
npm run devto start compilation in watch mode. - Reload Obsidian to see changes.
Build
Run npm run build to create main.js.
Code Overview
src/sorter.ts: The Brain. Contains the core logic for parsing Markdown text into a block tree, recursively sorting tasks (incomplete > complete), and rebuilding the string. Pure TypeScript, no Obsidian dependencies.main.ts: The Glue. Handles Obsidian API events (editor-changefor typing,vault.modifyfor external/preview changes), debouncing, and applying the sorted text back to the editor.esbuild.config.mjs: The Bundler. Configuresesbuildto bundle the TypeScript code into a singlemain.jsfile for Obsidian.manifest.json: Plugin metadata (id, version, name) required by Obsidian.
For plugin developers
Search results and similarity scores are powered by semantic analysis of your plugin's README. If your plugin isn't appearing for searches you'd expect, try updating your README to clearly describe your plugin's purpose, features, and use cases.