Skip to content

This document is a WORK IN PROGRESS.
This is just a quick personal cheat sheet: treat its contents with caution!


khal, khard and todoman

kahl is CLI CalDAV client: a calendars manager.

khard is a CLI CardDAV client: a contacts manager.

todoman is a CLI CalDAV client: a TODO/task manager.

Reference(s)

TODO

click-repl : install python-click-repl (for pacman) and then run todo repl for interactive mode


Table of content


Install

# pacman -S vdirsyncer
# pacman -S khal
# pacman -S khard
# pacman -S todoman
    > :: python-pyxdg and python-xdg are in conflict. Remove python-xdg? [y/N] y
# apt install vdirsyncer
# apt install khal
# apt install khard
# apt install todoman

TODO


TODO


TODO



Config

  • vdirsyncer config (e.g. tasks and calendars sync from Nextcloud):

    $ mkdir -p ~/calendars
    $ mkdir -p ~/contacts
    $ mkdir -p ~/.local/share/vdirsyncer/
    $ mkdir -p ~/.config/vdirsyncer/
    $ vi ~/.config/vdirsyncer/config
        >
        > # See <http://vdirsyncer.pimutils.org/>
        > # See <https://github.com/pimutils/vdirsyncer>
        > # See <https://github.com/pimutils/vdirsyncer/blob/master/config.example>
        >
        > [general]
        > # A folder where vdirsyncer can store some metadata about each pair.
        > status_path = "~/.local/share/vdirsyncer"
        >
        > # CARDDAV: Contacts config (khard)
        > #
        > [pair contacts]
        > a = "contacts_local"
        > b = "contacts_remote"
        > collections = ["from a", "from b"]
        >
        > [storage contacts_local]
        > type = "filesystem"
        > path = "~/contacts"
        > fileext = ".vcf"
        >
        > [storage contacts_remote]
        > type = "carddav"
        > url = "https://yournextcloud.example.lcl/remote.php/dav/addressbooks/users/USERNAME/"
        > username = "<USERNAME>"
        > password = "<PASSWORD>"
        > # Instead of inserting plaintext password, fetch it using pass:
        > #password.fetch = ["command", "pass", "nextcloud"]
        >
        > # CALDAV: Calendars config (khal and todoman)
        > #
        > [pair calendars]
        > a = "calendars_local"
        > b = "calendars_remote"
        > collections = ["from a", "from b"]
        > metadata = ["displayname", "color"]
        >
        > [storage calendars_local]
        > type = "filesystem"
        > path = "~/calendars"
        > fileext = ".ics"
        >
        > [storage calendars_remote]
        > type = "caldav"
        > url = "https://yournextcloud.example.lcl/remote.php/dav/calendars/USERNAME/"
        > username = "<USERNAME>"
        > password = "<PASSWORD>"
        > # Instead of inserting plaintext password, fetch it using pass:
        > #password.fetch = ["command", "pass", "nextcloud"]
    
    $ vdirsyncer discover # let vdirsyncer create a local copy of the calendars (answer `y` when asked)
    $ vdirsyncer metasync # sync metadata (e.g. displaynames and colors)
    $ vdirsyncer sync
    

  • khal config:

    $ khal configure # defaults are good
    $ vi ~/.config/khal/config
        >
        > # See <https://github.com/pimutils/khal>
        > # See <https://khal.readthedocs.io/en/latest/index.html>
        >
        > [calendars]
        >
        > [[calendar_local]]
        > path = ~/calendars/*
        > type = discover
        >
        > [locale]
        > timeformat = %H:%M
        > dateformat = %d/%m/%Y
        > longdateformat = %d/%m/%Y
        > datetimeformat = %d/%m/%Y %H:%M
        > longdatetimeformat = %d/%m/%Y %H:%M
    

  • khard config:

    $ mkdir -p ~/.config/khard
    $ vi ~/.config/khard/khard.conf
        > # example configuration file for khard version > 0.14.0
        > # place it under ~/.config/khard/khard.conf
        > # This file is parsed by the configobj library. The syntax is described at
        > # <https://configobj.readthedocs.io/en/latest/configobj.html#the-config-file-format>
        >
        > [addressbooks]
        > [[contacts]]
        > # change the following path according to your addressbook name (e.g. "contacts" by default on
        > # nextcloud):
        > path = ~/contacts/contacts/
        >
        > #[[family]]
        > #path = ~/.contacts/family/
        >
        > #[[friends]]
        > #path = ~/.contacts/friends/
        >
        > [general]
        > debug = no
        > default_action = list
        > # These are either strings or comma seperated lists
        > editor = vim, -i, NONE
        > merge_editor = vimdiff
        >
        > [contact table]
        > # display names by first or last name: first_name / last_name / formatted_name
        > display = first_name
        > # group by address book: yes / no
        > group_by_addressbook = no
        > # reverse table ordering: yes / no
        > reverse = no
        > # append nicknames to name column: yes / no
        > show_nicknames = no
        > # show uid table column: yes / no
        > show_uids = yes
        > # sort by first or last name: first_name / last_name / formatted_name
        > sort = last_name
        > # localize dates: yes / no
        > localize_dates = yes
        > # set a comma separated list of preferred phone number types in descending priority
        > # or nothing for non-filtered alphabetical order
        > preferred_phone_number_type = pref, cell, home
        > # set a comma separated list of preferred email address types in descending priority
        > # or nothing for non-filtered alphabetical order
        > preferred_email_address_type = pref, work, home
        >
        > [vcard]
        > # extend contacts with your own private objects
        > # these objects are stored with a leading "X-" before the object name in the vcard files
        > # every object label may only contain letters, digits and the - character
        > # example:
        > #   private_objects = Jabber, Skype, Twitter
        > # default: ,  (the empty list)
        > private_objects = Jabber, Skype, Twitter
        > # preferred vcard version: 3.0 / 4.0
        > preferred_version = 3.0
        > # Look into source vcf files to speed up search queries: yes / no
        > search_in_source_files = no
        > # skip unparsable vcard files: yes / no
        > skip_unparsable = no
    

  • todoman config:

    $ mkdir -p ~/.config/todoman
    $ vi ~/.config/todoman/todoman.conf
        > [main]
        > path = ~/calendars/*
        > date_format = %d/%m/%Y
        > time_format = %H:%M
    


Use

Sync

  • Discover and sync before running khal, khard or todoman:

    $ vdirsyncer discover # discover potential new calendars and/or contacts
    $ vdirsyncer metasync # sync metadata (e.g. displaynames and colors)
    $ vdirsyncer sync
    

  • Discover and sync calendars (for khal and todoman):

    $ vdirsyncer discover calendars
    $ vdirsyncer metasync calendars
    $ vdirsyncer sync calendars
    

  • Only discover and sync contacts (for khard):

    $ vdirsyncer discover contacts
    $ vdirsyncer metasync contacts
    $ vdirsyncer sync contacts
    

  • Remove all local vdirsyncer data and re sync:

    $ rm -rf ~/calendars/*
    $ rm -rf ~/contacts/*
    $ rm -rf ~/.local/share/vdirsyncer/*
    $ vdirsyncer discover # discover potential new calendars and/or contacts
    $ vdirsyncer metasync # sync metadata (e.g. displaynames and colors)
    $ vdirsyncer sync
    

  • Add a crontab rule in order to not forget to sync after modifying your calendars and/or contacts with khal, todoman or khard:

    $ crontab -e
        > ...
        > */30 * * * * vdirsyncer sync > /dev/null
    

todoman

  • List tasks:

    $ todo list
    

  • List tasks of a specific list (e.g. "Pro"):

    $ todo list Pro
    

  • List filters and sort:

    $ todo list --location office # fitler by location containing "office"
    $ todo list --category Perso # fitler by category containing "Perso"
    $ todo list --grep call # fitler by message containing "call"
    
    $ todo list --sort due Pro # sort by due date in Pro list
    $ todo list --sort --reverse priority # sort by priority in reverse order
    $ todo list --sort --no-reverse priority # sort by priority without reversing order
    
    $ todo list --due 24 # only show todos due during the next 24 hours
    $ todo list --priority medium # only show todos with medium or high priority (low, medium, high)
    $ todo list --start 24 # only show todos that will start during the next 24 hours
    $ todo list --startable # fitler todos which could be starded (start time in the passed)
    
    $ todo list --status completed # only show completed todos
    

    • $ todo list --sort" fields:

      • description
      • location
      • status
      • summary
      • uid
      • rrule
      • percent_complete
      • priority
      • sequence
      • categories
      • completed_at
      • created_at
      • dtstamp
      • start
      • due
      • last_modified
    • todo list --priority fields:

      • low
      • medium
      • high
    • todo list --status fields

      • needs-action
      • cancelled
      • completed
      • in-progress
      • any
  • Show a task (by it's id, e.g. 42):

    $ todo show 42
    

  • Edit a task (by it's id, e.g. 42):

    $ todo edit 42 -i
    

  • Create a new task (e.g. in "Pro" list):

    $ todo new -l Pro -i
    

  • Copy tasks (by their id, e.g. 32 and 42) to a specific list (e.g. "Pro"):

    $ todo copy 32 42 -l Pro
    

  • Move tasks (by their id, e.g. 32 and 42) to a specific list (e.g. "Pro"):

    $ todo move 32 42 -l Pro
    

  • Mark tasks (by their id, e.g. 32 and 42) as done:

    $ todo done 32 42
    

  • Cancel tasks (by their id, e.g. 32 and 42) and confirm:

    $ todo cancel 32 42 --yes
    

  • Delete tasks (by their id, e.g. 32 and 42) and confirm:

    $ todo delete 32 42 --yes
    

  • Delete done tasks:

    $ todo flush
    

khal

  • Run khal interactive:

    $ ikhal
    

  • ikhal shortcuts:

    • Everywhere:

      • j move cursor down
      • k move cursor up
      • h move cursor left
      • l move cursor right
      • Enter focus to the right column / focus to an event / edit the focused event
      • Tab focus to the right column / focus to an event / edit the focused event
    • When browsing the calendar column (left column):

      • t focus to the current date
      • v visual selection of a date range (vim like), select the other end with o, escape it with escape
      • n create new event
      • / search for event
      • q quit
    • When browsing the event list column (left column):

      • d toggle event deletion status (event will be deleted when ikhal exits)
      • p duplicate selected event
      • e export selected event
      • q quit
    • When editing and event:

      • Tab jump to next selectable element
      • shift+Tab jump to previous selectable element
      • meta+enter quick save (meta will probably be alt)
      • ctrl+w (text field) deletes word before cursor
      • ctrl+u (text field) deletes till the defining
      • ctrl+k (text field) deletes till the end
      • ctrl+a (text field) jump to the defining of the line
      • ctrl+e (text field) jump to the end of the line
      • ctrl+a (date field) increment number under cursor by 15 minutes
      • ctrl+a (date field) decrement number under cursor by 15 minutes
      • enter (date field) access miniature calendar
      • enter (action field) activate actions on text item enclosed by < brackets >
      • esc esc quit without saving

khard

  • khard command list:
    $ khard --help
    

Troubleshooting

Tip: Sync CalDAV tasks (e.g. Nextcloud tasks) with Taskwarrior through Caldavwarrior

See https://gitlab.com/BlackEdder/caldavwarrior.

Prerequisite(s)

dub (Package and build management system for D)"

# pacman -S dub
# apt install dub

TODO


TODO


Then clone and build Caldavwarrior:

$ mkdir -p ~/apps/src-apps
$ cd ~/apps/src-apps
$ git clone https://gitlab.com/BlackEdder/caldavwarrior.git
$ cd caldavwarrior
$ git checkout v0.3.0 # checkout to the latest stable release (e.g. v0.3.0)
$ dub

Install the hooks by linking to the binary:

$ ln -s ~/apps/src-apps/caldavwarrior/caldavwarrior ~/.local/share/task/hooks/on-modify.caldavwarrior
$ ln -s ~/apps/src-apps/caldavwarrior/caldavwarrior ~/.local/share/task/hooks/on-add.caldavwarrior

Configure Caldavwarrior:

$ mkdir -p ~/.config/caldavwarrior
$ vi ~/.config/caldavwarrior/config.json
    > {
    > "caldavPath": "/home/user/calendars",
    > "vdirLocalStorage": "cal_local"
    > }

Configure vdirsyncer according to the previous Caldavwarrior config:

$ vi ~/.config/vdirsyncer/config
    > ...
    > # CALDAV: Tasks config
    > #
    > [pair cal]
    > a = "cal_local"
    > b = "cal_remote"
    > collections = ["from a", "from b"]
    >
    > [storage cal_local]
    > type = "filesystem"
    > path = "~/calendars"
    > fileext = ".vcf"
    >
    > [storage cal_remote]
    > type = "caldav"
    > url = "https://yournextcloud.example.lcl/remote.php/dav/calendars/USERNAME/"
    > username = "<USERNAME>"
    > # Instead of inserting plaintext password, fetch it using pass:
    > password.fetch = ["command", "pass", "nextcloud"]

Sync:

$ caldavwarrior sync


If this cheat sheet has been useful to you, then please consider leaving a star here.