diff --git a/.gitignore.d/bin b/.gitignore.d/bin
index f5c853a..f53fc99 100644
--- a/.gitignore.d/bin
+++ b/.gitignore.d/bin
@@ -1,7 +1,4 @@
*
-!/bin
-!/bin/birthdays
-!/bin/borg_backup
-!/bin/em
!/.gitignore.d
!/.gitignore.d/bin
+!/.local/bin
diff --git a/bin/birthdays b/.local/bin/birthdays
similarity index 100%
rename from bin/birthdays
rename to .local/bin/birthdays
diff --git a/bin/em b/.local/bin/em
similarity index 100%
rename from bin/em
rename to .local/bin/em
diff --git a/.local/bin/fuzzy-i3lock b/.local/bin/fuzzy-i3lock
new file mode 100755
index 0000000..ae4b552
--- /dev/null
+++ b/.local/bin/fuzzy-i3lock
@@ -0,0 +1,13 @@
+#!/bin/sh -e
+#
+# Show a pixelated screenshot as background image of i3lock
+#
+# See
+# Copied from
+#
+
+screenshot="${TMPDIR:-/tmp}/fuzzy-i3lock.png"
+
+scrot "$screenshot"
+mogrify -scale 10% -scale 1000% "$screenshot"
+exec i3lock -i "$screenshot"
diff --git a/.local/bin/i3-run b/.local/bin/i3-run
new file mode 100755
index 0000000..1baee9a
--- /dev/null
+++ b/.local/bin/i3-run
@@ -0,0 +1,9 @@
+#!/bin/sh
+
+# stolen from https://r0tty.org/git/dotfiles/i3
+
+# Make i3 spawn a program, in the current working directory. This is
+# useful for running GUI apps from a terminal without cluttering the
+# terminal with their output.
+
+exec i3-msg -t command exec "cd '$(pwd)' && $@"
diff --git a/.local/bin/ical2org b/.local/bin/ical2org
new file mode 100755
index 0000000..63960b2
--- /dev/null
+++ b/.local/bin/ical2org
@@ -0,0 +1,392 @@
+#!/usr/bin/awk -f
+# awk script for converting an iCal formatted file to a sequence of org-mode headings.
+# this may not work in general but seems to work for day and timed events from Google's
+# calendar, which is really all I need right now...
+#
+# usage:
+# awk -f THISFILE < icalinputfile.ics > orgmodeentries.org
+#
+# Note: change org meta information generated below for author and
+# email entries!
+#
+# Caveats:
+#
+# - date entries with no time specified are assumed to be local time zone;
+# same remark for date entries that do have a time but do not end with Z
+# e.g.: 20130101T123456 is local and will be kept as 2013-01-01 12:34
+# where 20130223T123422Z is UTC and will be corrected appropriately
+#
+# - UTC times are changed into local times, using the time zone of the
+# computer that runs the script; it would be very hard in an awk script
+# to respect the time zone of a file belonging to another time zone:
+# the offsets will be different as well as the switchover time(s);
+# (consider a remote shell to a computer with the file's time zone)
+#
+# - the UTC conversion entirely relies on the built-in strftime method;
+# the author is not responsible for any erroneous conversions nor the
+# consequence of such conversions
+#
+# - does process RRULE recurring events, but ignores COUNT specifiers
+#
+# - does not process EXDATE to exclude date(s) from recurring events
+#
+# Eric S Fraga
+# 20100629 - initial version
+# 20100708 - added end times to timed events
+# - adjust times according to time zone information
+# - fixed incorrect transfer for entries with ":" embedded within the text
+# - added support for multi-line summary entries (which become headlines)
+# 20100709 - incorporated time zone identification
+# - fixed processing of continuation lines as Google seems to
+# have changed, in the last day, the number of spaces at
+# the start of the line for each continuation...
+# - remove backslashes used to protect commas in iCal text entries
+# no further revision log after this as the file was moved into a git
+# repository...
+#
+# Updated by: Guido Van Hoecke
+# Last change: 2013.05.26 14:28:33
+#----------------------------------------------------------------------------------
+
+BEGIN {
+ ### config section
+
+ # maximum age in days for entries to be output: set this to -1 to
+ # get all entries or to N>0 to only get enties that start or end
+ # less than N days ago
+ max_age = -1;
+
+ # set to 1 or 0 to yes or not output a header block with TITLE,
+ # AUTHOR, EMAIL etc...
+ header = 1;
+
+ # set to 1 or 0 to yes or not output the original ical preamble as
+ # comment
+ preamble = 1;
+
+ # set to 1 to output time and summary as one line starting with
+ # the time (value 1) or to 0 to output the summary as first line
+ # and the date and time info as a second line
+ condense = 0;
+
+ # set to 1 or 0 to yes or not output the original ical entry as a
+ # comment (mostly useful for debugging purposes)
+ original = 1;
+
+ # google truncates long subjects with ... which is misleading in
+ # an org file: it gives the unfortunate impression that an
+ # expanded entry is still collapsed; value 1 will trim those
+ # ... and value 0 doesn't touch them
+ trimdots = 1;
+
+ # change this to your name
+ author = "uni plus"
+
+ # and to your email address
+ emailaddress = ""
+
+ ### end config section
+
+ # use a colon to separate the type of data line from the actual contents
+ FS = ":";
+
+ # we only need to preserve the original entry lines if either the
+ # preamble or original options are true
+ preserve = preamble || original
+ first = 1; # true until an event has been found
+ max_age_seconds = max_age*24*60*60
+
+ if (header) {
+ print "#+TITLE: Uni Plus calendar"
+ print "#+AUTHOR: ", author
+ print "#+EMAIL: ", emailaddress
+ print "#+DESCRIPTION: converted using the ical2org awk script"
+ print "#+CATEGORY: uni"
+ print "#+STARTUP: hidestars"
+ print "#+STARTUP: overview"
+ print ""
+ }
+}
+
+# continuation lines (at least from Google) start with a space
+# if the continuation is after a description or a summary, append the entry
+# to the respective variable
+
+/^[ ]/ {
+ if (indescription) {
+ entry = entry gensub("\r", "", "g", gensub("^[ ]", "", "", $0));
+ } else if (insummary) {
+ summary = summary gensub("\r", "", "g", gensub("^[ ]", "", "", $0))
+ }
+ if (preserve)
+ icalentry = icalentry "\n" $0
+}
+
+/^BEGIN:VEVENT/ {
+ # start of an event: initialize global velues used for each event
+ date = "";
+ entry = ""
+ headline = ""
+ icalentry = "" # the full entry for inspection
+ id = ""
+ indescription = 0;
+ insummary = 0
+ intfreq = "" # the interval and frequency for repeating org timestamps
+ lasttimestamp = -1;
+ location = ""
+ rrend = ""
+ status = ""
+ summary = ""
+
+ # if this is the first event, output the preamble from the iCal file
+ if (first) {
+ if(preamble) {
+ print "* COMMENT original iCal preamble"
+ print gensub("\r", "", "g", icalentry)
+ }
+ if (preserve)
+ icalentry = ""
+ first = false;
+ }
+}
+
+# any line that starts at the left with a non-space character is a new data field
+
+/^[A-Z]/ {
+ # we do not copy DTSTAMP lines as they change every time you download
+ # the iCal format file which leads to a change in the converted
+ # org file as I output the original input. This change, which is
+ # really content free, makes a revision control system update the
+ # repository and confuses.
+ if (preserve)
+ if (! index("DTSTAMP", $1))
+ icalentry = icalentry "\n" $0
+ # this line terminates the collection of description and summary entries
+ indescription = 0;
+ insummary = 0;
+}
+
+# this type of entry represents a day entry, not timed, with date stamp YYYYMMDD
+
+/^DTSTART;VALUE=DATE/ {
+ date = datestring($2);
+}
+
+/^DTEND;VALUE=DATE/ {
+ time2 = datestring($2, 1);
+ if ( issameday )
+ time2 = ""
+}
+
+# this represents a timed entry with date and time stamp YYYYMMDDTHHMMSS
+# we ignore the seconds
+
+/^DTSTART[:;][^V]/ {
+ date = datetimestring($2);
+ # print date;
+}
+
+# and the same for the end date;
+
+/^DTEND[:;][^V]/ {
+ time2 = datetimestring($2);
+ if (substr(date,1,10) == substr(time2,1,10)) {
+ # timespan within same date, use one date with a time range
+ date = date "-" substr(time2, length(time2)-4)
+ time2 = ""
+ }
+}
+
+# repetition rule
+
+/^RRULE:FREQ=(DAILY|WEEKLY|MONTHLY|YEARLY)/ {
+ # get the d, w, m or y value
+ freq = tolower(gensub(/.*FREQ=(.).*/, "\\1", $0))
+ # get the interval, and use 1 if none specified
+ interval = $2 ~ /INTERVAL=/ ? gensub(/.*INTERVAL=([0-9]+);.*/, "\\1", $2) : 1
+ # get the enddate of the rule and use "" if none specified
+ rrend = $2 ~ /UNTIL=/ ? datestring(gensub(/.*UNTIL=([0-9]{8}).*/, "\\1", $2)) : ""
+ # build the repetitor vale as understood by org
+ intfreq = " +" interval freq
+ # if the repetition is daily, and there is an end date, drop the repetitor
+ # as that is the default
+ if (intfreq == " +1d" && time2 =="" && rrend != "")
+ intfreq = ""
+}
+
+# The description will the contents of the entry in org-mode.
+# this line may be continued.
+
+/^DESCRIPTION/ {
+ $1 = "";
+ entry = entry gensub("\r", "", "g", $0);
+ indescription = 1;
+}
+
+# the summary will be the org heading
+
+/^SUMMARY/ {
+ $1 = "";
+ summary = gensub("\r", "", "g", $0);
+
+ # trim trailing dots if requested by config option
+ if(trimdots && summary ~ /\.\.\.$/)
+ sub(/\.\.\.$/, "", summary)
+ insummary = 1;
+}
+
+# the unique ID will be stored as a property of the entry
+
+/^UID/ {
+ id = gensub("\r", "", "g", $2);
+}
+
+/^LOCATION/ {
+ location = gensub("\r", "", "g", $2);
+}
+
+/^STATUS/ {
+ status = gensub("\r", "", "g", $2);
+}
+
+# when we reach the end of the event line, we output everything we
+# have collected so far, creating a top level org headline with the
+# date/time stamp, unique ID property and the contents, if any
+
+/^END:VEVENT/ {
+ #output event
+ if(max_age<0 || ( lasttimestamp>0 && systime()--<" time2
+ else if (rrend != "")
+ date = date ">--<" rrend
+
+ # translate \n sequences to actual newlines and unprotect commas (,)
+ if (condense)
+ print "* <" date "> " gensub("^[ ]+", "", "", gensub("\\\\,", ",", "g", gensub("\\\\n", " ", "g", summary)))
+ else
+ print "* " gensub("^[ ]+", "", "", gensub("\\\\,", ",", "g", gensub("\\\\n", " ", "g", summary)))
+ print ":PROPERTIES:"
+ print ":ID: " id
+ if(length(location))
+ print ":LOCATION: " location
+ if(length(status))
+ print ":STATUS: " status
+ print ":END:"
+ if (! condense)
+ print "<" date ">"
+ print ""
+ # translate \n sequences to actual newlines and unprotect commas (,)
+ if(length(entry)>1)
+ print gensub("^[ ]+", "", "", gensub("\\\\,", ",", "g", gensub("\\\\n", "\n", "g", entry)));
+
+ # output original entry if requested by 'original' config option
+ if (original)
+ print "** COMMENT original iCal entry\n", gensub("\r", "", "g", icalentry)
+ }
+}
+
+
+
+# funtion to convert an iCal time string 'yyyymmddThhmmss[Z]' into a
+# date time string as used by org, preferably including the short day
+# of week: 'yyyy-mm-dd day hh:mm' or 'yyyy-mm-dd hh:mm' if we cannot
+# define the day of the week
+
+function datetimestring(input)
+{
+ # print "________"
+ # print "input : " input
+ # convert the iCal Date+Time entry to a format that mktime can understand
+ spec = gensub("([0-9][0-9][0-9][0-9])([0-9][0-9])([0-9][0-9])T([0-9][0-9])([0-9][0-9])([0-9][0-9]).*[\r]*", "\\1 \\2 \\3 \\4 \\5 \\6", "g", input);
+ # print "spec :" spec
+
+ stamp = mktime(spec);
+ lasttimestamp = stamp;
+
+ if (stamp <= 0) {
+ # this is a date before the start of the epoch, so we cannot
+ # use strftime and will deliver a 'yyyy-mm-dd hh:mm' string
+ # without day of week; this assumes local time, and does not
+ # attempt UTC offset correction
+ spec = gensub("([0-9][0-9][0-9][0-9])([0-9][0-9])([0-9][0-9])T([0-9][0-9])([0-9][0-9])([0-9][0-9]).*[\r]*", "\\1-\\2-\\3 \\4:\\5", "g", input);
+ # print "==> spec:" spec;
+ return spec;
+ }
+
+ if (input ~ /[0-9]{8}T[0-9]{6}Z/ ) {
+ # this is an utc time;
+ # we need to correct the timestamp by the utc offset for this time
+ offset = strftime("%z", stamp)
+ pm = substr(offset,1,1) 1 # define multiplier +1 or -1
+ hh = substr(offset,2,2) * 3600 * pm
+ mm = substr(offset,4,2) * 60 * pm
+
+ # adjust the timestamp
+ stamp = stamp + hh + mm
+ }
+
+ return strftime("%Y-%m-%d %a %H:%M", stamp);
+}
+
+# function to convert an iCal date into an org date;
+# the optional parameter indicates whether this is an end date;
+# for single or multiple whole day events, the end date given by
+# iCal is the date of the first day after the event;
+# if the optional 'isenddate' parameter is non zero, this function
+# tries to reduce the given date by one day
+
+function datestring(input, isenddate)
+{
+ #convert the iCal string to a an mktime input string
+ spec = gensub("([0-9][0-9][0-9][0-9])([0-9][0-9])([0-9][0-9]).*[\r]*", "\\1 \\2 \\3 00 00 00", "g", input);
+
+ # compute the nr of seconds after or before the epoch
+ # dates before the epoch will have a negative timestamp
+ # days after the epoch will have a positive timestamp
+ stamp = mktime(spec);
+
+ if (isenddate) {
+ # subtract 1 day from the timestamp
+ # note that this also works for dates before the epoch
+ stamp = stamp - 86400;
+
+ # register whether the end date is same as the start date
+ issameday = lasttimestamp == stamp
+ }
+ # save timestamp to allow for check of max_age
+ lasttimestamp = stamp
+
+ if (stamp < 0) {
+ # this date is before the epoch;
+ # the returned datestring will not have the short day of week string
+ # as strftime does not handle negative times;
+ # we have to construct the datestring directly from the input
+ if (isenddate) {
+ # we really should return the date before the input date, but strftime
+ # does not work with negative timestamp values; so we can not use it
+ # to obtain the string representation of the corrected timestamp;
+ # we have to return the date specified in the iCal input and we
+ # add time 00:00 to clarify this
+ return spec = gensub("([0-9][0-9][0-9][0-9])([0-9][0-9])([0-9][0-9]).*[\r]*", "\\1-\\2-\\3 00:00", "g", input);
+ } else {
+ # just generate the desired representation of the input date, without time;
+ return gensub("([0-9][0-9][0-9][0-9])([0-9][0-9])([0-9][0-9]).*[\r]*", "\\1-\\2-\\3", "g", input);
+ }
+ }
+
+ # return the date and day of week
+ return strftime("%Y-%m-%d %a", stamp);
+}
+
+# Local Variables:
+# time-stamp-line-limit: 1000
+# time-stamp-format: "%04y.%02m.%02d %02H:%02M:%02S"
+# time-stamp-active: t
+# time-stamp-start: "Last change:[ \t]+"
+# time-stamp-end: "$"
+# End: