- Rust 100%
Strings live in src/i18n.rs; the language comes from `lang` in config.toml, else from the locale, else English. Due dates are parsed in both languages. Manifest text in English. |
||
|---|---|---|
| src | ||
| .gitignore | ||
| Cargo.lock | ||
| Cargo.toml | ||
| CHANGELOG.md | ||
| herdr-plugin.toml | ||
| LICENSE | ||
| README.md | ||
herdr-vikunja
A herdr plugin to view and manage your Vikunja tasks without leaving the terminal. Inspired by tsk.
- Task board in a pane beside your work: open tasks sorted by due date then priority, project tree (a project includes its sub-projects), task details, search, automatic refresh.
- Mark done / not done; a repeating task moves on to its next due date.
- Quick add in a popup (or
ain the board): title, due date, project.
The interface is in English or French (see lang below). Tested with herdr
0.9.3 and Vikunja 2.3.
Installation
Requires cargo (Rust ≥ 1.88). herdr plugin install only supports GitHub, so
clone this repository, build it and link the directory:
git clone https://git.helheim.net/bastien/herdr-vikunja.git
cd herdr-vikunja
cargo build --release
herdr plugin link "$PWD"
After updating (git pull), run cargo build --release again: herdr always
runs target/release/herdr-vikunja.
Configuration
-
In Vikunja: Settings → API Tokens → Create a token with at least:
projects:read_alltasks:read_all,read_one,update,createother:user(to find your default project)
-
Create
$(herdr plugin config-dir vikunja)/config.toml(usually~/.config/herdr/plugins/config/vikunja/config.toml):url = "https://vikunja.example.net" # instance root or .../api/v1 token = "tk_..." refresh_secs = 60 # optional, default 60 lang = "en" # optional: "en" or "fr"Keep it private:
chmod 600 config.toml. TheVIKUNJA_URLandVIKUNJA_API_TOKENenvironment variables override the file.Without
lang, the language follows the locale (LC_ALL,LC_MESSAGES, thenLANG): French forfr*, English otherwise. -
Check it:
./target/release/herdr-vikunja check.
herdr keybindings
Add to ~/.config/herdr/config.toml, then run herdr server reload-config:
[[keys.command]]
key = "prefix+t"
type = "plugin_action"
command = "vikunja.open-board" # open the board, focus it, or close it when focused
description = "vikunja: tasks"
[[keys.command]]
key = "prefix+a"
type = "plugin_action"
command = "vikunja.quick-add" # quick-add popup
description = "vikunja: quick add"
prefix+t and prefix+a are unbound in herdr's default keymap.
Keys
In the board:
| key | action |
|---|---|
↑ ↓ / j k, PgUp PgDn, g G |
move |
← → / h l |
previous / next project ("All" included) |
space / x |
mark done / not done |
a / n |
new task (current project preselected) |
/ |
search (title, labels, description); esc clears |
f |
switch between open tasks and the 100 most recently done |
r |
refresh |
o / enter |
open the task in the browser |
q |
quit |
A task marked done stays visible (struck through) until the next refresh, so
pressing space again undoes it.
In the quick-add form: tab/↓ next field, ← → change project, enter
creates, esc cancels, ctrl+u clears the field, ctrl+w deletes the last
word. The due date is read in English or French whatever the interface
language: today / auj, tomorrow / demain, +3 / +3d / +3j (days
from now), a weekday (fri, friday, ven, vendredi… always the next one),
15/10 (day/month), 15/10/2027 and 2027-10-15. It is stored as 23:59 local
time on that day.
Commands
herdr-vikunja board task board (default)
herdr-vikunja add quick-add form
herdr-vikunja open-board herdr action: open / focus / close the board
herdr-vikunja open-add herdr action: open the quick-add popup
herdr-vikunja check test the configuration and the connection
How it works
A single Rust binary (ratatui for the UI,
ureq for HTTP). herdr launches it as declared
in herdr-plugin.toml:
- the
boardentrypoint (asplitpane titled "Vikunja") and theaddentrypoint (a 74×9 popup) runherdr-vikunja board/herdr-vikunja add; - the
open-boardandquick-addactions runopen-board/open-add, which drive herdr through$HERDR_BIN_PATH:pane list,tab focus,plugin pane open|focus|close. An existing board is found by its pane label "Vikunja".
| file | role |
|---|---|
src/main.rs |
subcommands, check |
src/config.rs |
reads config.toml and the environment |
src/api.rs |
Vikunja REST client (/projects, /tasks, /user, create, update), pagination |
src/model.rs |
tasks and projects, sorting, project tree, due-date parsing, search, HTML description → text |
src/i18n.rs |
English and French strings, date formatting, language detection |
src/worker.rs |
network calls on a background thread so the UI never blocks |
src/ui/board.rs |
the task board |
src/ui/add.rs, src/ui/form.rs |
the popup and the quick-add form |
src/herdr.rs |
herdr actions (open / focus / close, popup) |
Worth knowing:
- Updating a task: Vikunja's update endpoint replaces every field, so the
task as received from the server is posted back whole with only
donechanged. The server's answer replaces the local copy (this is how repeating tasks get their next due date). - Dates: Vikunja encodes "no date" as year 1 (
0001-01-01T00:00:00Z). - Projects: archived projects and pseudo-projects (favorites, saved filters, negative ids) are skipped; a sub-project whose parent is not visible is shown at the root.
Limitations
- No editing of existing tasks (title, description, labels, priority):
oopens the task in Vikunja's web UI. - The "done" view is limited to the 100 most recently completed tasks.
- Descriptions are shown as plain text (the editor's HTML is simplified).
- Linux and macOS only.
Development
cargo test # unit tests (model, configuration, herdr actions)
cargo clippy --all-targets
To try it without touching your real tasks, start a throwaway Vikunja:
docker run -d --name vikunja-test -p 127.0.0.1:3456:3456 \
-e VIKUNJA_SERVICE_PUBLICURL=http://127.0.0.1:3456/ \
-e VIKUNJA_SERVICE_SECRET=dev-secret \
-e VIKUNJA_DATABASE_PATH=/tmp/vikunja.db \
-e VIKUNJA_FILES_BASEPATH=/tmp/files \
vikunja/vikunja:2.3.0
Register an account at http://127.0.0.1:3456, create an API token, then run the board outside herdr with a separate config directory:
mkdir -p /tmp/vk && printf 'url = "http://127.0.0.1:3456"\ntoken = "tk_..."\n' > /tmp/vk/config.toml
HERDR_PLUGIN_CONFIG_DIR=/tmp/vk cargo run -- board
License
Apache 2.0, like herdr.