CalDAV TUI
5 minute readSource code
codeberg.org/mm-dev/caldavtuiA CalDAV calendar client for the terminal
THIS PROJECT IS IN EARLY DEVELOPMENT — NOT READY FOR EVERYDAY USE.
If you want to try it out, I recommend setting up a new user on your CalDAV server and using credentials for that user to test the app. This way you won’t risk your real calendar data.
Written in Go with Bubble Tea.
CalDAV TUI should work in any terminal as long as Go can compile executables for the system architecture.
How to Use
Set up credentials
Your CalDAV credentials need to be exported into the shell as 3 environment variables:
CALDAV_URLCALDAV_USERCALDAV_PASS
You could do it naively with something like:
# DON'T DO THIS UNLESS YOU WANT TO ADD PLAINTEXT CREDENTIALS TO YOUR SHELL HISTORY
export CALDAV_URL="https://yourcaldavserver.com/remote.php/dav"
export CALDAV_USER="michaelmouse"
export CALDAV_PASS="password123"
This will leave your details in plain text in your history though, so isn’t a good idea.
I use KeePassXC and the following script exports my credentials when I source (not run) it with source creds-setup:
#!/bin/bash
# Script: `creds-setup`
# Usage: `source creds-setup`
# Ensure script is sourced, not run
if [[ "${BASH_SOURCE[0]}" == "${0}" ]]; then
echo "Error: this script must be sourced, not executed." >&2
echo "Run: source ${0}" >&2
exit 1
fi
# Get entire "caldavtui" entry from KeePassXC. This will return a multi-line string
_output=$(keepassxc-cli show -s /external-sd/000-KXC/Passwords.kdbx "caldavtui")
# Use `awk` to parse the entry and put the bits we need into the ENV vars
export CALDAV_URL=$(echo "$_output" | awk -F': ' '/^URL:/ {print $2}')
export CALDAV_USER=$(echo "$_output" | awk -F': ' '/^UserName:/ {print $2}')
export CALDAV_PASS=$(echo "$_output" | awk -F': ' '/^Password:/ {print $2}')
# Clean up
unset _output
Ultimately it’s up to you to work out how you want to get your credentials exported into the current shell. If you don’t already have a preferred way of doing this search for “safe ways to export credentials” or something similar.
Run the app
Once the credential variables are exported in a shell, the app can be run in the same shell with:
go run .
Panel Hierarchy
There is an information heirarchy with the left-most pane handling the highest-level content, and the right-most handling the most low-level content.
| Left panel | Middle panel | Right panel |
|---|---|---|
| <- Higher level (broader) | Lower level (more detailed) -> | |
| Select calendars | Select days | Day details (eg events) |
In practice this means
Left panel
Where you decide which calendars to show/hide. Hiding a calendar here means none of its events will be visible in the other panes.
Middle panel
Where you choose a range of days to view. This can be one of 2 styles (swap by pressing v for
view).
- Agenda View which shows a vertical list of days
- Month View which shows a view similar to a traditional calendar.
Right panel
Can be a few different things:
- A list of events for the selected day
- An area to create, edit or delete events
Keyboard controls
The status bar at the bottom of the screen shows common keys depending on the currently-selected panel.
Up/down/left/right inside panels
Directional movement within panels can be done using Vim keys (h, j, k, l) or the arrow
keys. Depending on the panel and mode this allows you to select calendars, days, or events.
The panel border has a pink highlight to help you see which item is focused or selected.
Selecting/deselecting calendars
In the calendars list (right hand panel) press space to toggle visibility of a calendar.
Move between panels
Holding down shift while pressing left/right (arrows or Vim keys) will move between panels. The selected panel will have a brighter heading than the others.
Large jumps (Agenda/Month view)
In the middle panel, holding down shift while pressing up/down (arrows or Vim keys) will jump around by a week, month or larger amount (depending on ‘days’ setting).
Form fields
When a form is visible (eg when editing an event) you can use Tab to move to the next field, and
Shift + Tab to move back to the previous field.
Global keys
These work most of the time, whichever panel is selected but some won’t work when you are creating/editing events (as they might interfere with typing in text fields).
vtoggle the middle panel between Agenda View and Month Viewaadd a new event, defaulting to the currently-selected dayeedit the currently-selected event (if any)
Responsive layout
The app is designed to work at various terminal sizes and remain usable (even if unattractively) right down to 60 columns wide. Although high resolution monitors are common nowadays, some developers like to have multiple terminal windows open at various sizes.
59 columns wide
132 columns wide
Potential Roadmap
This is a list of things the app could have, not what it will have (although as soon as I am 100% certain that something will not be in the app I will strike it out).
-
Collections
- List calendars on server (in collection)
- Read calendar colours
-
Event
- Delete
- Current instance
- Current and previous
- All instances
- Create/edit
- Title [/summary?]
- Notes [/description?]
- Allday toggle
- Start time
- end time
- can be different day for multi-day event
- Location
- Mark as busy for this time
- Categories
- Anniversary
- Birthday
- […etc check NextCloud]
- Notification
- Days/hours/mins before
- Notification
- Invitees/attendees
- Timezone
- Attachments
- Delete
-
Calendar
- Create [/edit?]
- Name
- Colour
calendar-color - Order
calendar-order - Timezone
- Allow VEVENT/VTODO/VFREEBUSY
- Add subscription calendar
- Thunderbird public holiday calendars
- Delete
- plus all events (implied?)
- Create [/edit?]
-
Tasks
- Display
- Create
- Edit
- Delete
Source Code
This is an open-source app. You can find the source code here:
codeberg.org/mm-dev/caldavtui
Support Development
Bitcoin
bc1qtd03k9fnulmxrgwsrruvp053rgal905em2c0cq
PayPal
dоոаtеઊmm-dеν.rосkѕ ⇱ type it, don't copy + paste!
Want to become a better programmer? Join the Recurse Center!