--- /dev/null
+#!/bin/sh
+set -eu
+
+if [ $# != 2 ]; then
+  echo >&2 E: Need exactly two arguments.
+  return 1
+fi
+
+TSK="$1"
+LINK="$2"
+
+case "$LINK" in
+  (*@*|"<*>")
+    LINK="${LINK%>}"; LINK="%{LINK#<}"
+    echo >&2 I: "Adding MsgID <$LINK> to task $TSK"
+    task "$TSK" mod data:msgid:"$LINK"
+    ;;
+
+  (*://*)
+    echo >&2 I: "Adding URL $LINK to task $TSK"
+    task "$TSK" mod data:url:"$LINK"
+    ;;
+
+  (*)
+    if [ -f "$LINK" ]; then
+
+      LINK="$(readlink -e "$LINK")"
+
+      case "$LINK" in
+        ($HOME/*) LINK="~${LINK#$HOME}";;
+      esac
+      echo >&2 I: "Adding file $LINK to task $TSK"
+      task "$TSK" mod data:file:"$LINK"
+
+    else
+      echo >&2 E: "Don't know how to handle link data $LINK"
+      return 1
+
+    fi
+    ;;
+esac
 
--- /dev/null
+#!/bin/sh
+set -eu
+
+if [ $# != 1 ]; then
+  echo >&2 E: Need exactly one argument.
+  return 1
+fi
+
+TSK="$1"
+
+DATA="$(task _get "$TSK".data)"
+DATATYPE="${DATA%%:*}"
+DATAPAYL="${DATA#*:}"
+
+case "$DATATYPE" in
+  ('')
+    echo >&2 I: No link data available for this task.
+    task "$TSK"
+    ;;
+
+  (msgid)
+    mutt -f =store -e "push '<search>~i $DATAPAYL'<enter>"
+    ;;
+
+  (url)
+    sensible-browser "$DATAPAYL"
+    ;;
+
+  (file)
+    if eval test -f "$DATAPAYL"; then
+      case "$(file --mime-type "$DATAPAYL")" in
+        (*": text/"*) eval sensible-editor "$DATAPAYL";;
+        (*) eval run-mailcap --action=edit "$DATAPAYL";;
+      esac
+    fi
+    ;;
+
+  (*)
+    eval run-mailcap --action=edit "$DATAPAYL"
+    ;;
+
+esac
 
--- /dev/null
+- /*.pem
+- /taskd-credentials.rc
 
--- /dev/null
+include /usr/share/taskwarrior/light-256.theme
+data.location=~/.var/taskwarrior
+
+nag=
+recurrence.indicator=@
+recurrence=off
+hyphenate=off
+
+color.tag.TEMPLATE=gray16 on white
+color.alternate=
+
+include /usr/share/taskwarrior/holidays.de-DE.rc
+include /usr/share/taskwarrior/holidays.en-NZ.rc
+
+include ~/.config/taskwarrior/taskd-credentials.rc
+
+uda.data.type=string
+uda.data.label=Ext.data
+uda.data.indicator=→
+
+report.next.columns=id,data.indicator,start.age,entry.age,depends,priority,project,tags,recur,scheduled.countdown,due.relative,until.remaining,description,urgency
+report.next.labels=ID,X,Active,Age,Deps,P,Project,Tag,Recur,S,Due,Until,Description,Urg
+
+alias.call=execute task_call
+alias.attach=execute task_attach
 
--- /dev/null
+*/30 * * * * ( task sync && task next && task sync ) >/dev/null 2>&1
 
--- /dev/null
+*
+!/.bin/task_attach
+!/.bin/task_call
+!/.config/taskwarrior/.gitignore
+!/.config/taskwarrior/rc
+!/.crontab.d/taskwarrior
+!/.gitignore.d/taskwarrior
+!/.taskrc
+!/.var/taskwarrior/.gitignore
+!/.var/taskwarrior/hooks
+!/.zsh/zshrc/parts.d/50-taskwarrior
 
--- /dev/null
+.config/taskwarrior/rc
\ No newline at end of file
 
--- /dev/null
+../../.config/taskwarrior/hooks
\ No newline at end of file
 
--- /dev/null
+#
+# taskwarrior shell integration
+#
+# Copyright © 2018 martin f. krafft <madduck@madduck.net>
+# Released under the terms of the Artistic Licence 2.0
+#
+# Source repository: http://git.madduck.net/v/etc/zsh.git
+#
+
+if whence task >/dev/null; then
+
+  function t() { task "$@"; }
+
+  alias t\?='alias -rm t[-+a-z]'
+  alias ta='t add'
+  alias tc='t call'
+  alias th='t attach'
+  alias tn='t next'
+  alias tl='t all'
+  alias ty='t sync'
+  alias td='t done'
+  alias te='t edit'
+  alias tu='t undo'
+  alias tm='t modify'
+  alias ts='t start'
+  alias t+='t annotate'
+
+  run_at_most_every 5m \
+    t 2>/dev/null || :
+fi
+
+# vim:ft=zsh