{"id":51616516,"url":"https://github.com/jjuchara/obsidian-tasks.nvim","last_synced_at":"2026-07-14T14:01:31.502Z","repository":{"id":369068763,"uuid":"1287103647","full_name":"jjuchara/obsidian-tasks.nvim","owner":"jjuchara","description":"Keyboard-first Obsidian task management for Neovim with multi-vault views and ordered tag trees","archived":false,"fork":false,"pushed_at":"2026-07-03T12:58:49.000Z","size":33,"stargazers_count":2,"open_issues_count":1,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2026-07-03T13:29:32.824Z","etag":null,"topics":["lua","neovim","neovim-plugin","obsidian","productivity","task-management"],"latest_commit_sha":null,"homepage":null,"language":"Lua","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/jjuchara.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":"CONTRIBUTING.md","funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2026-07-02T11:36:37.000Z","updated_at":"2026-07-03T12:58:53.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/jjuchara/obsidian-tasks.nvim","commit_stats":null,"previous_names":["jjuchara/obsidian-tasks.nvim"],"tags_count":3,"template":false,"template_full_name":null,"purl":"pkg:github/jjuchara/obsidian-tasks.nvim","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jjuchara%2Fobsidian-tasks.nvim","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jjuchara%2Fobsidian-tasks.nvim/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jjuchara%2Fobsidian-tasks.nvim/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jjuchara%2Fobsidian-tasks.nvim/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/jjuchara","download_url":"https://codeload.github.com/jjuchara/obsidian-tasks.nvim/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jjuchara%2Fobsidian-tasks.nvim/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":35464541,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-05-26T15:22:16.424Z","status":"online","status_checked_at":"2026-07-14T02:00:06.603Z","response_time":114,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["lua","neovim","neovim-plugin","obsidian","productivity","task-management"],"created_at":"2026-07-12T14:00:27.259Z","updated_at":"2026-07-14T14:01:31.495Z","avatar_url":"https://github.com/jjuchara.png","language":"Lua","funding_links":[],"categories":["Note Taking"],"sub_categories":["Cursorline"],"readme":"\u003cp align=\"center\"\u003e\n  \u003cimg src=\"assets/banner.svg\" alt=\"obsidian-tasks.nvim\" width=\"100%\"\u003e\n\u003c/p\u003e\n\n\u003cp align=\"center\"\u003e\n  \u003ca href=\"https://github.com/jjuchara/obsidian-tasks.nvim/actions/workflows/ci.yml\"\u003e\u003cimg src=\"https://img.shields.io/github/actions/workflow/status/jjuchara/obsidian-tasks.nvim/ci.yml?branch=main\u0026style=for-the-badge\u0026logo=github\u0026label=tests\" alt=\"Tests\"\u003e\u003c/a\u003e\n  \u003ca href=\"https://github.com/jjuchara/obsidian-tasks.nvim/blob/main/LICENSE\"\u003e\u003cimg src=\"https://img.shields.io/github/license/jjuchara/obsidian-tasks.nvim?style=for-the-badge\u0026color=8b5cf6\" alt=\"MIT License\"\u003e\u003c/a\u003e\n  \u003cimg src=\"https://img.shields.io/badge/Neovim-0.10%2B-57A143?style=for-the-badge\u0026logo=neovim\u0026logoColor=white\" alt=\"Neovim 0.10+\"\u003e\n  \u003cimg src=\"https://img.shields.io/badge/dependencies-zero-22c55e?style=for-the-badge\" alt=\"Zero dependencies\"\u003e\n\u003c/p\u003e\n\n\u003cp align=\"center\"\u003e\n  A keyboard-first task cockpit for one or many Obsidian vaults.\u003cbr\u003e\n  Your Markdown stays the source of truth.\n\u003c/p\u003e\n\n\u003cp align=\"center\"\u003e\n  \u003ca href=\"#installation\"\u003eInstall\u003c/a\u003e ·\n  \u003ca href=\"#configuration\"\u003eConfigure\u003c/a\u003e ·\n  \u003ca href=\"#usage\"\u003eUse\u003c/a\u003e ·\n  \u003ca href=\"FUTURE.md\"\u003eRoadmap\u003c/a\u003e\n\u003c/p\u003e\n\n---\n\n## Why obsidian-tasks.nvim?\n\nKeep notes in Obsidian and stay in Neovim when it is time to execute. The plugin reads ordinary Markdown checkboxes, builds an ordered tag tree, and lets you complete or create tasks without introducing a database or rewriting your vault.\n\n| | Capability |\n|---|---|\n| 🗂️ | Combine multiple vaults in one view or switch repositories with tabs inside the task view |\n| 🌳 | Group tasks recursively by tag order: `#work #frontend #urgent` |\n| ⚡ | Complete tasks with `\u003cSpace\u003e` and append `✅ YYYY-MM-DD` automatically |\n| ✍️ | Create tasks through a guided repository, tag, start date, and deadline flow |\n| 🪟 | Use a centered floating window or a regular native split |\n| 🔒 | Detect stale source lines before writing and update files atomically |\n| 🧩 | Run on the built-in Neovim API with no required dependencies |\n\n## Installation\n\n### lazy.nvim\n\n```lua\n{\n  \"jjuchara/obsidian-tasks.nvim\",\n  opts = {\n    repositories = {\n      {\n        name = \"personal\",\n        alias = \"Personal tasks\",\n        path = \"~/notes/personal/Tasks.md\",\n      },\n    },\n    mappings = {\n      open = \"\u003cleader\u003eto\",\n      create = \"\u003cleader\u003eta\",\n    },\n  },\n}\n```\n\n### Native packages\n\n```sh\ngit clone https://github.com/jjuchara/obsidian-tasks.nvim \\\n  ~/.local/share/nvim/site/pack/plugins/start/obsidian-tasks.nvim\n```\n\nThen call `setup()` from your configuration.\n\n## Configuration\n\nThe only required option is `repositories`. A repository accepts either a direct `path` to a task file or a `vault` plus a relative `todo_file`. Its optional `alias` is used as the display label while `name` remains the repository identifier.\n\n```lua\nrequire(\"obsidian-tasks\").setup({\n  repositories = {\n    {\n      name = \"personal\",\n      alias = \"Personal tasks\",        -- optional display label\n      path = \"~/notes/personal/Tasks.md\",\n    },\n    {\n      name = \"work\",\n      vault = \"~/notes/work\",\n      todo_file = \"Projects/Tasks.md\",\n    },\n  },\n\n  view = {\n    type = \"float\",                 -- \"float\" or \"window\"\n    width = 0.5,                    -- fraction of editor width\n    height = 0.5,                   -- fraction of editor height\n    border = \"rounded\",\n    title = \" Obsidian tasks \",\n    close_on_leave = true,          -- close a float when focus leaves it\n    repository_mode = \"sections\",  -- \"sections\" or \"tabs\"\n    window_command = \"botright new\",\n    status = \"active\",             -- \"active\", \"done\", or \"all\"\n    sort = \"source\",               -- \"source\", \"deadline\", or \"title\"\n    filter = nil,                   -- optional initial tag filter, e.g. \"#work\"\n    fold_level = 99,                -- initially expand groups through this tag depth\n  },\n\n  dates = {\n    display_format = \"%d.%m.%Y\",  -- strftime format used in the task view\n  },\n\n  creation = {\n    default_start_today = true,\n    prompt_additional_tags = true,\n    infinity_marker = \"♾️\",\n  },\n\n  completion = {\n    marker = \"✅\",\n  },\n\n  mappings = {\n    open = \"\u003cleader\u003eto\",           -- global mapping, nil disables it\n    create = \"\u003cleader\u003eta\",         -- global mapping, nil disables it\n    create_in_view = \"a\",\n    toggle = \"\u003cSpace\u003e\",\n    edit = \"\u003cCR\u003e\",\n    delete = \"d\",\n    undo = \"u\",\n    open_source = \"gf\",\n    refresh = \"r\",\n    close = { \"q\", \"\u003cEsc\u003e\" },\n    cycle_status = \"s\",\n    cycle_sort = \"o\",\n    filter = \"f\",\n    next_repository = \"\u003cTab\u003e\",\n    previous_repository = \"\u003cS-Tab\u003e\",\n  },\n})\n```\n\n## Usage\n\n### Commands\n\n| Command | Action |\n|---|---|\n| `:ObsidianTasks` | Open the task view |\n| `:ObsidianTasksCreate` | Start the guided creation flow |\n| `:ObsidianTasksRefresh` | Reload every open task view |\n| `:ObsidianTasksSort [source\\|deadline\\|title]` | Set sorting, or cycle it without an argument |\n| `:ObsidianTasksFilter [#tag\\|clear]` | Select or set a tag filter, or clear it |\n\n### Task view\n\n| Key | Action |\n|---|---|\n| `a` | Create a task without leaving the task view |\n| `\u003cSpace\u003e` | Toggle the task under the cursor |\n| `\u003cCR\u003e` | Edit task text, tags, start date, and deadline |\n| `d` | Delete the task under the cursor after confirmation |\n| `u` | Undo the latest task operation |\n| `gf` | Open the Markdown source at the task line |\n| `s` | Cycle `active → done → all` |\n| `o` | Cycle `source → deadline → title` sorting |\n| `f` | Select a tag filter or clear the active filter |\n| `za`, `zc`, `zo` | Toggle, close, or open the tag group under the cursor |\n| `r` | Refresh from disk |\n| `q`, `\u003cEsc\u003e` | Close the view |\n\nA floating view is modal by default: clicking another window closes it. Set `view.close_on_leave = false` if you prefer a persistent float.\nTask-view mappings must be unique. For example, do not assign both `edit` and `open_source` to `\u003cCR\u003e`.\nTag filtering matches any tag on a task, remains active after refresh, and applies to every open task view.\nTag groups use native Neovim folds and expose a fold column for mouse interaction. Their expanded and collapsed states are preserved across refreshes, sorting, filtering, and repository navigation. Set `view.fold_level = 0` to start with top-level groups collapsed, or use a larger depth to reveal initial levels.\n\n### Creating a task\n\n1. Select a repository when more than one is configured.\n2. Enter the task text.\n3. Select or create the primary tag, press Space to choose the tag under the cursor, or press Enter immediately to continue without one.\n4. Choose any number of additional tags from the existing-tag list. Press Enter to continue, or press Space to toggle the tag under the cursor. Selected additional tags are marked with `[x]`; use `+ new tag...` to add and select a new tag.\n5. Confirm the start date and optional deadline. Enter `yesterday`, `today`, `tomorrow`, an ISO date such as `2026-07-10`, or a date matching `dates.display_format`. Leading zeroes are optional, so `7.3.2026` is accepted for `%d.%m.%Y`.\n\nThe completion notification shows the persisted tag path, for example `#work → #gantt`.\nWhen task creation starts from an open task view, the view stays open and the newly created task is focused after refresh.\nDates are always stored as `YYYY-MM-DD`. `dates.display_format` changes rendered dates and the examples shown in creation prompts without modifying Markdown. Active tasks due today or tomorrow use `ObsidianTasksDueSoon`; overdue tasks use `ObsidianTasksOverdue`.\nDeadline sorting adds virtual `#overdue`, `#due-soon`, and `#on-track` groups. `#due-soon` covers today and tomorrow; later deadlines, completed tasks, and tasks without deadlines are `#on-track`.\n\nEditing a task from the task view rewrites the Markdown task line while preserving the checkbox state, creation date, and completion date. Clearing the deadline stores the configured no-deadline marker.\n\n## Markdown format\n\n```markdown\n## #work\n\n- [ ] Ship the release #work #frontend #urgent 📅 2026-07-10\n- [x] Fix the regression #work #backend ✅ 2026-07-02\n```\n\nTags are significant from left to right:\n\n```text\n#work\n└── #frontend\n    └── #urgent\n        └── Ship the release\n```\n\nWhen a task has no inline tag, the nearest `## #tag` heading is used as a fallback. YAML frontmatter and fenced code blocks are ignored.\n\n## Multiple repositories\n\n`repository_mode = \"sections\"` renders all repositories in one buffer with repository headers. `repository_mode = \"tabs\"` shows repository tabs inside the task view and renders tasks from the active repository. Use `\u003cTab\u003e` / `\u003cS-Tab\u003e` or click a tab to switch repositories.\n\n## Development\n\nRun the test suite without a plugin manager:\n\n```sh\nnvim --headless -u NONE -i NONE \\\n  \"+set rtp+=$PWD\" \\\n  \"+luafile tests/run.lua\" \\\n  +qa\n```\n\nSee [CONTRIBUTING.md](CONTRIBUTING.md) for the contribution workflow and `:help obsidian-tasks` for the built-in manual.\n\n## Status\n\nThe core workflow is usable today. Advanced queries, recurrence, and live filesystem watching are tracked in [FUTURE.md](FUTURE.md).\n\n## License\n\n[MIT](LICENSE) © 2026 jjuchara\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fjjuchara%2Fobsidian-tasks.nvim","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fjjuchara%2Fobsidian-tasks.nvim","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fjjuchara%2Fobsidian-tasks.nvim/lists"}