heph.nvim: task views — next/list/capture/attention/state/log (slice 11b)
Backend: enrich `list` to return titled RankedTask rows (title +
canonical_context_id, via a shared ranked_from_row with `next`), so the
Organizational view needs no N+1 node.get. TDD: query_surface test asserts
list rows carry title + context id.
Plugin:
- view.lua: Tactical `next` + Organizational `list` rendered scratch buffers;
<CR> opens the row's canonical-context doc. Narrowed the node autocmd to
heph://node/* so view buffers (heph://next, heph://list) don't trip it.
- task.lua: capture, set-attention, done/drop, skip, per-task log append, all
resolving "the current task" from the buffer (a task node, or a context doc
via its canonical-context backlink).
- picker.lua: vim.ui.select with Telescope auto-upgrade (headless-safe).
- command.lua: :Heph next/list/capture/attention/done/drop/skip/log/search.
e2e: capture→next→open context→add/check checklist→done; recurring
fresh-checklist (complete rolls forward in place, next occurrence all-unchecked
— the §4.4 hard requirement). 6 specs green via `mise run test-nvim`.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-01 21:12:56 -07:00
|
|
|
--- Task list views (tech-spec §8): Tactical `next` (the "what is next?" ranking)
|
|
|
|
|
--- and Organizational `list` (the whole outstanding set). Both render the same
|
2026-06-02 11:48:09 -07:00
|
|
|
--- titled rows the daemon returns into a scratch buffer, and are interactive:
|
|
|
|
|
--- <CR> open the task's canonical-context doc
|
|
|
|
|
--- a add a new task (prompt title + attention) from the list
|
|
|
|
|
--- d mark the task under the cursor done
|
|
|
|
|
--- r refresh
|
heph.nvim: task views — next/list/capture/attention/state/log (slice 11b)
Backend: enrich `list` to return titled RankedTask rows (title +
canonical_context_id, via a shared ranked_from_row with `next`), so the
Organizational view needs no N+1 node.get. TDD: query_surface test asserts
list rows carry title + context id.
Plugin:
- view.lua: Tactical `next` + Organizational `list` rendered scratch buffers;
<CR> opens the row's canonical-context doc. Narrowed the node autocmd to
heph://node/* so view buffers (heph://next, heph://list) don't trip it.
- task.lua: capture, set-attention, done/drop, skip, per-task log append, all
resolving "the current task" from the buffer (a task node, or a context doc
via its canonical-context backlink).
- picker.lua: vim.ui.select with Telescope auto-upgrade (headless-safe).
- command.lua: :Heph next/list/capture/attention/done/drop/skip/log/search.
e2e: capture→next→open context→add/check checklist→done; recurring
fresh-checklist (complete rolls forward in place, next occurrence all-unchecked
— the §4.4 hard requirement). 6 specs green via `mise run test-nvim`.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-01 21:12:56 -07:00
|
|
|
local rpc = require("heph.rpc")
|
|
|
|
|
|
|
|
|
|
local M = {}
|
|
|
|
|
|
2026-06-02 11:48:09 -07:00
|
|
|
-- buf -> { tasks = <RankedTask[]>, refresh = fn }; line N maps to tasks[N].
|
heph.nvim: task views — next/list/capture/attention/state/log (slice 11b)
Backend: enrich `list` to return titled RankedTask rows (title +
canonical_context_id, via a shared ranked_from_row with `next`), so the
Organizational view needs no N+1 node.get. TDD: query_surface test asserts
list rows carry title + context id.
Plugin:
- view.lua: Tactical `next` + Organizational `list` rendered scratch buffers;
<CR> opens the row's canonical-context doc. Narrowed the node autocmd to
heph://node/* so view buffers (heph://next, heph://list) don't trip it.
- task.lua: capture, set-attention, done/drop, skip, per-task log append, all
resolving "the current task" from the buffer (a task node, or a context doc
via its canonical-context backlink).
- picker.lua: vim.ui.select with Telescope auto-upgrade (headless-safe).
- command.lua: :Heph next/list/capture/attention/done/drop/skip/log/search.
e2e: capture→next→open context→add/check checklist→done; recurring
fresh-checklist (complete rolls forward in place, next occurrence all-unchecked
— the §4.4 hard requirement). 6 specs green via `mise run test-nvim`.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-01 21:12:56 -07:00
|
|
|
M._views = {}
|
|
|
|
|
|
2026-06-02 11:48:09 -07:00
|
|
|
local hint_ns = vim.api.nvim_create_namespace("heph_view_hint")
|
|
|
|
|
local HINT = " <CR> open a add d done r refresh"
|
|
|
|
|
|
|
|
|
|
local ATTENTIONS = { "white", "orange", "red", "blue" }
|
|
|
|
|
|
2026-06-03 11:05:02 -07:00
|
|
|
-- Compact relative date for a do/late epoch-ms value (mirrors heph-tui's fmt):
|
|
|
|
|
-- today / tomorrow / yesterday, MM-DD within the year, else YYYY-MM-DD.
|
|
|
|
|
local function fmt_date(ms)
|
|
|
|
|
local d = os.date("*t", math.floor(ms / 1000))
|
|
|
|
|
local n = os.date("*t")
|
|
|
|
|
local d_noon = os.time({ year = d.year, month = d.month, day = d.day, hour = 12 })
|
|
|
|
|
local n_noon = os.time({ year = n.year, month = n.month, day = n.day, hour = 12 })
|
|
|
|
|
local days = math.floor((d_noon - n_noon) / 86400 + 0.5)
|
|
|
|
|
if days == 0 then
|
|
|
|
|
return "today"
|
|
|
|
|
elseif days == 1 then
|
|
|
|
|
return "tomorrow"
|
|
|
|
|
elseif days == -1 then
|
|
|
|
|
return "yesterday"
|
|
|
|
|
elseif d.year == n.year then
|
|
|
|
|
return string.format("%02d-%02d", d.month, d.day)
|
|
|
|
|
else
|
|
|
|
|
return string.format("%04d-%02d-%02d", d.year, d.month, d.day)
|
|
|
|
|
end
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
-- The right-side date chip: a late marker once past due, else the do-date.
|
|
|
|
|
local function date_chip(t)
|
|
|
|
|
if t.late_on and os.time() * 1000 > t.late_on then
|
|
|
|
|
return "late:" .. fmt_date(t.late_on)
|
|
|
|
|
elseif t.do_date then
|
|
|
|
|
return "do:" .. fmt_date(t.do_date)
|
|
|
|
|
end
|
|
|
|
|
return ""
|
|
|
|
|
end
|
|
|
|
|
|
heph.nvim: task views — next/list/capture/attention/state/log (slice 11b)
Backend: enrich `list` to return titled RankedTask rows (title +
canonical_context_id, via a shared ranked_from_row with `next`), so the
Organizational view needs no N+1 node.get. TDD: query_surface test asserts
list rows carry title + context id.
Plugin:
- view.lua: Tactical `next` + Organizational `list` rendered scratch buffers;
<CR> opens the row's canonical-context doc. Narrowed the node autocmd to
heph://node/* so view buffers (heph://next, heph://list) don't trip it.
- task.lua: capture, set-attention, done/drop, skip, per-task log append, all
resolving "the current task" from the buffer (a task node, or a context doc
via its canonical-context backlink).
- picker.lua: vim.ui.select with Telescope auto-upgrade (headless-safe).
- command.lua: :Heph next/list/capture/attention/done/drop/skip/log/search.
e2e: capture→next→open context→add/check checklist→done; recurring
fresh-checklist (complete rolls forward in place, next occurrence all-unchecked
— the §4.4 hard requirement). 6 specs green via `mise run test-nvim`.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-01 21:12:56 -07:00
|
|
|
local function row(t)
|
|
|
|
|
local tag = t.attention and ("[" .. t.attention .. "]") or "[ ]"
|
2026-06-03 11:05:02 -07:00
|
|
|
local recur = t.recurrence and " ↻" or ""
|
|
|
|
|
local left = string.format("%s %s%s", tag, t.title, recur)
|
|
|
|
|
local chip = date_chip(t)
|
|
|
|
|
if chip ~= "" then
|
|
|
|
|
return string.format("%-50s %s", left, chip)
|
|
|
|
|
end
|
|
|
|
|
return left
|
heph.nvim: task views — next/list/capture/attention/state/log (slice 11b)
Backend: enrich `list` to return titled RankedTask rows (title +
canonical_context_id, via a shared ranked_from_row with `next`), so the
Organizational view needs no N+1 node.get. TDD: query_surface test asserts
list rows carry title + context id.
Plugin:
- view.lua: Tactical `next` + Organizational `list` rendered scratch buffers;
<CR> opens the row's canonical-context doc. Narrowed the node autocmd to
heph://node/* so view buffers (heph://next, heph://list) don't trip it.
- task.lua: capture, set-attention, done/drop, skip, per-task log append, all
resolving "the current task" from the buffer (a task node, or a context doc
via its canonical-context backlink).
- picker.lua: vim.ui.select with Telescope auto-upgrade (headless-safe).
- command.lua: :Heph next/list/capture/attention/done/drop/skip/log/search.
e2e: capture→next→open context→add/check checklist→done; recurring
fresh-checklist (complete rolls forward in place, next occurrence all-unchecked
— the §4.4 hard requirement). 6 specs green via `mise run test-nvim`.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-01 21:12:56 -07:00
|
|
|
end
|
|
|
|
|
|
2026-06-02 11:48:09 -07:00
|
|
|
local function task_on_line(buf)
|
|
|
|
|
local view = M._views[buf]
|
|
|
|
|
if not view then
|
|
|
|
|
return nil
|
|
|
|
|
end
|
2026-06-02 12:01:36 -07:00
|
|
|
-- line 1 is the key-hint header; task rows start at line 2.
|
|
|
|
|
return view.tasks[vim.api.nvim_win_get_cursor(0)[1] - 1]
|
2026-06-02 11:48:09 -07:00
|
|
|
end
|
|
|
|
|
|
|
|
|
|
-- Find or create the named scratch buffer, fill it, and (re)bind its keymaps.
|
|
|
|
|
-- `refresh` re-runs the query+render so actions can reflect their changes.
|
|
|
|
|
local function render(name, tasks, refresh)
|
heph.nvim: task views — next/list/capture/attention/state/log (slice 11b)
Backend: enrich `list` to return titled RankedTask rows (title +
canonical_context_id, via a shared ranked_from_row with `next`), so the
Organizational view needs no N+1 node.get. TDD: query_surface test asserts
list rows carry title + context id.
Plugin:
- view.lua: Tactical `next` + Organizational `list` rendered scratch buffers;
<CR> opens the row's canonical-context doc. Narrowed the node autocmd to
heph://node/* so view buffers (heph://next, heph://list) don't trip it.
- task.lua: capture, set-attention, done/drop, skip, per-task log append, all
resolving "the current task" from the buffer (a task node, or a context doc
via its canonical-context backlink).
- picker.lua: vim.ui.select with Telescope auto-upgrade (headless-safe).
- command.lua: :Heph next/list/capture/attention/done/drop/skip/log/search.
e2e: capture→next→open context→add/check checklist→done; recurring
fresh-checklist (complete rolls forward in place, next occurrence all-unchecked
— the §4.4 hard requirement). 6 specs green via `mise run test-nvim`.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-01 21:12:56 -07:00
|
|
|
local buf
|
|
|
|
|
for _, b in ipairs(vim.api.nvim_list_bufs()) do
|
|
|
|
|
if vim.api.nvim_buf_get_name(b) == name then
|
|
|
|
|
buf = b
|
|
|
|
|
break
|
|
|
|
|
end
|
|
|
|
|
end
|
|
|
|
|
if not buf then
|
|
|
|
|
buf = vim.api.nvim_create_buf(false, true) -- unlisted scratch
|
|
|
|
|
vim.api.nvim_buf_set_name(buf, name)
|
|
|
|
|
end
|
|
|
|
|
vim.bo[buf].buftype = "nofile"
|
|
|
|
|
vim.bo[buf].bufhidden = "hide"
|
|
|
|
|
vim.bo[buf].swapfile = false
|
|
|
|
|
|
2026-06-02 12:01:36 -07:00
|
|
|
-- Line 1 is a dimmed key hint; task rows follow.
|
|
|
|
|
local lines = { HINT }
|
heph.nvim: task views — next/list/capture/attention/state/log (slice 11b)
Backend: enrich `list` to return titled RankedTask rows (title +
canonical_context_id, via a shared ranked_from_row with `next`), so the
Organizational view needs no N+1 node.get. TDD: query_surface test asserts
list rows carry title + context id.
Plugin:
- view.lua: Tactical `next` + Organizational `list` rendered scratch buffers;
<CR> opens the row's canonical-context doc. Narrowed the node autocmd to
heph://node/* so view buffers (heph://next, heph://list) don't trip it.
- task.lua: capture, set-attention, done/drop, skip, per-task log append, all
resolving "the current task" from the buffer (a task node, or a context doc
via its canonical-context backlink).
- picker.lua: vim.ui.select with Telescope auto-upgrade (headless-safe).
- command.lua: :Heph next/list/capture/attention/done/drop/skip/log/search.
e2e: capture→next→open context→add/check checklist→done; recurring
fresh-checklist (complete rolls forward in place, next occurrence all-unchecked
— the §4.4 hard requirement). 6 specs green via `mise run test-nvim`.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-01 21:12:56 -07:00
|
|
|
for _, t in ipairs(tasks) do
|
|
|
|
|
lines[#lines + 1] = row(t)
|
|
|
|
|
end
|
2026-06-02 12:01:36 -07:00
|
|
|
if #tasks == 0 then
|
|
|
|
|
lines[#lines + 1] = "(nothing here — press 'a' to add a task)"
|
heph.nvim: task views — next/list/capture/attention/state/log (slice 11b)
Backend: enrich `list` to return titled RankedTask rows (title +
canonical_context_id, via a shared ranked_from_row with `next`), so the
Organizational view needs no N+1 node.get. TDD: query_surface test asserts
list rows carry title + context id.
Plugin:
- view.lua: Tactical `next` + Organizational `list` rendered scratch buffers;
<CR> opens the row's canonical-context doc. Narrowed the node autocmd to
heph://node/* so view buffers (heph://next, heph://list) don't trip it.
- task.lua: capture, set-attention, done/drop, skip, per-task log append, all
resolving "the current task" from the buffer (a task node, or a context doc
via its canonical-context backlink).
- picker.lua: vim.ui.select with Telescope auto-upgrade (headless-safe).
- command.lua: :Heph next/list/capture/attention/done/drop/skip/log/search.
e2e: capture→next→open context→add/check checklist→done; recurring
fresh-checklist (complete rolls forward in place, next occurrence all-unchecked
— the §4.4 hard requirement). 6 specs green via `mise run test-nvim`.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-01 21:12:56 -07:00
|
|
|
end
|
|
|
|
|
vim.bo[buf].modifiable = true
|
|
|
|
|
vim.api.nvim_buf_set_lines(buf, 0, -1, false, lines)
|
|
|
|
|
vim.bo[buf].modifiable = false
|
|
|
|
|
|
2026-06-02 11:48:09 -07:00
|
|
|
vim.api.nvim_buf_clear_namespace(buf, hint_ns, 0, -1)
|
|
|
|
|
vim.api.nvim_buf_set_extmark(buf, hint_ns, 0, 0, {
|
2026-06-02 12:01:36 -07:00
|
|
|
end_row = 0,
|
|
|
|
|
end_col = #HINT,
|
|
|
|
|
hl_group = "Comment",
|
2026-06-02 11:48:09 -07:00
|
|
|
})
|
|
|
|
|
|
|
|
|
|
M._views[buf] = { tasks = tasks, refresh = refresh }
|
|
|
|
|
local function map(lhs, fn, desc)
|
|
|
|
|
vim.keymap.set("n", lhs, fn, { buffer = buf, desc = desc })
|
|
|
|
|
end
|
|
|
|
|
map("<CR>", function()
|
heph.nvim: task views — next/list/capture/attention/state/log (slice 11b)
Backend: enrich `list` to return titled RankedTask rows (title +
canonical_context_id, via a shared ranked_from_row with `next`), so the
Organizational view needs no N+1 node.get. TDD: query_surface test asserts
list rows carry title + context id.
Plugin:
- view.lua: Tactical `next` + Organizational `list` rendered scratch buffers;
<CR> opens the row's canonical-context doc. Narrowed the node autocmd to
heph://node/* so view buffers (heph://next, heph://list) don't trip it.
- task.lua: capture, set-attention, done/drop, skip, per-task log append, all
resolving "the current task" from the buffer (a task node, or a context doc
via its canonical-context backlink).
- picker.lua: vim.ui.select with Telescope auto-upgrade (headless-safe).
- command.lua: :Heph next/list/capture/attention/done/drop/skip/log/search.
e2e: capture→next→open context→add/check checklist→done; recurring
fresh-checklist (complete rolls forward in place, next occurrence all-unchecked
— the §4.4 hard requirement). 6 specs green via `mise run test-nvim`.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-01 21:12:56 -07:00
|
|
|
M.open_under_cursor(buf)
|
2026-06-02 11:48:09 -07:00
|
|
|
end, "heph: open task context")
|
|
|
|
|
map("a", function()
|
|
|
|
|
M.add_from(buf)
|
|
|
|
|
end, "heph: add a task")
|
|
|
|
|
map("d", function()
|
|
|
|
|
M.done_under_cursor(buf)
|
|
|
|
|
end, "heph: mark task done")
|
|
|
|
|
map("r", function()
|
|
|
|
|
M.refresh(buf)
|
|
|
|
|
end, "heph: refresh")
|
heph.nvim: task views — next/list/capture/attention/state/log (slice 11b)
Backend: enrich `list` to return titled RankedTask rows (title +
canonical_context_id, via a shared ranked_from_row with `next`), so the
Organizational view needs no N+1 node.get. TDD: query_surface test asserts
list rows carry title + context id.
Plugin:
- view.lua: Tactical `next` + Organizational `list` rendered scratch buffers;
<CR> opens the row's canonical-context doc. Narrowed the node autocmd to
heph://node/* so view buffers (heph://next, heph://list) don't trip it.
- task.lua: capture, set-attention, done/drop, skip, per-task log append, all
resolving "the current task" from the buffer (a task node, or a context doc
via its canonical-context backlink).
- picker.lua: vim.ui.select with Telescope auto-upgrade (headless-safe).
- command.lua: :Heph next/list/capture/attention/done/drop/skip/log/search.
e2e: capture→next→open context→add/check checklist→done; recurring
fresh-checklist (complete rolls forward in place, next occurrence all-unchecked
— the §4.4 hard requirement). 6 specs green via `mise run test-nvim`.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-01 21:12:56 -07:00
|
|
|
vim.api.nvim_set_current_buf(buf)
|
2026-06-02 12:01:36 -07:00
|
|
|
if #tasks > 0 then
|
|
|
|
|
pcall(vim.api.nvim_win_set_cursor, 0, { 2, 0 }) -- land on the first task row
|
|
|
|
|
end
|
heph.nvim: task views — next/list/capture/attention/state/log (slice 11b)
Backend: enrich `list` to return titled RankedTask rows (title +
canonical_context_id, via a shared ranked_from_row with `next`), so the
Organizational view needs no N+1 node.get. TDD: query_surface test asserts
list rows carry title + context id.
Plugin:
- view.lua: Tactical `next` + Organizational `list` rendered scratch buffers;
<CR> opens the row's canonical-context doc. Narrowed the node autocmd to
heph://node/* so view buffers (heph://next, heph://list) don't trip it.
- task.lua: capture, set-attention, done/drop, skip, per-task log append, all
resolving "the current task" from the buffer (a task node, or a context doc
via its canonical-context backlink).
- picker.lua: vim.ui.select with Telescope auto-upgrade (headless-safe).
- command.lua: :Heph next/list/capture/attention/done/drop/skip/log/search.
e2e: capture→next→open context→add/check checklist→done; recurring
fresh-checklist (complete rolls forward in place, next occurrence all-unchecked
— the §4.4 hard requirement). 6 specs green via `mise run test-nvim`.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-01 21:12:56 -07:00
|
|
|
return buf
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
--- Open the canonical-context doc of the task on the cursor line.
|
|
|
|
|
function M.open_under_cursor(buf)
|
|
|
|
|
buf = buf or vim.api.nvim_get_current_buf()
|
2026-06-02 11:48:09 -07:00
|
|
|
local t = task_on_line(buf)
|
|
|
|
|
if t then
|
|
|
|
|
require("heph.node").open(t.canonical_context_id or t.node_id)
|
|
|
|
|
end
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
--- Re-run the view's query and re-render in place.
|
|
|
|
|
function M.refresh(buf)
|
|
|
|
|
local view = M._views[buf or vim.api.nvim_get_current_buf()]
|
|
|
|
|
if view and view.refresh then
|
|
|
|
|
view.refresh()
|
heph.nvim: task views — next/list/capture/attention/state/log (slice 11b)
Backend: enrich `list` to return titled RankedTask rows (title +
canonical_context_id, via a shared ranked_from_row with `next`), so the
Organizational view needs no N+1 node.get. TDD: query_surface test asserts
list rows carry title + context id.
Plugin:
- view.lua: Tactical `next` + Organizational `list` rendered scratch buffers;
<CR> opens the row's canonical-context doc. Narrowed the node autocmd to
heph://node/* so view buffers (heph://next, heph://list) don't trip it.
- task.lua: capture, set-attention, done/drop, skip, per-task log append, all
resolving "the current task" from the buffer (a task node, or a context doc
via its canonical-context backlink).
- picker.lua: vim.ui.select with Telescope auto-upgrade (headless-safe).
- command.lua: :Heph next/list/capture/attention/done/drop/skip/log/search.
e2e: capture→next→open context→add/check checklist→done; recurring
fresh-checklist (complete rolls forward in place, next occurrence all-unchecked
— the §4.4 hard requirement). 6 specs green via `mise run test-nvim`.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-01 21:12:56 -07:00
|
|
|
end
|
2026-06-02 11:48:09 -07:00
|
|
|
end
|
|
|
|
|
|
|
|
|
|
--- Add a task from the list: prompt a title, pick an attention, capture, refresh.
|
|
|
|
|
function M.add_from(buf)
|
|
|
|
|
vim.ui.input({ prompt = "New task: " }, function(title)
|
|
|
|
|
if not title or #title == 0 then
|
|
|
|
|
return
|
|
|
|
|
end
|
|
|
|
|
require("heph.picker").select(ATTENTIONS, { prompt = "attention for: " .. title }, function(attention)
|
|
|
|
|
require("heph.task").capture(title, { attention = attention })
|
|
|
|
|
require("heph.util").notify("captured: " .. title)
|
|
|
|
|
M.refresh(buf)
|
|
|
|
|
end)
|
|
|
|
|
end)
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
--- Mark the task on the cursor line done, then refresh.
|
|
|
|
|
function M.done_under_cursor(buf)
|
|
|
|
|
local t = task_on_line(buf)
|
heph.nvim: task views — next/list/capture/attention/state/log (slice 11b)
Backend: enrich `list` to return titled RankedTask rows (title +
canonical_context_id, via a shared ranked_from_row with `next`), so the
Organizational view needs no N+1 node.get. TDD: query_surface test asserts
list rows carry title + context id.
Plugin:
- view.lua: Tactical `next` + Organizational `list` rendered scratch buffers;
<CR> opens the row's canonical-context doc. Narrowed the node autocmd to
heph://node/* so view buffers (heph://next, heph://list) don't trip it.
- task.lua: capture, set-attention, done/drop, skip, per-task log append, all
resolving "the current task" from the buffer (a task node, or a context doc
via its canonical-context backlink).
- picker.lua: vim.ui.select with Telescope auto-upgrade (headless-safe).
- command.lua: :Heph next/list/capture/attention/done/drop/skip/log/search.
e2e: capture→next→open context→add/check checklist→done; recurring
fresh-checklist (complete rolls forward in place, next occurrence all-unchecked
— the §4.4 hard requirement). 6 specs green via `mise run test-nvim`.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-01 21:12:56 -07:00
|
|
|
if not t then
|
|
|
|
|
return
|
|
|
|
|
end
|
2026-06-02 11:48:09 -07:00
|
|
|
rpc.call("task.set_state", { id = t.node_id, state = "done" })
|
|
|
|
|
require("heph.util").notify("done: " .. t.title)
|
|
|
|
|
M.refresh(buf)
|
heph.nvim: task views — next/list/capture/attention/state/log (slice 11b)
Backend: enrich `list` to return titled RankedTask rows (title +
canonical_context_id, via a shared ranked_from_row with `next`), so the
Organizational view needs no N+1 node.get. TDD: query_surface test asserts
list rows carry title + context id.
Plugin:
- view.lua: Tactical `next` + Organizational `list` rendered scratch buffers;
<CR> opens the row's canonical-context doc. Narrowed the node autocmd to
heph://node/* so view buffers (heph://next, heph://list) don't trip it.
- task.lua: capture, set-attention, done/drop, skip, per-task log append, all
resolving "the current task" from the buffer (a task node, or a context doc
via its canonical-context backlink).
- picker.lua: vim.ui.select with Telescope auto-upgrade (headless-safe).
- command.lua: :Heph next/list/capture/attention/done/drop/skip/log/search.
e2e: capture→next→open context→add/check checklist→done; recurring
fresh-checklist (complete rolls forward in place, next occurrence all-unchecked
— the §4.4 hard requirement). 6 specs green via `mise run test-nvim`.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-01 21:12:56 -07:00
|
|
|
end
|
|
|
|
|
|
|
|
|
|
--- Tactical "what is next?" — render the ranking, return the rows.
|
|
|
|
|
function M.next(opts)
|
|
|
|
|
opts = opts or {}
|
|
|
|
|
local tasks = rpc.call("next", { scope = opts.scope, limit = opts.limit or 5 })
|
2026-06-02 11:48:09 -07:00
|
|
|
render("heph://next", tasks, function()
|
|
|
|
|
M.next(opts)
|
|
|
|
|
end)
|
heph.nvim: task views — next/list/capture/attention/state/log (slice 11b)
Backend: enrich `list` to return titled RankedTask rows (title +
canonical_context_id, via a shared ranked_from_row with `next`), so the
Organizational view needs no N+1 node.get. TDD: query_surface test asserts
list rows carry title + context id.
Plugin:
- view.lua: Tactical `next` + Organizational `list` rendered scratch buffers;
<CR> opens the row's canonical-context doc. Narrowed the node autocmd to
heph://node/* so view buffers (heph://next, heph://list) don't trip it.
- task.lua: capture, set-attention, done/drop, skip, per-task log append, all
resolving "the current task" from the buffer (a task node, or a context doc
via its canonical-context backlink).
- picker.lua: vim.ui.select with Telescope auto-upgrade (headless-safe).
- command.lua: :Heph next/list/capture/attention/done/drop/skip/log/search.
e2e: capture→next→open context→add/check checklist→done; recurring
fresh-checklist (complete rolls forward in place, next occurrence all-unchecked
— the §4.4 hard requirement). 6 specs green via `mise run test-nvim`.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-01 21:12:56 -07:00
|
|
|
return tasks
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
--- Organizational survey — render the outstanding set, return the rows.
|
feat(views): filter views (§8.2) — saved agenda slices
Make the owner's saved filters first-class so the agenda isn't one flat
list. `list` now takes a ListFilter predicate-as-data (heph-core::filter):
attention include/exclude sets, project-id scope, exclude_projects, and an
actionable do-date gate. New Store::view(name) resolves a built-in ViewSpec
— looking project names up to ids and subtree-expanding them through parent
links — then lists.
Five built-ins seeded from the Todoist queries (design §6.2.1): tom, ondeck,
chores, work, tasks (Schedule dropped — time-of-day isn't modeled on
date-grained do-dates). Surfaced as `heph view <name>` (no name lists them),
the `view` RPC + RemoteStore forward, and `:Heph view <name>` in nvim.
The list RPC/RemoteStore/CLI/heph.nvim migrate to the filter wire; legacy
--scope/--attention/--no-blue map onto it (nvim view.lua updated).
Tests: filter unit predicate, a views integration suite (subtree
scope+exclude, actionable gate, unknown-view error, absent-project empties),
a socket list/view dispatch test, two nvim e2e specs. 154 Rust tests + 18
nvim e2e green; clippy/fmt clean.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-03 06:39:07 -07:00
|
|
|
--- `list` takes a ListFilter (tech-spec §8.2); an empty table is the whole
|
|
|
|
|
--- outstanding set. Legacy opts map onto the filter fields.
|
heph.nvim: task views — next/list/capture/attention/state/log (slice 11b)
Backend: enrich `list` to return titled RankedTask rows (title +
canonical_context_id, via a shared ranked_from_row with `next`), so the
Organizational view needs no N+1 node.get. TDD: query_surface test asserts
list rows carry title + context id.
Plugin:
- view.lua: Tactical `next` + Organizational `list` rendered scratch buffers;
<CR> opens the row's canonical-context doc. Narrowed the node autocmd to
heph://node/* so view buffers (heph://next, heph://list) don't trip it.
- task.lua: capture, set-attention, done/drop, skip, per-task log append, all
resolving "the current task" from the buffer (a task node, or a context doc
via its canonical-context backlink).
- picker.lua: vim.ui.select with Telescope auto-upgrade (headless-safe).
- command.lua: :Heph next/list/capture/attention/done/drop/skip/log/search.
e2e: capture→next→open context→add/check checklist→done; recurring
fresh-checklist (complete rolls forward in place, next occurrence all-unchecked
— the §4.4 hard requirement). 6 specs green via `mise run test-nvim`.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-01 21:12:56 -07:00
|
|
|
function M.list(opts)
|
|
|
|
|
opts = opts or {}
|
feat(views): filter views (§8.2) — saved agenda slices
Make the owner's saved filters first-class so the agenda isn't one flat
list. `list` now takes a ListFilter predicate-as-data (heph-core::filter):
attention include/exclude sets, project-id scope, exclude_projects, and an
actionable do-date gate. New Store::view(name) resolves a built-in ViewSpec
— looking project names up to ids and subtree-expanding them through parent
links — then lists.
Five built-ins seeded from the Todoist queries (design §6.2.1): tom, ondeck,
chores, work, tasks (Schedule dropped — time-of-day isn't modeled on
date-grained do-dates). Surfaced as `heph view <name>` (no name lists them),
the `view` RPC + RemoteStore forward, and `:Heph view <name>` in nvim.
The list RPC/RemoteStore/CLI/heph.nvim migrate to the filter wire; legacy
--scope/--attention/--no-blue map onto it (nvim view.lua updated).
Tests: filter unit predicate, a views integration suite (subtree
scope+exclude, actionable gate, unknown-view error, absent-project empties),
a socket list/view dispatch test, two nvim e2e specs. 154 Rust tests + 18
nvim e2e green; clippy/fmt clean.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-03 06:39:07 -07:00
|
|
|
local filter = {}
|
|
|
|
|
if opts.scope then
|
|
|
|
|
filter.scope = { opts.scope }
|
|
|
|
|
end
|
|
|
|
|
if opts.attention then
|
|
|
|
|
filter.attention_in = { opts.attention }
|
|
|
|
|
end
|
|
|
|
|
if opts.include_blue == false then
|
|
|
|
|
filter.attention_not = { "blue" }
|
|
|
|
|
end
|
|
|
|
|
local tasks = rpc.call("list", filter)
|
2026-06-02 11:48:09 -07:00
|
|
|
render("heph://list", tasks, function()
|
|
|
|
|
M.list(opts)
|
|
|
|
|
end)
|
heph.nvim: task views — next/list/capture/attention/state/log (slice 11b)
Backend: enrich `list` to return titled RankedTask rows (title +
canonical_context_id, via a shared ranked_from_row with `next`), so the
Organizational view needs no N+1 node.get. TDD: query_surface test asserts
list rows carry title + context id.
Plugin:
- view.lua: Tactical `next` + Organizational `list` rendered scratch buffers;
<CR> opens the row's canonical-context doc. Narrowed the node autocmd to
heph://node/* so view buffers (heph://next, heph://list) don't trip it.
- task.lua: capture, set-attention, done/drop, skip, per-task log append, all
resolving "the current task" from the buffer (a task node, or a context doc
via its canonical-context backlink).
- picker.lua: vim.ui.select with Telescope auto-upgrade (headless-safe).
- command.lua: :Heph next/list/capture/attention/done/drop/skip/log/search.
e2e: capture→next→open context→add/check checklist→done; recurring
fresh-checklist (complete rolls forward in place, next occurrence all-unchecked
— the §4.4 hard requirement). 6 specs green via `mise run test-nvim`.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-01 21:12:56 -07:00
|
|
|
return tasks
|
|
|
|
|
end
|
|
|
|
|
|
feat(views): filter views (§8.2) — saved agenda slices
Make the owner's saved filters first-class so the agenda isn't one flat
list. `list` now takes a ListFilter predicate-as-data (heph-core::filter):
attention include/exclude sets, project-id scope, exclude_projects, and an
actionable do-date gate. New Store::view(name) resolves a built-in ViewSpec
— looking project names up to ids and subtree-expanding them through parent
links — then lists.
Five built-ins seeded from the Todoist queries (design §6.2.1): tom, ondeck,
chores, work, tasks (Schedule dropped — time-of-day isn't modeled on
date-grained do-dates). Surfaced as `heph view <name>` (no name lists them),
the `view` RPC + RemoteStore forward, and `:Heph view <name>` in nvim.
The list RPC/RemoteStore/CLI/heph.nvim migrate to the filter wire; legacy
--scope/--attention/--no-blue map onto it (nvim view.lua updated).
Tests: filter unit predicate, a views integration suite (subtree
scope+exclude, actionable gate, unknown-view error, absent-project empties),
a socket list/view dispatch test, two nvim e2e specs. 154 Rust tests + 18
nvim e2e green; clippy/fmt clean.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-03 06:39:07 -07:00
|
|
|
--- A built-in filter view (tech-spec §8.2) — render its rows like `list`.
|
|
|
|
|
function M.view(name, opts)
|
|
|
|
|
opts = opts or {}
|
|
|
|
|
local tasks = rpc.call("view", { name = name })
|
|
|
|
|
render("heph://view/" .. name, tasks, function()
|
|
|
|
|
M.view(name, opts)
|
|
|
|
|
end)
|
|
|
|
|
return tasks
|
|
|
|
|
end
|
|
|
|
|
|
heph.nvim: task views — next/list/capture/attention/state/log (slice 11b)
Backend: enrich `list` to return titled RankedTask rows (title +
canonical_context_id, via a shared ranked_from_row with `next`), so the
Organizational view needs no N+1 node.get. TDD: query_surface test asserts
list rows carry title + context id.
Plugin:
- view.lua: Tactical `next` + Organizational `list` rendered scratch buffers;
<CR> opens the row's canonical-context doc. Narrowed the node autocmd to
heph://node/* so view buffers (heph://next, heph://list) don't trip it.
- task.lua: capture, set-attention, done/drop, skip, per-task log append, all
resolving "the current task" from the buffer (a task node, or a context doc
via its canonical-context backlink).
- picker.lua: vim.ui.select with Telescope auto-upgrade (headless-safe).
- command.lua: :Heph next/list/capture/attention/done/drop/skip/log/search.
e2e: capture→next→open context→add/check checklist→done; recurring
fresh-checklist (complete rolls forward in place, next occurrence all-unchecked
— the §4.4 hard requirement). 6 specs green via `mise run test-nvim`.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-01 21:12:56 -07:00
|
|
|
return M
|