Update nightwatch75/todo to 0.0.14 (#127)

Settings shortcut in the panel header, and long task text now wraps inside its
own column instead of running under the row buttons.

Co-authored-by: nightwatch75 <nightwatch75@users.noreply.github.com>
Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
nightwatch75
2026-07-28 21:14:29 -04:00
committed by GitHub
co-authored by nightwatch75 Claude Opus 5
parent 64a0edecb1
commit e07a4299c2
4 changed files with 61 additions and 4 deletions
+15 -1
View File
@@ -33,6 +33,14 @@ noctalia msg panel-toggle nightwatch75/todo:panel
| **Enter**, or ✓ (row) | Commit the edit — the row goes back to a static line |
| ☐ / ☑ button (row) | Toggle done/to-do (done tasks are struck through) |
| 🗑 button (row) | Delete the task |
| ⚙ button (panel header) | Open this plugin's page in *Settings → Plugins* |
That settings page also opens from the command line, so it can be bound in your
compositor too:
```sh
noctalia msg settings-open-plugin nightwatch75/todo
```
## Priorities
@@ -79,6 +87,10 @@ close.
Tick a task (☐ → ☑) to complete it — its text is struck through until you
un-tick it. The bar glyph's tooltip shows how many tasks are still to do.
A task longer than the row wraps onto further lines and the row grows to fit,
so the whole text stays readable and never runs under the buttons on the
right.
## Storage
Tasks live in one file, `todo.json`, inside the configured **To Do folder**
@@ -111,7 +123,9 @@ noctalia msg plugins enable nightwatch75/todo
## Requirements
- noctalia with plugin API ≥ 5 (declarative drag-and-drop)
- noctalia v5.0.0-beta.6 or newer — the first tagged release that accepts
`plugin_api = 15` (`noctalia.openSettings()`, the panel's ⚙ button;
declarative drag-and-drop needs 5)
- No external dependencies
## License
+43 -1
View File
@@ -30,6 +30,38 @@
-- The bar widget (todo.luau) lights its glyph while the panel is open via the
-- shared "todo_open" state; it reads todo.json itself for the pending count.
-- Row width budget. A Button constrains its label only when it has an explicit
-- width (the host derives the label's max width from it); flexGrow alone lets a
-- long task overrun the buttons to its right instead of shrinking. So the text
-- button is given whatever the fixed parts of the row leave over.
--
-- The constrained label WRAPS, it does not ellipsize: Button sets the label's
-- maxWidth and TextEllipsize::End but never a maxLines, and the text renderer
-- only ellipsizes against an explicit line budget — with maxLines 0 Pango is
-- given the full 500-line backstop and wraps freely. Wrapping is what we want
-- here (the whole task stays readable), and the row grows to fit because
-- Button pins only a minimum height.
-- Every constant below mirrors one in noctalia's Style, named so the sum can be
-- re-checked against the host rather than re-measured by eye.
local PANEL_WIDTH = 400 -- keep in sync with [[panel]] width in plugin.toml
local PANEL_PADDING = 14 -- Style::panelPadding, applied left and right
local SCROLLBAR_GUTTER = 14 -- Style::scrollbarWidth (6) + Style::scrollbarGap (8)
local ROW_GAP = 8 -- the task row's own gap
local CHIP_W = 16 -- the priority chip
local GRIP_W = 24 -- the ☰ drag grip, manual mode only
local GLYPH_BTN_W = 30 -- ghost glyph button: 2 × Style::spaceSm + a 14px glyph
local ROW_CONTENT_W = PANEL_WIDTH - (2 * PANEL_PADDING) - SCROLLBAR_GUTTER
-- Width left for the task text once the chip, the optional grip and the
-- `trailing` glyph buttons (each preceded by a gap) have taken their share.
local function taskTextWidth(withGrip, trailing)
local width = ROW_CONTENT_W - CHIP_W - ROW_GAP - (trailing * (GLYPH_BTN_W + ROW_GAP))
if withGrip then
width -= GRIP_W + ROW_GAP
end
return width
end
local PRIORITIES = { "important", "medium", "low" }
local RANK = { important = 1, medium = 2, low = 3 }
local COLORS = { important = "#e06c75", medium = "#e5c07b", low = "#98c379" }
@@ -403,12 +435,14 @@ local function taskRow(item)
}))
else
-- Static text; clicking it re-opens the editor ("press on the text").
-- The explicit width is what makes a long task wrap onto another line
-- instead of running under the three buttons that follow it.
table.insert(children, ui.button({
key = "view-" .. id,
text = item.done and strike(item.text) or item.text,
variant = "ghost",
contentAlign = "start",
flexGrow = 1,
width = taskTextWidth(grip ~= nil, 3),
onClick = function()
enterEdit(id)
end,
@@ -510,6 +544,7 @@ render = function()
onClick = "onClearDone",
}),
ui.button({ key = "header-add", glyph = "plus", variant = "primary", tooltip = tr("tip_add"), onClick = "onAdd" }),
ui.button({ key = "header-settings", glyph = "settings", variant = "ghost", tooltip = tr("tip_settings"), onClick = "onOpenSettings" }),
ui.button({ key = "header-close", glyph = "close", variant = "ghost", tooltip = tr("tip_close"), onClick = "onClosePanel" }),
})
@@ -650,6 +685,13 @@ function onClearDoneCancel()
render()
end
-- Opens the settings window on this plugin's own page (the host supplies the
-- plugin id, so a plugin can only ever open its own). It closes the panel on
-- the way, so onClose flushes any pending edit first.
function onOpenSettings()
noctalia.openSettings()
end
function onClosePanel()
panel.close()
end
+2 -2
View File
@@ -8,8 +8,8 @@
id = "nightwatch75/todo"
name = "To Do"
version = "0.0.10"
plugin_api = 9
version = "0.0.14"
plugin_api = 15
author = "nightwatch75"
license = "MIT"
dependencies = []
+1
View File
@@ -30,6 +30,7 @@
"tip_grip": "Drag to reorder",
"tip_grip_drop": "Click another grip to drop here, or this one to cancel",
"tip_sort": "Switch ordering mode",
"tip_settings": "Plugin settings",
"tip_undone": "Mark as to do",
"title": "To Do",
"tooltip": "To Do — {count} to do"