Search...Search plugins and themes...
⌘K
Sign in
  • Get started
  • Download
  • Pricing
  • Enterprise
  • Account
  • Obsidian
  • Overview
  • Sync
  • Publish
  • Canvas
  • Mobile
  • Web Clipper
  • CLI
  • Learn
  • Help
  • Developers
  • Changelog
  • About
  • Roadmap
  • Blog
  • Resources
  • System status
  • License overview
  • Terms of service
  • Privacy policy
  • Security
  • Community
  • Plugins
  • Themes
  • Discord
  • Forum / 中文论坛
  • Merch store
  • Brand guidelines
Follow us
DiscordTwitterBlueskyThreadsMastodonYouTubeGitHub
© 2026 Obsidian

DoneDrop

kgdrathankgdrathan57 downloads

Automatically moves completed tasks to the bottom of their lists.

Add to Obsidian
  • Overview
  • Scorecard
  • Updates3

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

  1. Run npm install to install dependencies.
  2. Run npm run dev to start compilation in watch mode.
  3. 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-change for typing, vault.modify for external/preview changes), debouncing, and applying the sorted text back to the editor.
  • esbuild.config.mjs: The Bundler. Configures esbuild to bundle the TypeScript code into a single main.js file for Obsidian.
  • manifest.json: Plugin metadata (id, version, name) required by Obsidian.
81%
HealthExcellent
ReviewSatisfactory
About
Move completed tasks (- [x]) to the bottom of their indentation level to keep lists focused on open items. Handle nested subtasks recursively and operate in Live Preview and Reading Mode while preserving the editor cursor when applying changes.
TasksAutomationEditing
Details
Current version
1.0.2
Last updated
4 months ago
Created
4 months ago
Updates
3 releases
Downloads
57
Compatible with
Obsidian 0.15.0+
Platforms
Desktop, Mobile
License
Apache-2.0
Report bugRequest featureReport plugin
Author
kgdrathankgdrathan
gitlab.com/kgdrathan
GitHubkgdrathan
  1. Community
  2. Plugins
  3. Tasks
  4. DoneDrop

Related plugins

Task Collector (TC)

Change task status and collect tasks within a document using hotkeys and context menus.

Rollover Daily Todos

Rollover any unchecked checkboxes from your last daily note into today's note.

Todoist Sync

Materialize Todoist tasks within your notes.

MetaEdit

Manage your metadata.

Advanced Tables

Improved table navigation, formatting, and manipulation.

QuickAdd

Quickly add new notes or content to your vault.

Templater

Create and use dynamic templates.

Homepage

Open a note, base, or workspace on startup, or set it for quick access later.

TaskNotes

Note-based task management with calendar, pomodoro and time-tracking integration.

Day Planner

Day planning from a task list in a Markdown note with enhanced time block functionality.