Skip to content

Repository files navigation

nu_plugin_caldav

A nushell plugin for interfacing with a CalDAV server.

Commands

Command Input / Output Description
caldav query principal nothing -> string Get the principal user path for the current configured user.
caldav query homeset [principal] nothing -> string Find a homeset (collection of calendars) from CalDAV (optionally given a principal path).
caldav query calendars <homeset> nothing -> table<calendar> Reads the list calendars of calendars under a homeset from the CalDAV server.
caldav query events <calendar_path> nothing -> table<event_object> Reads events from a given calendar.
<calendar_events> | caldav save events <calendar_path> [--update] table<event_object> -> nothing Creates (optionally updates if already existing) events from the given input.
<calendar_events> | caldav timeline [--start] [--end] table<event_object> -> table<timeline_segment> Orders events chronologically.
caldav purge cache nothing -> nothing Completely clears cached events, calendars, and plugin state.

Type Definitions

The corresponding nushell record type for each Golang struct definition will have snake_case fields for public PascalCase fields on the Golang struct. Slices of structs will be treated as tables, rather than lists of records. Pointers to values will be treated as nullable values (ie. oneof<type, nothing>).

type Foo struct {
  Path string
  MaxResourceSize int64
}
record<path: string, max_resource_size: int>

Configuration

Server configuration is done through environment variables:

  • NU_PLUGIN_CALDAV_URL: Full URL (ex. https://hostname/...) to the CalDAV server.
  • NU_PLUGIN_CALDAV_USERNAME: Username for authentication with the CalDAV server. (optional)
  • NU_PLUGIN_CALDAV_PASSWORD: Password for authentication with the CalDAV server. (optional)
  • NU_PLUGIN_CALDAV_INSECURE: Set to 1 if HTTPS security errors should be ignored. (optional)

Example Usage

let principal = caldav query principal
let homeset = caldav query homeset $principal
let calendars = caldav query calendars $homeset
print $calendars
def localtime [str: string] {
$str | into datetime -z "l"
}
let calpath: string = $calendars
| filter { |it| $it.name == "Schedule" }
| first
| $in.path
caldav query events $calpath | caldav timeline --start (localtime "2025-11-9") --end (localtime "2025-11-16")
[{
main: {
summary: "test! 2",
location: "location of event",
description: "a human-friendly\ndescription",
categories: ["category_A", "category_B"],
class: "PUBLIC", # one of: PUBLIC, PRIVATE, CONFIDENTIAL
geo: {
latitude: 0.2,
longitude: 0.3,
},
priority: 1, # 1-9 (1 is highest, 9 is lowest)
status: "TENTATIVE", # one of: TENTATIVE, CONFIRMED, CANCELLED
transparency: "", # one of: OPAQUE, TRANSPARENT
url: "https://github.com",
comment: "comments that may be relevant",
attach: "https://github.com/LQR471814",
contact: "this is contact information associated w/ the event",
organizer: "https://github.com/LQR41814",
created: {
stamp: (date now)
},
start: {
stamp: (localtime "2025-11-14 21:45"),
},
end: {
stamp: (localtime "2025-11-14 22:00"),
},
},
}] | caldav save events $calpath

Design Decisions & Limitations

  • Server-side filtering is not planned to be implemented as:
    • caldav query events syncs events automatically and caches them locally, allowing you to call it as many times as you want.
    • caldav timeline automatically accounts for recurring events and overlapping events, allowing you to easily work with events chronologically.
    • Any other filtering you want done can be done with a nushell where command.
  • Incomplete implementation of CalDAV specification:
    • VEVENT
      • Binary attachments
      • Event scheduling / RSVP
    • VTODO
    • VJOURNAL
  • Static validation of event type is currently not possible due to nushell's lack of optional types.

About

A nushell plugin for CalDAV.

Resources

Stars

3 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages