Skip to content

Obsidian Tasks support: date-aware, filterable task index (phased) #751

Description

@srid

Summary

Make Emanote's task index (/-/tasks) a date-aware, filterable dashboard by understanding Obsidian Tasks emoji syntax. Tasks stay authored inline in their notes (- [ ] …); only the rendering gets smarter. Emanote stays read-only — completing/rolling tasks is the editor's job; Emanote displays.

Motivating use case: a calm, pull-not-push daily task dashboard (GTD "open loops" style) — a view you open, never a nag.

Authoring syntax (target)

Standard Obsidian Tasks emoji, appended to any - [ ] line:

- [ ] Draft the release notes 📅 2026-07-03 #active
- [ ] Follow up with the vendor ⏳ 2026-12-01 🔼 #waiting
- [ ] Send the monthly report 📅 2026-07-21 🔁 every month #active
Emoji Meaning Phase
📅 due · scheduled · 🛫 start dates 1
created · done · cancelled dates 1
🔺⏫🔼🔽⏬ priority 3
🔁 recurrence rule 3
🆔 / id / depends-on later

Task "state" (e.g. active/waiting/held/someday for a loop workflow) is just a #tag — already supported, no new syntax. Hierarchical tags (#loop/active, #loop/held, …) are recommended so related states share a namespace and filter as a group (loop/*).

Current behaviour (baseline)

/-/tasks (View/TaskIndex.hs) lists unchecked tasks, grouped by note, in path order; no dates, no filtering. Emoji/dates render as literal text. Tasks can't be filtered by tag (a task's inline #tag tags the note, not the task). This proposal changes that.


Phase 1 — Show task dates (PR 1)

You get: every task on /-/tasks shows its due/scheduled date as a badge, with overdue in red and due-today highlighted (computed live from the browser clock, so it never goes stale on the static site).

  • Parse the date emoji from each task's inlines into the task model (_taskDueDate, _taskScheduled, …); strip the recognised tokens from the rendered text and emit badges instead.
  • Parse in Emanote's task layer (Model/Task.hs) — no change to the heist-extra parser needed.
  • Template emits data-due etc.; a tiny vanilla loops.js adds the overdue/today classes. JS-off still shows the plain list.

Phase 2 — Filter & sort dashboard (PR 2)

You get: /-/tasks becomes a real dashboard — filter by tag (hierarchical, so namespaced states filter individually or as foo/*) and by due window (overdue · next 3 days · all), sort by due, and toggle group-by-note ⇄ a flat agenda. Default view = "what needs me soon."

  • Emit data-tags per task; client-side controls do the filtering/sorting (no rebuild).
  • A small load count ("12 open · 3 due") for at-a-glance load.

Phase 3 — Priority & recurrence (PR 3)

You get: priority badges (/🔼/🔽) that sort, and recurring tasks (🔁) shown with their rule and a computed next due.

  • Parse priority + recurrence; extend sort to (overdue, priority, due).
  • Recurrence is display only — Emanote doesn't mutate files.

Phase 4 — Embedded task queries (PR 4)

You get: drop a query into any note to embed a filtered task list — e.g. a hand-made dashboard page showing "all #active due this week." Composability beyond the global /-/tasks.

  • Extend the query mechanism (Model/Query.hs, currently note-only) with a tasks source + a render template, reusing the Phase 1–3 parsing.

Non-goals

  • Reminders / push. Pull-not-push — a view you open, not a nag. No notifications, no server.
  • Editing/completing tasks. Emanote renders; an editor (or external tooling) mutates the Markdown.

Key files

heist-extra:TaskList.hs (low-level parse) · Model/Task.hs (indexed task + new metadata) · View/TaskIndex.hs + templates/special/tasks.tpl (the view) · Model/Query.hs (Phase 4) · new default/js/loops.js.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions