aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorWeitian LI <liweitianux@gmail.com>2015-01-19 10:21:08 +0800
committerWeitian LI <liweitianux@gmail.com>2015-01-19 10:21:08 +0800
commit0b08340aecac94e17356431894c9635d9bc958d2 (patch)
tree2dfd7f2b0a098b28fbbf2bda4d41e76475625c04
parent6a3885395e9bb793e22694fd1a210078cef69dfc (diff)
downloaddotfiles-0b08340aecac94e17356431894c9635d9bc958d2.tar.bz2
Updated various configs.
-rw-r--r--.config/fontconfig/fonts.conf461
-rw-r--r--.config/gtk-3.0/bookmarks6
-rw-r--r--.config/gtk-3.0/settings.ini26
-rw-r--r--.gitignore7
-rw-r--r--.gnupg/dirmngr.conf21
-rw-r--r--.gnupg/gpg-agent.conf21
-rw-r--r--.gnupg/gpg.conf120
-rw-r--r--.gnupg/sks-keyservers.netCA.pem32
-rw-r--r--.msmtprc56
-rw-r--r--.mutt/attachments65
-rw-r--r--.mutt/colors120
-rw-r--r--.mutt/gpg.rc113
-rw-r--r--.mutt/macros2
-rw-r--r--.mutt/mailboxes1
-rw-r--r--.mutt/mailcap36
-rw-r--r--.mutt/mailinglists17
-rw-r--r--.mutt/muttrc202
-rw-r--r--.mutt/muttrc.bak172
-rw-r--r--.mutt/sample.muttrc340
-rw-r--r--.mutt/zh54
-rw-r--r--.offlineimap/offlineimap.py63
-rw-r--r--.offlineimaprc113
-rw-r--r--.profile10
-rw-r--r--.todo/config95
-rwxr-xr-x.todo/todo.sh1431
-rw-r--r--.zshrc86
-rw-r--r--.zshrc.local118
27 files changed, 3551 insertions, 237 deletions
diff --git a/.config/fontconfig/fonts.conf b/.config/fontconfig/fonts.conf
index 543c78a..0831205 100644
--- a/.config/fontconfig/fonts.conf
+++ b/.config/fontconfig/fonts.conf
@@ -1,57 +1,52 @@
-<?xml version="1.0"?>
-<!DOCTYPE fontconfig SYSTEM "fonts.dtd">
+<?xml version='1.0'?>
+<!DOCTYPE fontconfig SYSTEM 'fonts.dtd'>
<fontconfig>
- <!--
+ <!--
Weitian LI <liweitianux@gmail.com>
2014/04/06
-->
-
- <!--
+ <!--
system wide: /etc/fonts/local.conf
per-user configuration: $XDG_CONFIG_HOME/fontconfig/fonts.conf
(~/.config/fontconfig/fonts.conf)
-->
-
- <!-- private font directory -->
- <dir prefix="xdg">fonts</dir>
-
- <!-- default settings: smoothed and hinted -->
- <match target="font" >
- <edit name="autohint" mode="assign">
- <bool>true</bool>
- </edit>
- <edit name="antialias" mode="assign">
- <bool>true</bool>
- </edit>
- <edit name="hinting" mode="assign">
- <bool>true</bool>
- </edit>
- <edit name="hintstyle" mode="assign">
- <const>hintmedium</const>
- </edit>
- <edit name="lcdfilter" mode="assign">
- <const>lcddefault</const>
- </edit>
- <edit name="rgba" mode="assign">
- <const>rgb</const>
- </edit>
- <!-- enable embedded bitmap -->
- <edit name="embeddedbitmap" mode="assign">
- <bool>true</bool>
- </edit>
- </match>
-
- <!-- DPI -->
- <!--
+ <!-- private font directory -->
+ <dir prefix="xdg">fonts</dir>
+ <!-- default settings: smoothed and hinted -->
+ <match target="font">
+ <edit mode="assign" name="autohint">
+ <bool>true</bool>
+ </edit>
+ <edit mode="assign" name="antialias">
+ <bool>true</bool>
+ </edit>
+ <edit mode="assign" name="hinting">
+ <bool>true</bool>
+ </edit>
+ <edit mode="assign" name="hintstyle">
+ <const>hintmedium</const>
+ </edit>
+ <edit mode="assign" name="lcdfilter">
+ <const>lcddefault</const>
+ </edit>
+ <edit mode="assign" name="rgba">
+ <const>rgb</const>
+ </edit>
+ <!-- enable embedded bitmap -->
+ <edit mode="assign" name="embeddedbitmap">
+ <bool>true</bool>
+ </edit>
+ </match>
+ <!-- DPI -->
+ <!--
<match target="pattern">
<edit name="dpi" mode="assign">
<double>96</double>
</edit>
</match>
-->
-
- <!-- For point size less equal than 6: only smoothed -->
- <!--
+ <!-- For point size less equal than 6: only smoothed -->
+ <!--
<match target="font" >
<test name="size" compare="less_eq">
<double>6</double>
@@ -67,206 +62,220 @@
</edit>
</match>
-->
-
- <!-- font families -->
- <!--
+ <!-- font families -->
+ <!--
Names not including any well known alias are given 'sans-serif'
-->
- <match target="pattern">
- <test qual="all" name="family" compare="not_eq">
- <string>sans-serif</string>
- </test>
- <test qual="all" name="family" compare="not_eq">
- <string>serif</string>
- </test>
- <test qual="all" name="family" compare="not_eq">
- <string>monospace</string>
- </test>
- <edit name="family" mode="append_last">
- <string>sans-serif</string>
- </edit>
- </match>
-
- <!--
+ <match target="pattern">
+ <test compare="not_eq" qual="all" name="family">
+ <string>sans-serif</string>
+ </test>
+ <test compare="not_eq" qual="all" name="family">
+ <string>serif</string>
+ </test>
+ <test compare="not_eq" qual="all" name="family">
+ <string>monospace</string>
+ </test>
+ <edit mode="append_last" name="family">
+ <string>sans-serif</string>
+ </edit>
+ </match>
+ <!--
Alias well known font names to available TrueType fonts.
These substitute TrueType faces for similar Type1
faces to improve screen appearance.
-->
- <alias>
- <family>Times</family>
- <prefer>
- <family>Times New Roman</family>
- </prefer>
- <default>
- <family>serif</family>
- </default>
- </alias>
- <alias>
- <family>Helvetica</family>
- <prefer>
- <family>Arial</family>
- </prefer>
- <default>
- <family>sans-serif</family>
- </default>
- </alias>
- <alias>
- <family>Courier</family>
- <prefer>
- <family>Courier New</family>
- </prefer>
- <default>
- <family>monospace</family>
- </default>
- </alias>
-
- <!--
+ <alias>
+ <family>Times</family>
+ <prefer>
+ <family>Times New Roman</family>
+ </prefer>
+ <default>
+ <family>serif</family>
+ </default>
+ </alias>
+ <alias>
+ <family>Helvetica</family>
+ <prefer>
+ <family>Arial</family>
+ </prefer>
+ <default>
+ <family>sans-serif</family>
+ </default>
+ </alias>
+ <alias>
+ <family>Courier</family>
+ <prefer>
+ <family>Courier New</family>
+ </prefer>
+ <default>
+ <family>monospace</family>
+ </default>
+ </alias>
+ <!--
The example of the requirements of OR operator;
If the 'family' contains 'Courier New' OR 'Courier'
add 'monospace' as the alternative
-->
- <match target="pattern">
- <test name="family" compare="eq">
- <string>Courier New</string>
- </test>
- <edit name="family" mode="prepend">
- <string>monospace</string>
- </edit>
- </match>
- <match target="pattern">
- <test name="family" compare="eq">
- <string>Courier</string>
- </test>
- <edit name="family" mode="prepend">
- <string>monospace</string>
- </edit>
- </match>
-
- <!-- use WenQuanYi font when serif is requested for Chinese -->
- <match>
- <!--
+ <match target="pattern">
+ <test compare="eq" name="family">
+ <string>Courier New</string>
+ </test>
+ <edit mode="prepend" name="family">
+ <string>monospace</string>
+ </edit>
+ </match>
+ <match target="pattern">
+ <test compare="eq" name="family">
+ <string>Courier</string>
+ </test>
+ <edit mode="prepend" name="family">
+ <string>monospace</string>
+ </edit>
+ </match>
+ <!-- use WenQuanYi font when serif is requested for Chinese -->
+ <match>
+ <!--
If you don't want to use WenQuanYi Zen Hei font for zh-tw etc,
you can use zh-cn instead of zh.
Please note, even if you set zh-cn, it still matches zh.
if you don't like it, you can use compare="eq"
instead of compare="contains".
-->
- <test name="lang" compare="contains">
- <string>zh</string>
- </test>
- <test name="family">
- <string>serif</string>
- </test>
- <edit name="family" mode="prepend">
- <string>WenQuanYi Micro Hei</string>
- <string>WenQuanYi Zen Hei</string>
- </edit>
- </match>
-
- <!-- font family preferences -->
- <match>
- <test name="family">
- <string>serif</string>
- </test>
- <edit name="family" mode="prepend">
- <string>DejaVu Serif</string>
- <string>Liberation Serif</string>
- <string>Linux Libertine</string>
- <string>Linux Libertine O</string>
- <string>Bitstream Vera Serif</string>
- <string>Droid Serif</string>
- <string>AR PL UMing CN</string>
- <string>AR PL UMing TW</string>
- <string>AR PL UMing HK</string>
- <string>AR PL SungtiL GB</string>
- </edit>
- </match>
- <match>
- <test name="family">
- <string>sans-serif</string>
- </test>
- <edit name="family" mode="prepend">
- <string>DejaVu Sans</string>
- <string>Liberation Sans</string>
- <string>Linux Biolinum</string>
- <string>Linux Biolinum O</string>
- <string>Source Sans Pro</string>
- <string>Droid Sans</string>
- <string>WenQuanYi Micro Hei</string>
- <string>WenQuanYi Zen Hei</string>
- <string>Droid Sans Fallback</string>
- <string>AR PL UKai CN</string>
- <string>AR PL UKai TW</string>
- <string>AR PL UKai HK</string>
- <string>AR PL KaitiM GB</string>
- <string>AR PL KaitiM Big5</string>
- </edit>
- </match>
- <match>
- <test name="family">
- <string>monospace</string>
- </test>
- <edit name="family" mode="prepend">
- <string>DejaVu Sans Mono</string>
- <string>Liberation Mono</string>
- <string>Source Code Pro</string>
- <string>Inconsolata</string>
- <string>Bitstream Vera Sans Mono</string>
- <string>Droid Sans Mono</string>
- <string>WenQuanYi Micro Hei Mono</string>
- <string>WenQuanYi Zen Hei Mono</string>
- </edit>
- </match>
-
- <!-- reorder the serif, sans-serif and monospace family -->
- <alias>
- <family>serif</family>
- <prefer>
- <family>DejaVu Serif</family>
- <family>Liberation Serif</family>
- <family>Linux Libertine</family>
- <family>Linux Libertine O</family>
- <family>Bitstream Vera Serif</family>
- <family>Droid Serif</family>
- <family>AR PL UMing CN</family>
- <family>AR PL UMing TW</family>
- <family>AR PL UMing HK</family>
- <family>AR PL SungtiL GB</family>
- </prefer>
- </alias>
- <alias>
- <family>sans-serif</family>
- <prefer>
- <family>DejaVu Sans</family>
- <family>Liberation Sans</family>
- <family>Linux Biolinum</family>
- <family>Linux Biolinum O</family>
- <family>Source Sans Pro</family>
- <family>Bitstream Vera Sans</family>
- <family>Droid Sans</family>
- <family>WenQuanYi Micro Hei</family>
- <family>WenQuanYi Zen Hei</family>
- <family>Droid Sans Fallback</family>
- <family>AR PL UKai CN</family>
- <family>AR PL UKai TW</family>
- <family>AR PL UKai HK</family>
- <family>AR PL KaitiM GB</family>
- <family>AR PL KaitiM Big5</family>
- </prefer>
- </alias>
- <alias>
- <family>monospace</family>
- <prefer>
- <family>DejaVu Sans Mono</family>
- <family>Liberation Mono</family>
- <family>Source Code Pro</family>
- <family>Inconsolata</family>
- <family>Bitstream Vera Sans Mono</family>
- <family>Droid Sans Mono</family>
- <family>WenQuanYi Micro Hei Mono</family>
- <family>WenQuanYi Zen Hei Mono</family>
- </prefer>
- </alias>
- <!-- end reorder fonts -->
-
+ <test compare="contains" name="lang">
+ <string>zh</string>
+ </test>
+ <test name="family">
+ <string>serif</string>
+ </test>
+ <edit mode="prepend" name="family">
+ <string>WenQuanYi Micro Hei</string>
+ <string>WenQuanYi Zen Hei</string>
+ </edit>
+ </match>
+ <!-- font family preferences -->
+ <match>
+ <test name="family">
+ <string>serif</string>
+ </test>
+ <edit mode="prepend" name="family">
+ <string>DejaVu Serif</string>
+ <string>Liberation Serif</string>
+ <string>Linux Libertine</string>
+ <string>Linux Libertine O</string>
+ <string>Bitstream Vera Serif</string>
+ <string>Droid Serif</string>
+ <string>AR PL UMing CN</string>
+ <string>AR PL UMing TW</string>
+ <string>AR PL UMing HK</string>
+ <string>AR PL SungtiL GB</string>
+ </edit>
+ </match>
+ <match>
+ <test name="family">
+ <string>sans-serif</string>
+ </test>
+ <edit mode="prepend" name="family">
+ <string>DejaVu Sans</string>
+ <string>Liberation Sans</string>
+ <string>Linux Biolinum</string>
+ <string>Linux Biolinum O</string>
+ <string>Source Sans Pro</string>
+ <string>Droid Sans</string>
+ <string>WenQuanYi Micro Hei</string>
+ <string>WenQuanYi Zen Hei</string>
+ <string>Droid Sans Fallback</string>
+ <string>AR PL UKai CN</string>
+ <string>AR PL UKai TW</string>
+ <string>AR PL UKai HK</string>
+ <string>AR PL KaitiM GB</string>
+ <string>AR PL KaitiM Big5</string>
+ </edit>
+ </match>
+ <match>
+ <test name="family">
+ <string>monospace</string>
+ </test>
+ <edit mode="prepend" name="family">
+ <string>DejaVu Sans Mono</string>
+ <string>Liberation Mono</string>
+ <string>Source Code Pro</string>
+ <string>Inconsolata</string>
+ <string>Bitstream Vera Sans Mono</string>
+ <string>Droid Sans Mono</string>
+ <string>WenQuanYi Micro Hei Mono</string>
+ <string>WenQuanYi Zen Hei Mono</string>
+ </edit>
+ </match>
+ <!-- reorder the serif, sans-serif and monospace family -->
+ <alias>
+ <family>serif</family>
+ <prefer>
+ <family>DejaVu Serif</family>
+ <family>Liberation Serif</family>
+ <family>Linux Libertine</family>
+ <family>Linux Libertine O</family>
+ <family>Bitstream Vera Serif</family>
+ <family>Droid Serif</family>
+ <family>AR PL UMing CN</family>
+ <family>AR PL UMing TW</family>
+ <family>AR PL UMing HK</family>
+ <family>AR PL SungtiL GB</family>
+ </prefer>
+ </alias>
+ <alias>
+ <family>sans-serif</family>
+ <prefer>
+ <family>DejaVu Sans</family>
+ <family>Liberation Sans</family>
+ <family>Linux Biolinum</family>
+ <family>Linux Biolinum O</family>
+ <family>Source Sans Pro</family>
+ <family>Bitstream Vera Sans</family>
+ <family>Droid Sans</family>
+ <family>WenQuanYi Micro Hei</family>
+ <family>WenQuanYi Zen Hei</family>
+ <family>Droid Sans Fallback</family>
+ <family>AR PL UKai CN</family>
+ <family>AR PL UKai TW</family>
+ <family>AR PL UKai HK</family>
+ <family>AR PL KaitiM GB</family>
+ <family>AR PL KaitiM Big5</family>
+ </prefer>
+ </alias>
+ <alias>
+ <family>monospace</family>
+ <prefer>
+ <family>DejaVu Sans Mono</family>
+ <family>Liberation Mono</family>
+ <family>Source Code Pro</family>
+ <family>Inconsolata</family>
+ <family>Bitstream Vera Sans Mono</family>
+ <family>Droid Sans Mono</family>
+ <family>WenQuanYi Micro Hei Mono</family>
+ <family>WenQuanYi Zen Hei Mono</family>
+ </prefer>
+ </alias>
+ <!-- end reorder fonts -->
+ <match target="font">
+ <edit mode="assign" name="rgba">
+ <const>none</const>
+ </edit>
+ </match>
+ <match target="font">
+ <edit mode="assign" name="hinting">
+ <bool>true</bool>
+ </edit>
+ </match>
+ <match target="font">
+ <edit mode="assign" name="hintstyle">
+ <const>hintmedium</const>
+ </edit>
+ </match>
+ <match target="font">
+ <edit mode="assign" name="antialias">
+ <bool>true</bool>
+ </edit>
+ </match>
+ <dir>~/.fonts</dir>
</fontconfig>
diff --git a/.config/gtk-3.0/bookmarks b/.config/gtk-3.0/bookmarks
new file mode 100644
index 0000000..067f5ec
--- /dev/null
+++ b/.config/gtk-3.0/bookmarks
@@ -0,0 +1,6 @@
+file:///home/aly/books
+file:///home/aly/documents
+file:///home/aly/downloads
+file:///home/aly/music
+file:///home/aly/pictures
+davs://ly.noip.me:8801/remote.php/webdav Aly's ownCloud
diff --git a/.config/gtk-3.0/settings.ini b/.config/gtk-3.0/settings.ini
index 061e8c4..0a14ade 100644
--- a/.config/gtk-3.0/settings.ini
+++ b/.config/gtk-3.0/settings.ini
@@ -1,8 +1,20 @@
[Settings]
-gtk-font-name = Sans 10
-;gtk-application-prefer-dark-theme = 1
-gtk-theme-name = Adwaita
-;gtk-theme-name = FlatStudioDark
-gtk-icon-theme-name = AwOkenWhite
-gtk-fallback-icon-theme-name = gnome
-
+gtk-font-name=Oxygen-Sans 10
+;gtk-application-prefer-dark-theme=1
+gtk-theme-name=QtCurve
+;gtk-theme-name=FlatStudioDark
+gtk-icon-theme-name=default.kde4
+gtk-fallback-icon-theme-name=gnome
+gtk-cursor-theme-name=breeze_cursors
+gtk-cursor-theme-size=0
+gtk-toolbar-style=GTK_TOOLBAR_BOTH_HORIZ
+gtk-toolbar-icon-size=GTK_ICON_SIZE_LARGE_TOOLBAR
+gtk-button-images=1
+gtk-menu-images=1
+gtk-enable-event-sounds=1
+gtk-enable-input-feedback-sounds=1
+gtk-xft-antialias=1
+gtk-xft-hinting=1
+gtk-xft-hintstyle=hintmedium
+gtk-xft-rgba=rgb
+gtk-application-prefer-dark-theme=1
diff --git a/.gitignore b/.gitignore
index 3b651c9..fd301f2 100644
--- a/.gitignore
+++ b/.gitignore
@@ -84,12 +84,17 @@ __pycache__/
# mutt
.mutt/aliases
-.mutt/*.muttrc
+.mutt/certificates
+.mutt/history
+.mutt/signature
+.mutt/gmail.muttrc
+.mutt/lavabit.muttrc
.mutt/cache/
.mutt/tmp/
# todo
.todo/todo.txt
+.todo/todo.txt.bak
.todo/done.txt
.todo/report.txt
diff --git a/.gnupg/dirmngr.conf b/.gnupg/dirmngr.conf
new file mode 100644
index 0000000..7696da9
--- /dev/null
+++ b/.gnupg/dirmngr.conf
@@ -0,0 +1,21 @@
+#####################################################################
+# GnuPG configuration file
+#
+# dirmngr: CRL and OCSP daemon (GnuPG >= 2.1)
+# ~/.gnupg/dirmngr.conf
+#
+# Ref:
+# [1] SKS Keyservers: Overview of the pools
+# https://sks-keyservers.net/overview-of-pools.php
+#
+# Weitian LI <liweitianux@gmail.com>
+# 2015/01/16
+#####################################################################
+
+# keyserver hkps://hkps.pool.sks-keyservers.net
+# This pool only contains servers available using hkps.
+# keyserver-options ca-cert-file' is obsolete! (GnuPG >= 2.1)
+# NOTE: cannot use '~' or '$HOME' in path ??
+hkp-cacert /home/aly/dotfiles/.gnupg/sks-keyservers.netCA.pem
+
+# vim: set ts=8 sw=4 tw=0 fenc=utf-8 ft=gpg: #
diff --git a/.gnupg/gpg-agent.conf b/.gnupg/gpg-agent.conf
new file mode 100644
index 0000000..9225c5e
--- /dev/null
+++ b/.gnupg/gpg-agent.conf
@@ -0,0 +1,21 @@
+#####################################################################
+# GnuPG Agent configuration file
+# ~/.gnupg/gpg-agent.conf
+#
+# Ref:
+# Gentoo wiki: GnuPG
+#
+# Weitian LI <liweitianux@gmail.com>
+# 2014/06/12
+#####################################################################
+
+#pinentry-program /usr/bin/pinentry-gtk-2
+#pinentry-program /usr/bin/pinentry-qt4
+pinentry-program /usr/bin/pinentry-curses
+
+no-grab
+
+# default timeout of the passphrase (10 minutes)
+default-cache-ttl 600
+
+# vim: set ts=8 sw=4 tw=0 fenc=utf-8 ft=gpg: #
diff --git a/.gnupg/gpg.conf b/.gnupg/gpg.conf
new file mode 100644
index 0000000..6db3bf6
--- /dev/null
+++ b/.gnupg/gpg.conf
@@ -0,0 +1,120 @@
+#####################################################################
+# GnuPG configuration file
+# ~/.gnupg/gpg.conf
+#
+# Based on Github: ioerror/duraconf's configuration:
+# https://github.com/ioerror/duraconf/blob/master/configs/gnupg/gpg.conf
+#
+# Reference:
+# [1] Riseup: OpenPGP Best Practices
+# https://help.riseup.net/en/gpg-best-practices
+# [2] Secure GnuPG configuration
+# http://sparkslinux.wordpress.com/2013/07/09/secure-gnupg-configuration
+#
+# Weitian LI <liweitianux@gmail.com>
+# Created: 2014/06/12
+# Updated: 2015/01/19
+#####################################################################
+
+#-----------------------------
+# default key
+#-----------------------------
+
+# The default key to sign with. If this option is not used, the default key is
+# the first key found in the secret keyring
+default-key 0xF00D615C9984147B450F56EAF81BF4535F26EBF6
+
+#-----------------------------
+# behavior
+#-----------------------------
+
+# Uncomment the following option to get rid of the copyright notice
+no-greeting
+
+# create ASCII armored output (default is binary OpenPGP format)
+#armor
+
+# If you do not use the Latin-1 (ISO-8859-1) charset, you should tell
+# GnuPG which is the native character set. Please check the man page
+# for supported character sets. This character set is only used for
+# metadata and not for the actual message which does not undergo any
+# translation. Note that future version of GnuPG will change to UTF-8
+# as default character set.
+charset utf-8
+
+# Disable inclusion of the version string in ASCII armored output
+no-emit-version
+
+# Disable comment string in clear text signatures and ASCII armored messages
+no-comments
+
+# Display long key IDs
+keyid-format 0xlong
+
+# List all keys (or the specified ones) along with their fingerprints
+with-fingerprint
+
+# Display the calculated validity of user IDs during key listings
+list-options show-uid-validity
+verify-options show-uid-validity
+
+# Try to use the GnuPG-Agent. With this option, GnuPG first tries to connect to
+# the agent before it asks for a passphrase.
+use-agent
+
+#-----------------------------
+# keyserver
+#-----------------------------
+
+# This is the server that --recv-keys, --send-keys, and --search-keys will
+# communicate with to receive keys from, send keys to, and search for keys on
+keyserver hkp://pool.sks-keyservers.net
+#keyserver hkps://hkps.pool.sks-keyservers.net
+
+# Provide a certificate store to override the system default
+# Get this from https://sks-keyservers.net/sks-keyservers.netCA.pem
+# option 'ca-cert-file' is obsolete. (GnuPG >= 2.1)
+#keyserver-options ca-cert-file=~/dotfiles/.gnupg/sks-keyservers.netCA.pem
+
+# Set the proxy to use for HTTP and HKP keyservers - default to the standard
+# local Tor socks proxy
+# It is encouraged to use Tor for improved anonymity. Preferrably use either a
+# dedicated SOCKSPort for GnuPG and/or enable IsolateDestPort and
+# IsolateDestAddr
+#keyserver-options http-proxy=socks5-hostname://127.0.0.1:9050
+# Don't leak DNS, see https://trac.torproject.org/projects/tor/ticket/2846
+keyserver-options no-try-dns-srv
+
+# When using --refresh-keys, if the key in question has a preferred keyserver
+# URL, then disable use of that preferred keyserver to refresh the key from
+keyserver-options no-honor-keyserver-url
+
+# When searching for a key with --search-keys, include keys that are marked on
+# the keyserver as revoked
+keyserver-options include-revoked
+
+#-----------------------------
+# algorithm and ciphers
+#-----------------------------
+
+# list of personal digest preferences. When multiple digests are supported by
+# all recipients, choose the strongest one
+#personal-cipher-preferences AES256 TWOFISH AES192 AES
+personal-cipher-preferences AES256 AES192 AES CAST5
+
+# list of personal digest preferences. When multiple ciphers are supported by
+# all recipients, choose the strongest one
+personal-digest-preferences SHA512 SHA384 SHA256 SHA224
+
+# list of personal compress preferences
+personal-compress-preferences ZLIB BZIP2 ZIP
+
+# message digest algorithm used when signing a key
+cert-digest-algo SHA512
+
+# This preference list is used for new keys and becomes the default for
+# "setpref" in the edit menu
+#default-preference-list SHA512 SHA384 SHA256 SHA224 AES256 TWOFISH AES192 AES ZLIB BZIP2 ZIP Uncompressed
+default-preference-list SHA512 SHA384 SHA256 SHA224 AES256 AES192 AES CAST5 ZLIB BZIP2 ZIP Uncompressed
+
+# vim: set ts=8 sw=4 tw=0 fenc=utf-8 ft=gpg: #
diff --git a/.gnupg/sks-keyservers.netCA.pem b/.gnupg/sks-keyservers.netCA.pem
new file mode 100644
index 0000000..24a2ad2
--- /dev/null
+++ b/.gnupg/sks-keyservers.netCA.pem
@@ -0,0 +1,32 @@
+-----BEGIN CERTIFICATE-----
+MIIFizCCA3OgAwIBAgIJAK9zyLTPn4CPMA0GCSqGSIb3DQEBBQUAMFwxCzAJBgNV
+BAYTAk5PMQ0wCwYDVQQIDARPc2xvMR4wHAYDVQQKDBVza3Mta2V5c2VydmVycy5u
+ZXQgQ0ExHjAcBgNVBAMMFXNrcy1rZXlzZXJ2ZXJzLm5ldCBDQTAeFw0xMjEwMDkw
+MDMzMzdaFw0yMjEwMDcwMDMzMzdaMFwxCzAJBgNVBAYTAk5PMQ0wCwYDVQQIDARP
+c2xvMR4wHAYDVQQKDBVza3Mta2V5c2VydmVycy5uZXQgQ0ExHjAcBgNVBAMMFXNr
+cy1rZXlzZXJ2ZXJzLm5ldCBDQTCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoC
+ggIBANdsWy4PXWNUCkS3L//nrd0GqN3dVwoBGZ6w94Tw2jPDPifegwxQozFXkG6I
+6A4TK1CJLXPvfz0UP0aBYyPmTNadDinaB9T4jIwd4rnxl+59GiEmqkN3IfPsv5Jj
+MkKUmJnvOT0DEVlEaO1UZIwx5WpfprB3mR81/qm4XkAgmYrmgnLXd/pJDAMk7y1F
+45b5zWofiD5l677lplcIPRbFhpJ6kDTODXh/XEdtF71EAeaOdEGOvyGDmCO0GWqS
+FDkMMPTlieLA/0rgFTcz4xwUYj/cD5e0ZBuSkYsYFAU3hd1cGfBue0cPZaQH2HYx
+Qk4zXD8S3F4690fRhr+tki5gyG6JDR67aKp3BIGLqm7f45WkX1hYp+YXywmEziM4
+aSbGYhx8hoFGfq9UcfPEvp2aoc8u5sdqjDslhyUzM1v3m3ZGbhwEOnVjljY6JJLx
+MxagxnZZSAY424ZZ3t71E/Mn27dm2w+xFRuoy8JEjv1d+BT3eChM5KaNwrj0IO/y
+u8kFIgWYA1vZ/15qMT+tyJTfyrNVV/7Df7TNeWyNqjJ5rBmt0M6NpHG7CrUSkBy9
+p8JhimgjP5r0FlEkgg+lyD+V79H98gQfVgP3pbJICz0SpBQf2F/2tyS4rLm+49rP
+fcOajiXEuyhpcmzgusAj/1FjrtlynH1r9mnNaX4e+rLWzvU5AgMBAAGjUDBOMB0G
+A1UdDgQWBBTkwyoJFGfYTVISTpM8E+igjdq28zAfBgNVHSMEGDAWgBTkwyoJFGfY
+TVISTpM8E+igjdq28zAMBgNVHRMEBTADAQH/MA0GCSqGSIb3DQEBBQUAA4ICAQAR
+OXnYwu3g1ZjHyley3fZI5aLPsaE17cOImVTehC8DcIphm2HOMR/hYTTL+V0G4P+u
+gH+6xeRLKSHMHZTtSBIa6GDL03434y9CBuwGvAFCMU2GV8w92/Z7apkAhdLToZA/
+X/iWP2jeaVJhxgEcH8uPrnSlqoPBcKC9PrgUzQYfSZJkLmB+3jEa3HKruy1abJP5
+gAdQvwvcPpvYRnIzUc9fZODsVmlHVFBCl2dlu/iHh2h4GmL4Da2rRkUMlbVTdioB
+UYIvMycdOkpH5wJftzw7cpjsudGas0PARDXCFfGyKhwBRFY7Xp7lbjtU5Rz0Gc04
+lPrhDf0pFE98Aw4jJRpFeWMjpXUEaG1cq7D641RpgcMfPFvOHY47rvDTS7XJOaUT
+BwRjmDt896s6vMDcaG/uXJbQjuzmmx3W2Idyh3s5SI0GTHb0IwMKYb4eBUIpQOnB
+cE77VnCYqKvN1NVYAqhWjXbY7XasZvszCRcOG+W3FqNaHOK/n/0ueb0uijdLan+U
+f4p1bjbAox8eAOQS/8a3bzkJzdyBNUKGx1BIK2IBL9bn/HravSDOiNRSnZ/R3l9G
+ZauX0tu7IIDlRCILXSyeazu0aj/vdT3YFQXPcvt5Fkf5wiNTo53f72/jYEJd6qph
+WrpoKqrwGwTpRUCMhYIUt65hsTxCiJJ5nKe39h46sg==
+-----END CERTIFICATE-----
diff --git a/.msmtprc b/.msmtprc
new file mode 100644
index 0000000..b73f2bb
--- /dev/null
+++ b/.msmtprc
@@ -0,0 +1,56 @@
+#
+# msmtp configuration file
+#
+# LIweitiaNux
+# February 6, 2012
+#
+# Ref: http://pbrisbin.com/posts/two_accounts_in_mutt
+#
+
+### Accounts will inherit settings from this section
+defaults
+auth on
+tls on
+tls_starttls on
+#tls_trust_file /usr/local/share/certs/ca-root-nss.crt
+tls_trust_file /etc/ssl/certs/ca-certificates.crt
+protocol smtp
+logfile ~/.msmtp/msmtp.log
+
+# SSL: 465
+# TLS: 587
+
+### autistici
+account autistici
+host smtp.autistici.org
+port 587
+tls_trust_file ~/.msmtp/autistici_ca.crt
+tls_certcheck on
+#auto_from on
+from liweitianux@autistici.org
+user liweitianux@autistici.org
+passwordeval gpg -d ~/.msmtp/autistici.gpg
+#password password
+
+### gmail
+account gmail
+host smtp.gmail.com
+port 587
+from Weitian LI
+user liweitianux@gmail.com
+#passwordeval gpg -d ~/.msmtp/gmail.gpg
+#password password
+
+### lavabit
+account lavabit
+host smtp.lavabit.com
+port 587
+from Weitian LI
+user liweitianux
+#passwordeval gpg -d ~/.msmtp/lavabit.gpg
+#password passwod
+
+
+### set a default account
+account default : autistici
+
diff --git a/.mutt/attachments b/.mutt/attachments
new file mode 100644
index 0000000..1c8535e
--- /dev/null
+++ b/.mutt/attachments
@@ -0,0 +1,65 @@
+# $Id$
+#
+# mutt attchment searching and counting configuration
+#
+# LIweitiaNux
+# February 8, 2012
+#
+# Ref: file:///usr/local/share/doc/mutt/html/mimesupport.html
+#
+
+# Removing a pattern from a list removes that pattern literally. It
+# does not remove any type matching the pattern.
+#
+# attachments +A */.*
+# attachments +A image/jpeg
+# unattachments +A */.*
+#
+# This leaves "attached" image/jpeg files on the allowed attachments
+# list. It does not remove all items, as you might expect, because the
+# second */.* is not a matching expression at this time.
+#
+# Remember: "unattachments" only undoes what "attachments" has done!
+# It does not trigger any matching on actual messages.
+
+# Qualify any MIME part with an "attachment" disposition, EXCEPT for
+# text/x-vcard and application/pgp parts. (PGP parts are already known
+# to mutt, and can be searched for with ~g, ~G, and ~k.)
+#
+# I've added x-pkcs7 to this, since it functions (for S/MIME)
+# analogously to PGP signature attachments. S/MIME isn't supported
+# in a stock mutt build, but we can still treat it specially here.
+#
+
+attachments +A */.*
+attachments -A text/x-vcard application/pgp.*
+attachments -A application/x-pkcs7-.*
+
+
+# Discount all MIME parts with an "inline" disposition, unless they're
+# text/plain. (Why inline a text/plain part unless it's external to the
+# message flow?)
+
+attachments +I text/plain
+
+
+# These two lines make Mutt qualify MIME containers. (So, for example,
+# a message/rfc822 forward will count as an attachment.) The first
+# line is unnecessary if you already have "attach-allow */.*", of
+# course. These are off by default! The MIME elements contained
+# within a message/* or multipart/* are still examined, even if the
+# containers themselves don't qualify.
+
+#attachments +A message/.* multipart/.*
+#attachments +I message/.* multipart/.*
+
+
+## You probably don't really care to know about deleted attachments.
+attachments -A message/external-body
+attachments -I message/external-body
+
+## Then entering the command “attachments ?” as a command will list
+## your current settings in Muttrc format, so that it can be pasted
+## elsewhere.
+
+# vim: filetype=muttrc
diff --git a/.mutt/colors b/.mutt/colors
new file mode 100644
index 0000000..0da5176
--- /dev/null
+++ b/.mutt/colors
@@ -0,0 +1,120 @@
+# -*- muttrc -*-
+#
+# Color settings for mutt.
+#
+# LIweitiaNux
+# February 8, 2012
+#
+# Ref: http://aperiodic.net/phil/configs/mutt/colors
+
+# Default color definitions
+color normal white default
+color hdrdefault green default
+color quoted green default
+color quoted1 yellow default
+color quoted2 blue default
+color signature cyan default
+color indicator brightyellow blue
+color error brightred default
+color status brightwhite blue
+color tree brightmagenta default
+color tilde blue default
+color attachment brightyellow default
+color markers brightblue default
+color message white default
+color search brightwhite magenta
+color bold brightyellow default
+
+# Color definitions when on a mono screen
+mono bold bold
+mono underline underline
+mono indicator reverse
+mono error bold
+
+# Colors for items in the reader
+color header brightyellow default "^(From|Subject):"
+color header brightmagenta default ^Date:
+color header brightcyan default ^To:
+color header brightcyan default ^Cc:
+mono header bold "^(From|Subject):"
+
+# Many of these formulas were stolen from Jeremy Blosser
+# These would be much simpler if colors were additive.
+
+# regular new messages
+color index black white "~N !~T !~F !~p !~P"
+# regular tagged messages
+color index black cyan "~T !~F !~p !~P"
+# regular flagged messages
+color index black blue "~F !~p !~P"
+# messages to me
+color index yellow default "~p !~N !~T !~F !~P"
+color index brightyellow white "~p ~N !~T !~F !~P"
+color index yellow cyan "~p ~T !~F !~P"
+color index yellow blue "~p ~F !~P"
+# messages from me
+color index green default "~P !~N !~T !~F"
+color index green white "~P ~N !~T !~F"
+color index green cyan "~P ~T !~F"
+color index green blue "~P ~F"
+# messages which mention my name in the body
+color index yellow default "~b \"phil(_g|\!| gregory| gold)|pgregory\" !~N !~T !~F !~p !~P"
+color index brightyellow white "~b \"phil(_g|\!| gregory| gold)|pgregory\" ~N !~T !~F !~p !~P"
+color index yellow cyan "~b \"phil(_g|\!| gregory| gold)|pgregory\" ~T !~F !~p !~P"
+color index yellow red "~b \"phil(_g|\!| gregory| gold)|pgregory\" ~F !~p !~P"
+# messages which are in reference to my mails
+color index magenta default "~x \"(mithrandir|aragorn)\\.aperiodic\\.net|thorin\\.hillmgt\\.com\" !~N !~T !~F !~p !~P"
+color index magenta white "~x \"(mithrandir|aragorn)\\.aperiodic\\.net|thorin\\.hillmgt\\.com\" ~N !~T !~F !~p !~P"
+color index magenta cyan "~x \"(mithrandir|aragorn)\\.aperiodic\\.net|thorin\\.hillmgt\\.com\" ~T !~F !~p !~P"
+color index magenta blue "~x \"(mithrandir|aragorn)\\.aperiodic\\.net|thorin\\.hillmgt\\.com\" ~F !~p !~P"
+# messages to root, etc.
+color index cyan default "~C \"(root|postmaster|abuse|mailer-daemon)@\" !~N !~P !~p"
+color index cyan white "~C \"(root|postmaster|abuse|mailer-daemon)@\" ~N !~P !~p"
+# big messages
+color index red default "!~N ~z 10485760-"
+color index red cyan "~T !~F !~p !~P ~z 10485760-"
+color index red white "~N ~z 10485760-"
+
+# deleted messages
+color index brightred default "!~N ~D"
+color index brightred white "~N ~D"
+
+
+# Highlights inside the body of a message.
+
+# Attribution lines
+color body magenta default "\\* [^<]+ <[^>]+> \\[[^]]+\\]:"
+color body magenta default "(^|[^[:alnum:]])on [a-z0-9 ,]+( at [a-z0-9:,. +-]+)? wrote:"
+
+# URLs
+color body brightyellow default "([a-z][a-z0-9+-]*://(((([a-z0-9_.!~*'();:&=+$,-]|%[0-9a-f][0-9a-f])*@)?((([a-z0-9]([a-z0-9-]*[a-z0-9])?)\\.)*([a-z]([a-z0-9-]*[a-z0-9])?)\\.?|[0-9]+\\.[0-9]+\\.[0-9]+\\.[0-9]+)(:[0-9]+)?)|([a-z0-9_.!~*'()$,;:@&=+-]|%[0-9a-f][0-9a-f])+)(/([a-z0-9_.!~*'():@&=+$,-]|%[0-9a-f][0-9a-f])*(;([a-z0-9_.!~*'():@&=+$,-]|%[0-9a-f][0-9a-f])*)*(/([a-z0-9_.!~*'():@&=+$,-]|%[0-9a-f][0-9a-f])*(;([a-z0-9_.!~*'():@&=+$,-]|%[0-9a-f][0-9a-f])*)*)*)?(\\?([a-z0-9_.!~*'();/?:@&=+$,-]|%[0-9a-f][0-9a-f])*)?(#([a-z0-9_.!~*'();/?:@&=+$,-]|%[0-9a-f][0-9a-f])*)?|(www|ftp)\\.(([a-z0-9]([a-z0-9-]*[a-z0-9])?)\\.)*([a-z]([a-z0-9-]*[a-z0-9])?)\\.?(:[0-9]+)?(/([-a-z0-9_.!~*'():@&=+$,]|%[0-9a-f][0-9a-f])*(;([-a-z0-9_.!~*'():@&=+$,]|%[0-9a-f][0-9a-f])*)*(/([-a-z0-9_.!~*'():@&=+$,]|%[0-9a-f][0-9a-f])*(;([-a-z0-9_.!~*'():@&=+$,]|%[0-9a-f][0-9a-f])*)*)*)?(\\?([-a-z0-9_.!~*'();/?:@&=+$,]|%[0-9a-f][0-9a-f])*)?(#([-a-z0-9_.!~*'();/?:@&=+$,]|%[0-9a-f][0-9a-f])*)?)[^].,:;!)? \t\r\n<>\"]"
+
+# email addresses
+color body brightmagenta default "((@(([0-9a-z-]+\\.)*[0-9a-z-]+\\.?|#[0-9]+|\\[[0-9]?[0-9]?[0-9]\\.[0-9]?[0-9]?[0-9]\\.[0-9]?[0-9]?[0-9]\\.[0-9]?[0-9]?[0-9]\\]),)*@(([0-9a-z-]+\\.)*[0-9a-z-]+\\.?|#[0-9]+|\\[[0-9]?[0-9]?[0-9]\\.[0-9]?[0-9]?[0-9]\\.[0-9]?[0-9]?[0-9]\\.[0-9]?[0-9]?[0-9]\\]):)?[0-9a-z_.+%$-]+@(([0-9a-z-]+\\.)*[0-9a-z-]+\\.?|#[0-9]+|\\[[0-2]?[0-9]?[0-9]\\.[0-2]?[0-9]?[0-9]\\.[0-2]?[0-9]?[0-9]\\.[0-2]?[0-9]?[0-9]\\])"
+
+# PGP messages
+color body brightgreen default "^gpg: Good signature .*"
+color body white default "^gpg: "
+color body brightwhite red "^gpg: BAD signature from.*"
+mono body bold "^gpg: Good signature"
+mono body bold "^gpg: BAD signature from.*"
+
+### Various smilies and the like
+color body brightwhite default "<[Gg]>" # <g>
+color body brightwhite default "<[Bb][Gg]>" # <bg>
+color body brightwhite default " [;:]-*[})>{(<|]" # :-) etc...
+# *bold*
+color body brightblue default "(^|[[:space:][:punct:]])\\*[^*]+\\*([[:space:][:punct:]]|$)"
+mono body bold "(^|[[:space:][:punct:]])\\*[^*]+\\*([[:space:][:punct:]]|$)"
+# _underline_
+color body brightblue default "(^|[[:space:][:punct:]])_[^_]+_([[:space:][:punct:]]|$)"
+mono body underline "(^|[[:space:][:punct:]])_[^_]+_([[:space:][:punct:]]|$)"
+# /italic/ (Sometimes gets directory names)
+color body brightblue default "(^|[[:space:][:punct:]])/[^/]+/([[:space:][:punct:]]|$)"
+mono body underline "(^|[[:space:][:punct:]])/[^/]+/([[:space:][:punct:]]|$)"
+
+### Border lines.
+color body blue default "( *[-+=#*~_]){6,}"
+
+#
+# vim: set ts=8 sw=4 tw=0 fenc=utf-8 ft=muttrc: #
diff --git a/.mutt/gpg.rc b/.mutt/gpg.rc
new file mode 100644
index 0000000..e90fc00
--- /dev/null
+++ b/.mutt/gpg.rc
@@ -0,0 +1,113 @@
+# -*-muttrc-*-
+#
+# Command formats for gpg.
+#
+# This version uses gpg-2comp from
+# http://70t.de/download/gpg-2comp.tar.gz
+#
+# $Id$
+#
+# %p The empty string when no passphrase is needed,
+# the string "PGPPASSFD=0" if one is needed.
+#
+# This is mostly used in conditional % sequences.
+#
+# %f Most PGP commands operate on a single file or a file
+# containing a message. %f expands to this file's name.
+#
+# %s When verifying signatures, there is another temporary file
+# containing the detached signature. %s expands to this
+# file's name.
+#
+# %a In "signing" contexts, this expands to the value of the
+# configuration variable $pgp_sign_as. You probably need to
+# use this within a conditional % sequence.
+#
+# %r In many contexts, mutt passes key IDs to pgp. %r expands to
+# a list of key IDs.
+
+# Note that we explicitly set the comment armor header since GnuPG, when used
+# in some localiaztion environments, generates 8bit data in that header, thereby
+# breaking PGP/MIME.
+
+# decode application/pgp
+set pgp_decode_command="gpg --status-fd=2 %?p?--passphrase-fd 0? --no-verbose --quiet --batch --output - %f"
+
+# verify a pgp/mime signature
+set pgp_verify_command="gpg --status-fd=2 --no-verbose --quiet --batch --output - --verify %s %f"
+
+# decrypt a pgp/mime attachment
+set pgp_decrypt_command="gpg --status-fd=2 %?p?--passphrase-fd 0? --no-verbose --quiet --batch --output - %f"
+
+# create a pgp/mime signed attachment
+# set pgp_sign_command="gpg-2comp --comment '' --no-verbose --batch --output - %?p?--passphrase-fd 0? --armor --detach-sign --textmode %?a?-u %a? %f"
+set pgp_sign_command="gpg --no-verbose --batch --quiet --output - %?p?--passphrase-fd 0? --armor --detach-sign --textmode %?a?-u %a? %f"
+
+# create a application/pgp signed (old-style) message
+# set pgp_clearsign_command="gpg-2comp --comment '' --no-verbose --batch --output - %?p?--passphrase-fd 0? --armor --textmode --clearsign %?a?-u %a? %f"
+set pgp_clearsign_command="gpg --no-verbose --batch --quiet --output - %?p?--passphrase-fd 0? --armor --textmode --clearsign %?a?-u %a? %f"
+
+# create a pgp/mime encrypted attachment
+# set pgp_encrypt_only_command="pgpewrap gpg-2comp -v --batch --output - --encrypt --textmode --armor --always-trust -- -r %r -- %f"
+set pgp_encrypt_only_command="pgpewrap gpg --batch --quiet --no-verbose --output - --encrypt --textmode --armor --always-trust -- -r %r -- %f"
+
+# create a pgp/mime encrypted and signed attachment
+# set pgp_encrypt_sign_command="pgpewrap gpg-2comp %?p?--passphrase-fd 0? -v --batch --output - --encrypt --sign %?a?-u %a? --armor --always-trust -- -r %r -- %f"
+set pgp_encrypt_sign_command="pgpewrap gpg %?p?--passphrase-fd 0? --batch --quiet --no-verbose --textmode --output - --encrypt --sign %?a?-u %a? --armor --always-trust -- -r %r -- %f"
+
+# import a key into the public key ring
+set pgp_import_command="gpg --no-verbose --import %f"
+
+# export a key from the public key ring
+set pgp_export_command="gpg --no-verbose --export --armor %r"
+
+# verify a key
+set pgp_verify_key_command="gpg --verbose --batch --fingerprint --check-sigs %r"
+
+# read in the public key ring
+set pgp_list_pubring_command="gpg --no-verbose --batch --quiet --with-colons --list-keys %r"
+
+# read in the secret key ring
+set pgp_list_secring_command="gpg --no-verbose --batch --quiet --with-colons --list-secret-keys %r"
+
+# fetch keys
+# set pgp_getkeys_command="pkspxycwrap %r"
+
+# specify the uid to use when encrypting/signing
+#set pgp_sign_as=0xC0B1382A # FreeBSD
+#set pgp_sign_as=0xB9919753 # Debian
+
+# this set the number of seconds to keep in memory the passpharse
+# used to encrypt/sign the more the less secure it will be
+set pgp_timeout=300
+
+# pattern for good signature - may need to be adapted to locale!
+#
+# it's a regexp used against the GPG output: if it matches some line of the output
+# then mutt considers the message a good signed one (ignoring the GPG exit code)
+set pgp_good_sign="^gpg: Good signature from"
+# set pgp_good_sign="^gpgv?: Good signature from "
+# OK, here's a version which uses gnupg's message catalog:
+# set pgp_good_sign="`gettext -d gnupg -s 'Good signature from "' | tr -d '"'`"
+# This version uses --status-fd messages
+# set pgp_good_sign="^\\[GNUPG:\\] GOODSIG"
+
+# mutt uses by default PGP/GPG to sign/encrypt messages
+# if you want to use S-mime instead set the smime_is_default variable to yes
+
+# automatically sign all outcoming messages
+#set crypt_autosign
+# sign only replies to signed messages
+#set crypt_replysign
+
+# automatically encrypt outcoming messages
+#set crypt_autoencrypt=yes
+# encrypt only replies to signed messages
+#set crypt_replyencrypt=yes
+# encrypt and sign replies to encrypted messages
+#set crypt_replysignencrypted=yes
+
+# automatically verify the sign of a message when opened
+#set crypt_verify_sig=yes
+
+# vim: filetype=muttrc
diff --git a/.mutt/macros b/.mutt/macros
new file mode 100644
index 0000000..faf43e9
--- /dev/null
+++ b/.mutt/macros
@@ -0,0 +1,2 @@
+macro pager \cb <pipe-entry>'urlview'<enter> 'Follow links with urlview'
+
diff --git a/.mutt/mailboxes b/.mutt/mailboxes
new file mode 100644
index 0000000..1f5948f
--- /dev/null
+++ b/.mutt/mailboxes
@@ -0,0 +1 @@
+mailboxes "+autistici/Drafts" "+autistici/INBOX" "+autistici/Sent" "+autistici/Spam" "+autistici/Trash"
diff --git a/.mutt/mailcap b/.mutt/mailcap
new file mode 100644
index 0000000..c9d3b03
--- /dev/null
+++ b/.mutt/mailcap
@@ -0,0 +1,36 @@
+# $Id$
+#
+# mutt mailcap configuration file
+#
+# Weitian LI <liweitianux@gmail.com>
+# 2014/07/13
+#
+
+## 'copiousoutput' tells mutt the cmd passes possibly large amounts
+## of text, causes mutt to invoke a pager. also denote non-interactive.
+
+#text/html; firefox -remote 'openURL(%s)'; test=RunningFirefox
+text/html; w3m -T text/html -I %{charset} -dump %s; nametemplate=%s.html; copiousoutput
+
+image/jpeg; feh %s
+image/png; feh %s
+image/gif; feh %s
+image/*; feh %s
+
+video/*; vlc %s
+
+application/x-compressed-tar; tar -tf %s; copiousoutput
+application/x-gnuzip; gzcat; copiousoutput
+application/x-bzip; bunzip2 -c %s | tar -tf -; copiousoutput
+application/x-tar-gz; gunzip -c %s | tar -tf -; copiousoutput
+application/x-7z-compressed; 7z l %s; copiousoutput
+
+# application/postscript; ps2ascii %s; copiousoutput
+# application/pdf; apvlv %s; copiousoutput
+# application/pdf; mupdf %s; copiousoutput
+application/pdf; pdftotext '%s' -; copiousoutput; description="PDF Document"; nametemplate="%s.pdf"
+application/msword; wvHtml --charset=gb2312 %s - | w3m -dump %s; nametemplate=%s.html; copiousoutput
+# application/vnd.ms-excel;
+
+
+# vim: set ts=8 sw=4 tw=0 fenc=utf-8 ft=mailcap: #
diff --git a/.mutt/mailinglists b/.mutt/mailinglists
new file mode 100644
index 0000000..29aaf72
--- /dev/null
+++ b/.mutt/mailinglists
@@ -0,0 +1,17 @@
+# $Id$
+#
+# mailing lists settings
+# lists and subscribe
+#
+# LIweitiaNux
+# February 9, 2012
+#
+
+## lists
+lists ^opensourcesjtu2010@googlegroups\.com$
+
+## subscribe
+subscribe ^astro-ph@arXiv\.org$
+subscribe en@bsdmag\.org$
+
+# vim: filetype=muttrc
diff --git a/.mutt/muttrc b/.mutt/muttrc
new file mode 100644
index 0000000..7d593d0
--- /dev/null
+++ b/.mutt/muttrc
@@ -0,0 +1,202 @@
+# $Id$
+#
+###########################################################
+## mutt configuration file ##
+## ##
+## Weitian LI <liweitianux@gmail.com> ##
+## 2014/07/13 ##
+###########################################################
+
+### personal settings
+set realname = "Weitian LI"
+### mailboxes
+# from 'offlineimap'
+source ~/.mutt/mailboxes
+### gmail, use as default
+source ~/.mutt/gmail.muttrc
+### account specific sources
+folder-hook 'gmail.*' source ~/.mutt/gmail.muttrc
+folder-hook 'lavabit.*' source ~/.mutt/lavabit.muttrc
+folder-hook 'autistici.*' source ~/.mutt/autistici.muttrc
+
+### files and directories
+set alias_file = ~/.mutt/aliases
+#set header_cache = ~/.mutt/cache/headers # needs external db lib
+set message_cachedir = ~/.mutt/cache
+set certificate_file = ~/.mutt/certificates
+set mailcap_path = ~/.mutt/mailcap
+set signature = ~/.mutt/signature
+set history_file = ~/.mutt/history
+set tmpdir = ~/.mutt/tmp
+
+### settings
+set mbox_type = Maildir
+set folder = ~/Maildir
+set mail_check = 300 # how often (in s) look for new mail
+set timeout = 15 # prompt timeout until abort waiting for input
+#set sendmail_wait = -1 # always put sendmail in the bkg without waiting
+set sleep_time = 0 # time to pause while displaying certain info msgs
+set wait_key # wait after an external cmd invoked
+set history = 128 # control the size of the string history buffer
+set save_history = 128 # control the size of the 'history_file'
+unset confirmappend # don't ask me if i want to append to mailboxes
+set beep_new # beep when receive a new msg while mailbox open
+set copy # always save a copy of outgoing messages
+set delete # purge deleted messages without asking
+set quit = ask-yes # ask for confirmation when quit mutt
+set wrap_search # searches wrap around the end
+set help # show the help lines
+set use_from # always generate the `From:' header field
+set read_inc = 25 # specify at which rate to update progress counters
+set write_inc = 25
+set print = ask-yes # ask me if I really want to print messages
+set print_command = /usr/bin/false # how to print things (I like to save trees)
+
+### index settings
+#set date_format = "%m/%d/%y at %I:%M"
+#set index_format = "%4C %Z %{%m/%d} %-15.15F (%4c) %s" # format of the index
+set to_chars = " +TCFL" # char used to indicate mail addressed to you
+set sort = threads # primary sorting method
+set sort_aux = reverse-date-received
+set uncollapse_jump # don't collapse on an unread message
+set sort_re # thread based on regex
+set reply_regexp = "^(([Rr][Ee]?(\[[0-9]+\])?: *)?(\[[^]]+\] *)?)*"
+
+### pager settings
+set pager_format="-%S- %-20.20f %s" # format of the pager status bar
+set pager_index_lines = 5 # number of index lines to show
+set pager_context = 5 # number of context lines to show
+set pager_stop # don't go to next message automatically
+set menu_scroll # scroll in menus
+set smart_wrap # don't split words
+set tilde # show tildes like in vim
+unset markers # no ugly '+' signs for wrapped lines
+set noprompt_after # ask me for a command after the external pager exits
+set quote_regexp = "^( {0,4}[>|:#%]| {0,4}[a-z0-9]+[>|]+)+"
+
+### composing mail
+set editor = "vim +/^$ -c 'set syntax=mail ft=mail enc=utf-8'"
+set visual = "vim +/^$ -c 'set syntax=mail ft=mail enc=utf-8'"
+set envelope_from # which from?
+set sig_dashes # dashes before my 'signature'
+set autoedit # go to the editor right away when composing
+ # set, cannot use 'send-hooks' depend on recipients
+set edit_headers # show headers when composing
+set askcc # ask for CC:
+set askbcc # ask for BCC:
+set fcc_attach # save attachments with the body
+set forward_format = "Fwd: %s"
+set forward_quote # include message in forwards
+set forward_decode # decode when forwarding
+unset mime_forward # forward attachments as part of body
+set attribution = "On %d, %n wrote: "
+#set metoo # sends a copy to all recipients and myself
+set fast_reply # skip to compose when replying
+set reply_to # reply to 'Reply to:' field
+set reverse_name # reply as whomever it was to
+set nosave_empty # remove files when no messages are left
+#set postpone # auto postpone message not sent when exit
+#set recall # prompt to recall postponed messages
+set include # include message in replies
+#set post_indent_string = '---end quoted text---'
+unset bounce_delivered # not include 'Delivered-To' headers, 'postfix'
+## charset
+set send_charset = "utf-8" # for messages that we send
+set assumed_charset = "iso-8859-1" # if no charset given on incoming messages
+
+### headers settings
+ignore * # ignore all headers
+unignore from: to cc bcc date subject # show only these headers
+hdr_order from: to cc date subject
+
+### aliases
+# set alias_file = ~/.mutt/aliases
+set sort_alias = alias # sort alias file by alias
+set reverse_alias # show names from alias file in index
+#set alias_format = "%4n %t %-20a %r"
+source $alias_file # enable auto-completion
+
+### abook
+set query_command = "abook --mutt-query '%s'"
+macro generic,index,pager \Ca "<shell-escape>abook<return>" "launch abook"
+macro index,pager A "<pipe-message>abook --add-email<return>" "add the sender address to abook"
+
+### key bindings
+bind index,pager \# noop
+bind index i noop
+
+bind pager i exit
+bind pager / search
+bind pager <UP> previous-line
+bind pager <DOWN> next-line
+bind pager k previous-line
+bind pager j next-line
+bind pager gg top
+bind pager G bottom
+bind pager K previous-undeleted
+bind pager J next-undeleted
+bind index,browser gg first-entry
+bind index,browser G last-entry
+bind index K previous-unread
+bind index J next-unread
+bind index,pager R group-reply
+
+### macros
+macro pager ';' "<exit><tag-prefix>" "q+ ;"
+macro index q "<sync-mailbox><change-folder>?<toggle-mailboxes>" "Leaves Index to folder list"
+macro browser q "<exit><quit>" "Exit mutt"
+macro browser <Tab> "<toggle-mailboxes><check-new>" "Check New"
+macro index \Cr "<tag-prefix><clear-flag>N" "mark tagged messages as read"
+macro index B "<limit>~b " "search message bodies"
+macro index I "<change-folder>!<enter>" "go to Inbox"
+# save a decoded copy in ~
+macro index P "<pipe-message>cat > ~/" "save message as"
+# quick-sync with offlineimap
+macro index,browser Z "<shell-escape>offlineimap -o -u ttyui<enter>" "offlineimap sync ..."
+# urlview
+macro pager \Cu "<pipe-entry>urlview<enter>" "Follow links with urlview"
+
+
+###########################################################
+## Misc settings ##
+###########################################################
+## mailing lists: lists and subscribe
+set followup_to # generate 'Mail-Followup-To:' header field
+set honor_followup_to # 'Mail-Followup-To' header is honored
+source ~/.mutt/mailinglists
+
+## mutt colors definitions
+source ~/.mutt/colors
+#set arrow_cursor # use '->' instead of hiliting the whole line
+
+## GnuPG
+source ~/.mutt/gpg.rc
+
+## auto view
+auto_view text/html application/x-gunzip application/x-bzip application/x-tar-gz \
+ application/x-compressed-tar application/msword application/postscript
+
+## MIME multipart/alternative
+## The 'multipart/alternative' container type only has child MIME parts
+## which represent the same content in an alternative way. often used to
+## send HTML msgs which contain an alternative plain text representation.
+alternative_order text/plain text/enriched text/html application/postscript
+
+## MIME lookup, mime-lookup
+## specifies a list of MIME types that should *not* be treated
+## according to their mailcap entry
+mime_lookup application/octet-stream application/X-Lotus-Manuscript
+
+## attachment searching and counting
+## attachments { +|- } disposition mime-type
+## 'disposition': inline(I), attachment(A)
+source ~/.mutt/attachments
+
+## cope with encodings
+# attachment encodeing
+set rfc2047_parameters = yes
+# some mail without 'charset', then set 'us-ascii' as an alias to 'gb2312'
+charset-hook ^us-ascii$ gb2312
+
+#
+# vim: set ts=8 sw=4 tw=0 fenc=utf-8 ft=muttrc: #
diff --git a/.mutt/muttrc.bak b/.mutt/muttrc.bak
new file mode 100644
index 0000000..7cca10c
--- /dev/null
+++ b/.mutt/muttrc.bak
@@ -0,0 +1,172 @@
+# $Id$
+#
+##########################################
+## mutt configuration file ##
+## ##
+## LIweitiaNux ##
+## February 6, 2012 ##
+##########################################
+
+### files and directories
+set alias_file = ~/.mutt/aliases
+#set header_cache = ~/.mutt/cache/headers # needs external db lib
+set message_cachedir = ~/.mutt/cache
+set certificate_file = ~/.mutt/certificates
+set mailcap_path = ~/.mutt/mailcap
+set signature = ~/.mutt/signature
+set history_file = ~/.mutt/history
+set tmpdir = ~/.mutt/tmp
+
+### settings
+set mbox_type = Maildir
+set folder = ~/Maildir
+set mail_check = 300 # how often (in s) look for new mail
+set timeout = 15 # prompt timeout until abort waiting for input
+#set sendmail_wait = -1 # always put sendmail in the bkg without waiting
+set sleep_time = 0 # time to pause while displaying certain info msgs
+set history = 128 # control the size of the string history buffer
+set save_history = 128 # control the size of the 'history_file'
+unset confirmappend # don't ask me if i want to append to mailboxes
+set beep_new # beep when receive a new msg while mailbox open
+set copy # always save a copy of outgoing messages
+set delete # purge deleted messages without asking
+set quit = ask-yes # ask for confirmation when quit mutt
+#set date_format = "%m/%d/%y at %I:%M"
+set wrap_search # searches wrap around the end
+set help # show the help lines
+set use_from # always generate the `From:' header field
+set read_inc = 25 # specify at which rate to update progress counters
+set write_inc = 25
+set print = ask-yes # ask me if I really want to print messages
+set print_command = /usr/bin/false # how to print things (I like to save trees)
+
+### index settings
+set index_format = "%4C %Z %{%m/%d} %-15.15F (%4c) %s" # format of the index
+set sort = threads # primary sorting method
+set sort_aux = reverse-date-received
+set uncollapse_jump # don't collapse on an unread message
+set sort_re # thread based on regex
+set reply_regexp = "^(([Rr][Ee]?(\[[0-9]+\])?: *)?(\[[^]]+\] *)?)*"
+
+### pager settings
+set pager_format="-%S- %-20.20f %s" # format of the pager status bar
+set pager_index_lines = 5 # number of index lines to show
+set pager_context = 5 # number of context lines to show
+set pager_stop # don't go to next message automatically
+set menu_scroll # scroll in menus
+set smart_wrap # don't split words
+set tilde # show tildes like in vim
+unset markers # no ugly '+' signs for wrapped lines
+set noprompt_after # ask me for a command after the external pager exits
+set quote_regexp = "^( {0,4}[>|:#%]| {0,4}[a-z0-9]+[>|]+)+"
+
+### composing mail
+set editor = "vim +/^$"
+set visual = "vim +/^$"
+set realname = "LIweitiaNux"
+set envelope_from # which from?
+set sig_dashes # dashes before my 'signature'
+set autoedit # go to the editor right away when composing
+ # set, cannot use 'send-hooks' depend on recipients
+set edit_headers # show headers when composing
+set askcc # ask for CC:
+set askbcc # ask for BCC:
+set fcc_attach # save attachments with the body
+unset mime_forward # forward attachments as part of body
+set forward_format = "Fwd: %s"
+set forward_quote # include message in forwards
+set forward_decode # decode when forwarding
+set attribution = "On %d, %n wrote: "
+#set metoo # sends a copy to all recipients and myself
+set fast_reply # skip to compose when replying
+set reply_to # reply to 'Reply to:' field
+set reverse_name # reply as whomever it was to
+set nosave_empty # remove files when no messages are left
+#set postpone # auto postpone message not sent when exit
+#set recall # prompt to recall postponed messages
+set include # include message in replies
+#set post_indent_string = '---end quoted text---'
+
+### headers settings
+ignore * # ignore all headers
+unignore from: to cc bcc date subject # show only these headers
+hdr_order from: to cc date subject
+
+### mailboxes
+# from 'offlineimap'
+source ~/.mutt/mailboxes
+
+### gmail, use as default
+source ~/.mutt/gmail.muttrc
+### account specific sources
+folder-hook gmail.* source ~/.mutt/gmail.muttrc
+folder-hook lavabit.* source ~/.mutt/lavabit.muttrc
+
+### aliases
+# set alias_file = ~/.mutt/aliases
+set sort_alias = alias # sort alias file by alias
+set reverse_alias # show names from alias file in index
+set alias_format = "%4n %t %-20a %r"
+source $alias_file # enable auto-completion
+
+### bindings
+bind index,pager \# noop
+bind index i noop
+bind pager i exit
+bind pager / search
+bind pager <up> previous-line
+bind pager <down> next-line
+bind pager k previous-line
+bind pager j next-line
+bind pager gg top
+bind pager G bottom
+bind pager K previous-undeleted
+bind pager J next-undeleted
+bind index gg first-entry
+bind index G last-entry
+bind index K previous-unread
+bind index J next-unread
+bind index,pager R group-reply
+
+### macros
+macro index \Cr "<tag-prefix><clear-flag>N" "mark tagged messages as read"
+macro index B "<limit>~b " "search message bodies"
+macro index I "<change-folder>!<enter>" "go to Inbox"
+# save a decoded copy in ~
+macro index P "<pipe-message>cat > ~/" "save message as"
+# quick-sync with offlineimap
+macro index Z "<shell-escape>offlineimap -o -q -u ttyui<enter>" "offlineimap sync ..."
+
+### Misc settings
+## mutt colors definitions
+source ~/.mutt/colors
+#set arrow_cursor # use -> instead of hiliting the whole line
+
+## zh attachment encodeing
+set rfc2047_parameters = yes
+
+## GnuPG
+source ~/.mutt/gpg.rc
+
+## auto view
+auto_view text/html application/x-gunzip application/x-tar-gz \
+ application/msword application/postscript
+
+## MIME multipart/alternative
+## The 'multipart/alternative' container type only has child MIME parts
+## which represent the same content in an alternative way. often used to
+## send HTML msgs which contain an alternative plain text representation.
+alternative_order text/plain text/enriched text/html application/postscript
+
+## attachment searching and counting
+## attachments { +|- } disposition mime-type
+## 'disposition': inline(I), attachment(A)
+source ~/.mutt/attachments
+
+## MIME lookup, mime-lookup
+## specifies a list of MIME types that should *not* be treated
+## according to their mailcap entry
+mime_lookup application/octet-stream application/X-Lotus-Manuscript
+
+#
+# vim: filetype=muttrc
diff --git a/.mutt/sample.muttrc b/.mutt/sample.muttrc
new file mode 100644
index 0000000..07dbe17
--- /dev/null
+++ b/.mutt/sample.muttrc
@@ -0,0 +1,340 @@
+# $Id$
+
+# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+#
+# ME's personal .muttrc (Mutt 0.92.5)
+#
+# The format of this file is one command per line. Everything after a pound
+# sign (#) is a comment, unless a backward slash (\) precedes it. Note: In
+# folder-hook and send-hook you need to account for two levels of dequoting
+# (see manual).
+#
+
+# Note: $folder should be set _before_ any other path vars where `+' or `='
+# is used because paths are expanded when parsed
+#
+#set folder=~/Mail # where i keep my mailboxes
+
+#set abort_unmodified=yes # automatically abort replies if I don't
+ # change the message
+set alias_file=~/.mail_aliases # where I keep my aliases
+#set allow_8bit # never do Q-P encoding on legal 8-bit chars
+set arrow_cursor # use -> instead of hiliting the whole line
+#set ascii_chars # use ASCII instead of ACS chars for threads
+#set askbcc
+#set askcc
+#set attribution="On %d, %n wrote:" # how to attribute replies
+set autoedit # go to the editor right away when composing
+#set auto_tag # always operate on tagged messages
+#set charset="iso-8859-1" # character set for your terminal
+set noconfirmappend # don't ask me if i want to append to mailboxes
+#set confirmcreate # prompt when creating new files
+set copy=yes # always save a copy of outgoing messages
+set delete=yes # purge deleted messages without asking
+set edit_headers # let me edit the message header when composing
+#set editor="emacs -nw" # editor to use when composing messages
+#set bounce=yes # don't ask about bouncing messages, just do it
+#set fast_reply # skip initial prompts when replying
+#set fcc_attach # keep attachments in copies of sent messages?
+#set force_name # fcc by recipient, create if mailbox doesn't exist
+#set forward_decode # weed and MIME decode forwaded messages
+#set forward_format="[%a: %s]" # subject to use when forwarding messages
+#set forward_quote # quote the header and body of forward msgs
+#set index_format="%4C %Z %{%m/%d} [%2N] %-15.15F (%4c) %s"
+set index_format="%4C %Z %{%m/%d} %-15.15F (%4c) %s" # format of the index
+#set hdrs # include `my_hdr' lines in outgoing messages
+#set header # include message header when replying
+set help # show the help lines
+#set history=20 # number of lines of history to remember
+#set hostname="mutt.org" # my DNS domain
+set include # always include messages when replying
+#set indent_string="> " # how to quote replied text
+#set locale="C" # locale to use for printing time
+#set mailcap_path="~/.mailcap:/usr/local/share/mailcap"
+set nomark_old # i don't care about whether a message is old
+set mail_check=10 # how often to poll for new mail
+set mbox=+mbox # where to store read messages
+#set menu_scroll # no implicit next-page/prev-page
+#set metoo # remove my address when replying
+set mime_forward # use message/rfc822 type to forward messages
+set move=yes # don't ask about moving messages, just do it
+#set pager=less # some people prefer an external pager
+#set pager_context=3 # no. of lines of context to give when scrolling
+#set pager_format="-%S- %-20.20f %s" # format of the pager status bar
+set pager_index_lines=6 # how many index lines to show in the pager
+#set pager_stop # don't move to the next message on next-page
+#set pgp_strict_enc # use Q-P encoding when needed for PGP
+set postponed=+postponed # mailbox to store postponed messages in
+#set post_indent_string='---end quoted text---'
+#set print=ask-yes # ask me if I really want to print messages
+set print_command=/bin/false # how to print things (I like to save trees)
+set noprompt_after # ask me for a command after the external pager exits
+#set quote_regexp="^ *[a-zA-Z]*[>:#}]" # how to catch quoted text
+set read_inc=25 # show progress when reading a mailbox
+#set recall # prompt to recall postponed messages
+set record=+outbox # default location to save outgoing mail
+set reply_to # always use reply-to if present
+#set reply_regexp="^(re:[ \t]*)+"# how to identify replies in the subject:
+#set resolve # move to the next message when an action is performed
+#set reverse_alias # attempt to look up my names for people
+set reverse_name # use my address as it appears in the message
+ # i am replying to
+set nosave_empty # remove files when no messages are left
+#set save_name # save outgoing messages by recipient, if the
+#set sendmail="/usr/lib/sendmail -oi -oem" # how to deliver mail
+#set shell="/bin/zsh" # program to use for shell escapes
+#set signature="~/.signature" # file which contains my signature
+
+# I subscribe to a lot of mailing lists, so this is _very_ useful. This
+# groups messages on the same subject to make it easier to follow a
+# discussion. Mutt will draw a nice tree showing how the discussion flows.
+set sort=threads # primary sorting method
+
+#set sort_aux=reverse-date-received # how to sort subthreads
+#set sort_aux=last-date # date of the last message in thread
+set sort_browser=reverse-date # how to sort files in the dir browser
+set spoolfile='~/mailbox' # where my new mail is located
+#set status_format="-%r-Mutt: %f [Msgs:%?M?%M/?%m%?n? New:%n?%?d? Del:%d?%?F? Flag:%F?%?t? Tag:%t?%?p? Post:%p?%?b? Inc:%b? %l]---(%s)-%>-(%P)---"
+#set status_on_top # some people prefer the status bar on top
+#set strict_threads # don't thread by subject
+set tilde # virtual lines to pad blank lines in the pager
+#set timeout=0 # timeout for prompt in the index menu
+#set tmpdir=~/tmp # where to store temp files
+#set to_chars=" +TCF"
+#set use_8bitmime # enable the -B8BITMIME sendmail flag
+set nouse_domain # don't qualify local addresses with $domain
+#set use_from # always generate the `From:' header field
+set implicit_autoview=yes # pager shows parts having a mailcap viewer
+set pgp_verify_sig=no # don't automatically verify message signatures
+#set visual=vim # editor invoked by ~v in the builtin editor
+#set nowait_key # prompt when a pipe returns normal status
+set write_inc=25 # show progress while writing mailboxes
+
+# only enable the following IFF you have sendmail 8.8.x or you will not
+# be able to send mail!!!
+#set dsn_notify='failure,delay' # when to return an error message
+#set dsn_return=hdrs # what to return in the error message
+
+# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+#
+# Header fields I don't normally want to see
+#
+ignore * # this means "ignore all lines by default"
+
+# I do want to see these fields, though!
+unignore from: subject to cc mail-followup-to \
+ date x-mailer x-url # this shows how nicely wrap long lines
+
+# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+#
+# Color definitions
+#
+
+#color normal white default
+color hdrdefault red default
+color quoted brightblue default
+color signature red default
+color indicator brightyellow red
+color error brightred default
+color status yellow blue
+color tree magenta default # the thread tree in the index menu
+color tilde magenta default
+color message brightcyan default
+color markers brightcyan default
+color attachment brightmagenta default
+color search default green # how to hilite search patterns in the pager
+
+color header brightred default ^(From|Subject):
+color body magenta default "(ftp|http|https)://[^ ]+" # point out URLs
+color body magenta default [-a-z_0-9.]+@[-a-z_0-9.]+ # e-mail addresses
+color underline brightgreen default
+
+# attributes when using a mono terminal
+#mono header underline ^(From|Subject):
+mono quoted bold
+
+# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+#
+# Key bindings
+#
+# maps:
+# alias alias menu
+# attach attachment menu
+# browser directory browser
+# compose compose menu
+# index message index
+# pgp pgp menu
+# postpone postponed message recall menu
+# generic generic keymap for all of the above
+# editor line editor
+# pager text viewer
+#
+
+bind generic "\e<" first-entry # emacs-like bindings for moving to top/bottom
+bind generic \e> last-entry
+bind generic { top-page
+bind generic } bottom-page
+bind generic \177 last-entry
+
+macro index \cb "<pipe-message> urlview<Enter>" # simulate the old browse-url function
+
+macro index S "<save-message>+spam<Enter>"
+macro pager S "<save-message>+spam<Enter>"
+
+#macro index \# "<search>bug<Enter>" # search for bugs
+#macro index "\"" "<enter-command> set realname=\"real hairy macro\" ?realname<Enter>" # and a comment to boot!
+#macro index f1 "<enter-command>woohoo!"
+
+bind pager G bottom # just like vi and less
+#macro pager \Ck "<pipe-message> pgp -kaf<Enter>" # a comment is valid here
+#macro pager X "<pipe-message> morepgp<Enter>" # pipe PGP message to a script
+
+#bind editor \cy eol # make ^Y jump to the end of the line
+
+# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+#
+# User Defined Headers
+#
+
+#my_hdr X-Useless-Header: Look ma, it's a \# sign! # real comment
+#my_hdr X-Operating-System: `uname -a`
+
+# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+#
+# Specify default filename when saving messages
+#
+# save-hook [!]<pattern> <mailbox>
+#
+# <mailbox> is provided as default when saving messages from <pattern>
+
+#save-hook mutt- =mutt-mail
+#save-hook aol\\.com$ +spam
+save-hook ^judge +diplomacy
+
+# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+#
+# Multiple spool mailboxes
+#
+# mbox-hook [!]<pattern> <mbox-mailbox>
+#
+# Read mail in <pattern> is moved to <mbox-mailbox> when <pattern> is
+# closed.
+
+#mbox-hook =mutt-users.in =mutt-users
+#mbox-hook +TEST +inbox
+
+# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+#
+# Change settings based upon message recipient
+#
+# send-hook [!]<pattern> <command>
+#
+# <command> is executed when sending mail to an address matching <pattern>
+
+#send-hook mutt- 'set signature=~/.sigmutt; my_hdr From: Mutt User <user@example.com>'
+
+# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+#
+# Specify where to save composed messages
+#
+# fcc-hook [!]<pattern> <mailbox>
+#
+# <pattern> is recipient(s), <mailbox> is where to save a copy
+
+#fcc-hook joe +joe
+#fcc-hook bob +bob
+
+# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+#
+# Change settings based on mailbox
+#
+# folder-hook [!]<pattern> <command>
+#
+# <command> is executed when opening a mailbox matching <pattern>
+
+#folder-hook . 'set sort=date-sent'
+#folder-hook mutt 'set index_format="%4C %Z %02m/%02N %-20.20F (%4l) %s"'
+#folder-hook =mutt my_hdr Revolution: \#9 # real comment
+
+#folder-hook . 'set reply_regexp="^re:[ \t]*"'
+
+# this mailing list prepends "[WM]" to all non reply subjects, so set
+# $reply_regexp to ignore it
+# Warning: May break threads for other people.
+#folder-hook +wmaker 'set reply_regexp="^(re:[ \t]*)?\[WM\][ \t]*"'
+
+# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+#
+# Aliases
+#
+# alias <name> <address> [ , <address> ... ]
+
+#alias exam "\# to annoy michael" <user@host>
+#alias me Michael Elkins <me@mutt.org> # me!
+alias mutt-dev Mutt Development List <mutt-dev@mutt.org> # power users
+alias mutt-users Mutt User List <mutt-users@mutt.org>
+alias mutt-announce Mutt Announcement List <mutt-announce@mutt.org>
+alias wmaker WindowMaker Mailing List <wmaker@eosys.com>
+
+# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+#
+# Mailboxes to watch for new mail
+#
+# mailboxes <path1> [ <path2> ... ]
+#
+
+mailboxes ! +mutt-dev +mutt-users +open-pgp +wmaker +hurricane +vim +ietf \
+ +drums
+#mailboxes `echo $HOME/Mail/*`
+
+# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+#
+# Specify the order of the headers to appear when displaying a message
+#
+# hdr_order <hdr1> [ <hdr2> ... ]
+#
+
+unhdr_order * # forget the previous settings
+hdr_order date from subject to cc
+
+# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+#
+# Identify mailing lists I subscribe to
+#
+# lists <list-name> [ <list-name> ... ]
+
+lists ^mutt-dev@mutt\\.org$ ^mutt-users@mutt\\.org$
+
+# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+#
+# Automatically use entries from ~/.mailcap to view these MIME types
+#
+# auto_view <type> [ <type> ... ]
+
+auto_view application/x-gunzip
+auto_view application/x-gzip
+
+# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+#
+# Scoring
+#
+# score <pattern> <value>
+#
+# 9999 and -9999 are special values which cause processing of hooks to stop
+# at that entry. If you prefix the score with an equal sign (=), the score
+# is assigned to the message and processing stops.
+
+#score '~f ^me@cs\.hmc\.edu$' 1000
+#score '~t mutt | ~c mutt' =500
+#score '~f aol\.com$' -9999
+
+# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+#
+# I use Mutt on several different machines, so I put local config commands
+# in a separate file so I can have the rest of the settings the same on all
+# machines.
+#
+
+source ~/.muttrc-local # config commands local to this site
+
+# EOF
diff --git a/.mutt/zh b/.mutt/zh
new file mode 100644
index 0000000..e773420
--- /dev/null
+++ b/.mutt/zh
@@ -0,0 +1,54 @@
+#
+# mutt zh settings
+#
+
+## Ref: http://forum.ubuntu.org.cn/viewtopic.php?f=73&t=322014
+#set send_charset="us-ascii:iso-8859-1:gb2312:utf-8"
+set send_charset="gb2312"
+set assumed_charset="utf-8:gb2312:gb18030:gbk"
+set locale="zh_CN.UTF-8"
+charset-hook ^us-ascii$ GB2312
+charset-hook !UTF-8 GB2312
+auto_view text/html
+set rfc2047_parameters=yes
+
+## Ref: http://leeon.me/a/mutt-muttrc-chinese-configuration-note
+#当 Mutt 用 thread 方式显示时,是否用纯 ascii 表示树状列表。
+set ascii_chars=yes
+#回信的引文之前插入那个符号?
+set indent_str="> "
+#打分
+#新信件+4分,主题包含“通知”的+2,主题包含 “Circulation” +3, 已经标记删除的 -5,上次没有读的 +1,包含 “believe”的 -10(垃圾广告!)。
+score "~N" +4
+score "~s 通知" +2
+score "~s Circulation" +3
+score "~D" -5
+score "~O" +1
+score "~s believe" -10
+#排序方式。
+set sort=score
+#当用 thread 排序方式时,我们对各个 thread 的相对排序顺序。
+set sort_aux=date
+#你的终端支持哪一种编码的显示?这个必须和你的终端编码一样。推荐用utf8
+set charset="utf8"
+#send_charset
+#set send_charset="us-ascii:iso-8859-1:gb2312:utf-8"
+set send_charset="us-ascii:iso-8859-1:gb2312:utf-8"
+#外部程序退出时,是否要求用户按一个键才返回。这在察看某些shell命令输出时是比要的,
+#否则它们一下就消失了。
+set wait_key=yes
+#mutt显示日期为中文
+set locale="zh_CN"
+#有些没有设置字符编码时
+charset-hook ^us-ascii$ gb2312
+#Chinaren 等服务器发出来的信件使用了 quoted-printable 的 subject,
+#而且设置编码为 "iso8859-1",这显然是错误的。
+#对付这个错误的办法是把 iso-8859-1 变成 gb2312 的别名
+charset-hook ^iso-8859-1$ gb2312
+# evolution 发过来的 subject 为 utf-8 编码的邮件标题乱码!
+#那就把不是 utf-8 的编码都映射到 gb2312
+charset-hook !utf-8 gb2312
+charset-hook .* gb2312
+
+
+# vim: filetype=muttrc
diff --git a/.offlineimap/offlineimap.py b/.offlineimap/offlineimap.py
new file mode 100644
index 0000000..50f91e2
--- /dev/null
+++ b/.offlineimap/offlineimap.py
@@ -0,0 +1,63 @@
+#!/usr/bin/env python
+#
+# Ref:
+# Encrypt OfflineIMAP Password
+# http://unix.stackexchange.com/questions/44214/encrypt-offlineimap-password
+#
+# Configurations:
+# [general]
+# pythonfile = ~/.offlineimap/offlineimap.py
+# ...
+# [Repository <reponame>]
+# remotepasseval = mailpasswd("<accountname>")
+# ...
+#
+# 2014/06/20
+#
+
+import os
+import subprocess
+
+def mailpasswd(account):
+ account = os.path.basename(account)
+ path = '{0}/.offlineimap/{1}.gpg'.format(os.environ['HOME'], account)
+ args = ['gpg', '--use-agent', '--quiet', '--batch', '-d', path]
+ try:
+ return subprocess.check_output(args).strip()
+ except subprocess.CalledProcessError:
+ return ''
+
+# subprocess.check_output() only introduced in python 2.7
+# this version of 'mailpasswd' works with older version of python
+#def mailpasswd(account):
+# account = os.path.basename(account)
+# path = '{0}/.offlineimap/{1}.gpg'.format(os.environ['HOME'], account)
+# args = ['gpg', '--use-agent', '--quiet', '--batch', '-d', path]
+# proc = subprocess.Popen(args, stdout=subprocess.PIPE)
+# output = proc.communicate()[0].strip()
+# retcode = proc.wait()
+# if retcode == 0:
+# return output
+# else:
+# return ''
+
+
+# If you have several accounts that get checked simultaneously, and you
+# use 'gpg-agent', then it will ask for you passphrase for each account.
+# I prime the agent by creating a file, and priming the gpg-agent by
+# decrypting this file on launch of offlineimap.
+def prime_gpg_agent():
+ # echo "prime" | gpg -e -r <recipient> > ~/.offlineimap/prime.gpg
+ ret = False
+ i = 1
+ while not ret:
+ ret = (mailpasswd("prime") == "prime")
+ if i > 2:
+ from offlineimap.ui import getglobalui
+ sys.stderr.write("Error reading in passwords. Terminating.\n")
+ getglobalui().terminate()
+ i += 1
+ return ret
+
+prime_gpg_agent()
+
diff --git a/.offlineimaprc b/.offlineimaprc
new file mode 100644
index 0000000..11b7f3c
--- /dev/null
+++ b/.offlineimaprc
@@ -0,0 +1,113 @@
+#
+# offlineimap configuration file
+#
+# LIweitiaNux
+# February 6, 2012
+#
+# Ref: http://pbrisbin.com/posts/two_accounts_in_mutt
+#
+
+[general]
+# mailpasswd
+pythonfile = ~/.offlineimap/offlineimap.py
+# This should contain a comma delimited list of all
+# identifiers of the accounts that are to be synced
+#accounts = gmail, lavabit
+accounts = autistici
+# Control how many accuonts may be synced simulaneously
+maxsyncaccounts = 1
+# UI, NOTE: cron job calls the quiet UI with -u
+#ui = blinkenlights
+ui = ttyui
+#ui = quiet # This will suppress anything but errors
+
+
+[Account autistici]
+localrepository = autistici-local
+remoterepository = autistici-remote
+#autorefresh = 10
+#
+[Repository autistici-local]
+type = Maildir
+localfolders = ~/Maildir/autistici
+#
+[Repository autistici-remote]
+type = IMAP
+remotehost = mail.autistici.org
+ssl = yes
+#cert_fingerprint = eea375e1c67a1464ecc6c3a7e6ca9596d1c2dae5
+sslcacertfile = ~/.msmtp/autistici_ca.crt
+remoteport = 993
+remoteuser = liweitianux@autistici.org
+#remotepass = password
+remotepasseval = mailpasswd("autistici")
+
+
+[Account gmail]
+# The identifier for the local repository; e.g., the
+# maildir that offlineimap will sync with an IMAP server
+localrepository = gmail-local
+# The identifier for the remote repository. This is
+# the actual IMAP, which is usually foreign to the system
+remoterepository = gmail-remote
+# Minutes between syncs
+#autorefresh = 10
+# Number of quick-syncs between autorefreshes. Quick-syncs
+# do not update if the only changes were to IMAP flags
+#quick = 10
+
+[Repository gmail-local]
+# offlineimap now only supports Maildir and IMAP for local repositories
+type = Maildir
+localfolders = ~/Maildir/gmail
+
+[Repository gmail-remote]
+# Remote repository can be IMAP or Gmail
+type = Gmail
+remotehost = imap.gmail.com
+ssl = yes
+remoteport = 993
+#remoteuser = username
+#remotepass = password
+nametrans = lambda foldername: re.sub ('^\[gmail\]', 'bak',
+ re.sub ('sent_mail', 'sent',
+ re.sub ('starred', 'flagged',
+ re.sub (' ', '_', foldername.lower()))))
+folderfilter = lambda foldername: foldername not in '[Gmail]/All Mail'
+# Instead of closing the connection once a sync is complete,
+# offlineimap will send empty data to the server to hold the
+# connection open. A value of 60 attempts to hold the connection
+# for a minute between syncs (both quick and autorefresh)
+#keepalive = 60
+
+
+[Account lavabit]
+localrepository = lavabit-local
+remoterepository = lavabit-remote
+#autorefresh = 10
+#quick = 10
+
+[Repository lavabit-local]
+type = Maildir
+localfolders = ~/Maildir/lavabit
+
+[Repository lavabit-remote]
+type = IMAP
+remotehost = imap.lavabit.com
+ssl = yes
+remoteport = 993
+#remoteuser = username
+#remotepass = password
+
+
+# Generate a muttrc fragment containing the mailboxes
+# that it syncs
+# NOTE: add "source ~/.mutt/mailboxes" to "muttrc"
+[mbnames]
+enabled = yes
+filename = ~/.mutt/mailboxes
+header = "mailboxes "
+peritem = "+%(accountname)s/%(foldername)s"
+sep = " "
+footer = "\n"
+
diff --git a/.profile b/.profile
index 09bef4a..760945f 100644
--- a/.profile
+++ b/.profile
@@ -18,11 +18,15 @@ export QT4_IM_MODULE="fcitx"
###### PATH ######
# $HOME/bin
-export PATH=$HOME/bin:$PATH
+if [ -d "$HOME/bin" ]; then
+ export PATH="$HOME/bin:$PATH"
+fi
+# admin
+if `groups | grep -qE '\b(wheel|adm|sudo)\b'`; then
+ export PATH="$PATH:/usr/local/sbin:/usr/sbin:/sbin"
+fi
# TeXlive
export PATH=$PATH:/usr/local/texlive/bin/x86_64-linux
-# admin
-export PATH=$PATH:/usr/local/sbin:/usr/sbin:/sbin
###### gpg agent ######
eval "$(gpg-agent --daemon)"
diff --git a/.todo/config b/.todo/config
new file mode 100644
index 0000000..a60e513
--- /dev/null
+++ b/.todo/config
@@ -0,0 +1,95 @@
+###########################################################
+## todo.txt-cli configuration
+## https://github.com/ginatrapani/todo.txt-cli
+###########################################################
+
+# === EDIT FILE LOCATIONS BELOW ===
+
+# Your todo.txt directory
+#export TODO_DIR="/Users/gina/Documents/todo"
+#export TODO_DIR=$(dirname "$0")
+export TODO_DIR="$HOME/.todo"
+
+# Your todo/done/report.txt locations
+export TODO_FILE="$TODO_DIR/todo.txt"
+export DONE_FILE="$TODO_DIR/done.txt"
+export REPORT_FILE="$TODO_DIR/report.txt"
+
+# You can customize your actions directory location
+export TODO_ACTIONS_DIR="$HOME/.todo.actions.d"
+
+# == EDIT FILE LOCATIONS ABOVE ===
+
+# === COLOR MAP ===
+
+## Text coloring and formatting is done by inserting ANSI escape codes.
+## If you have re-mapped your color codes, or use the todo.txt
+## output in another output system (like Conky), you may need to
+## over-ride by uncommenting and editing these defaults.
+## If you change any of these here, you also need to uncomment
+## the defaults in the COLORS section below. Otherwise, todo.txt
+## will still use the defaults!
+
+export BLACK='\\033[0;30m'
+export RED='\\033[0;31m'
+export GREEN='\\033[0;32m'
+export BROWN='\\033[0;33m'
+export BLUE='\\033[0;34m'
+export PURPLE='\\033[0;35m'
+export CYAN='\\033[0;36m'
+export LIGHT_GREY='\\033[0;37m'
+export DARK_GREY='\\033[1;30m'
+export LIGHT_RED='\\033[1;31m'
+export LIGHT_GREEN='\\033[1;32m'
+export YELLOW='\\033[1;33m'
+export LIGHT_BLUE='\\033[1;34m'
+export LIGHT_PURPLE='\\033[1;35m'
+export LIGHT_CYAN='\\033[1;36m'
+export WHITE='\\033[1;37m'
+export DEFAULT='\\033[0m'
+
+# === COLORS ===
+
+## Uncomment and edit to override these defaults.
+## Reference the constants from the color map above,
+## or use $NONE to disable highlighting.
+#
+# Priorities can be any upper-case letter.
+# A,B,C are highlighted; you can add coloring for more.
+#
+export PRI_A=$YELLOW # color for A priority
+export PRI_B=$GREEN # color for B priority
+export PRI_C=$LIGHT_BLUE # color for C priority
+#export PRI_D=... # define your own
+export PRI_X=$WHITE # color unless explicitly defined
+
+# There is highlighting for tasks that have been done,
+# but haven't been archived yet.
+#
+export COLOR_DONE=$LIGHT_GREY
+
+# There is highlighting for projects and contexts.
+#
+export COLOR_PROJECT=$RED
+export COLOR_CONTEXT=$RED
+
+# === BEHAVIOR ===
+
+## customize list output
+#
+# TODOTXT_SORT_COMMAND will filter after line numbers are
+# inserted, but before colorization, and before hiding of
+# priority, context, and project.
+#
+#export TODOTXT_SORT_COMMAND='env LC_COLLATE=C sort -f -k2'
+#
+# Sort by priority, then by number
+export TODOTXT_SORT_COMMAND='env LC_COLLATE=C sort -k 2,2 -k 1,1n'
+
+# TODOTXT_FINAL_FILTER will filter list output after colorization,
+# priority hiding, context hiding, and project hiding. That is,
+# just before the list output is displayed.
+#
+# export TODOTXT_FINAL_FILTER='cat'
+
+# vim: set ts=8 sw=4 tw=0 fenc=utf-8 ft=sh: #
diff --git a/.todo/todo.sh b/.todo/todo.sh
new file mode 100755
index 0000000..fbd2725
--- /dev/null
+++ b/.todo/todo.sh
@@ -0,0 +1,1431 @@
+#! /usr/bin/env bash
+
+# === HEAVY LIFTING ===
+shopt -s extglob extquote
+
+# NOTE: Todo.sh requires the .todo/config configuration file to run.
+# Place the .todo/config file in your home directory or use the -d option for a custom location.
+
+[ -f VERSION-FILE ] && . VERSION-FILE || VERSION="2.10"
+version() {
+ cat <<-EndVersion
+ TODO.TXT Command Line Interface v$VERSION
+
+ First release: 5/11/2006
+ Original conception by: Gina Trapani (http://ginatrapani.org)
+ Contributors: http://github.com/ginatrapani/todo.txt-cli/network
+ License: GPL, http://www.gnu.org/copyleft/gpl.html
+ More information and mailing list at http://todotxt.com
+ Code repository: http://github.com/ginatrapani/todo.txt-cli/tree/master
+ EndVersion
+ exit 1
+}
+
+# Set script name and full path early.
+TODO_SH=$(basename "$0")
+TODO_FULL_SH="$0"
+export TODO_SH TODO_FULL_SH
+
+oneline_usage="$TODO_SH [-fhpantvV] [-d todo_config] action [task_number] [task_description]"
+
+usage()
+{
+ cat <<-EndUsage
+ Usage: $oneline_usage
+ Try '$TODO_SH -h' for more information.
+ EndUsage
+ exit 1
+}
+
+shorthelp()
+{
+ cat <<-EndHelp
+ Usage: $oneline_usage
+
+ Actions:
+ add|a "THING I NEED TO DO +project @context"
+ addm "THINGS I NEED TO DO
+ MORE THINGS I NEED TO DO"
+ addto DEST "TEXT TO ADD"
+ append|app ITEM# "TEXT TO APPEND"
+ archive
+ command [ACTIONS]
+ deduplicate
+ del|rm ITEM# [TERM]
+ depri|dp ITEM#[, ITEM#, ITEM#, ...]
+ do ITEM#[, ITEM#, ITEM#, ...]
+ help [ACTION...]
+ list|ls [TERM...]
+ listall|lsa [TERM...]
+ listaddons
+ listcon|lsc [TERM...]
+ listfile|lf [SRC [TERM...]]
+ listpri|lsp [PRIORITIES] [TERM...]
+ listproj|lsprj [TERM...]
+ move|mv ITEM# DEST [SRC]
+ prepend|prep ITEM# "TEXT TO PREPEND"
+ pri|p ITEM# PRIORITY
+ replace ITEM# "UPDATED TODO"
+ report
+ shorthelp
+
+ Actions can be added and overridden using scripts in the actions
+ directory.
+ EndHelp
+
+ # Only list the one-line usage from the add-on actions. This assumes that
+ # add-ons use the same usage indentation structure as todo.sh.
+ addonHelp | grep -e '^ Add-on Actions:' -e '^ [[:alpha:]]'
+
+ cat <<-EndHelpFooter
+
+ See "help" for more details.
+ EndHelpFooter
+}
+
+help()
+{
+ cat <<-EndOptionsHelp
+ Usage: $oneline_usage
+
+ Options:
+ -@
+ Hide context names in list output. Use twice to show context
+ names (default).
+ -+
+ Hide project names in list output. Use twice to show project
+ names (default).
+ -c
+ Color mode
+ -d CONFIG_FILE
+ Use a configuration file other than the default ~/.todo/config
+ -f
+ Forces actions without confirmation or interactive input
+ -h
+ Display a short help message; same as action "shorthelp"
+ -p
+ Plain mode turns off colors
+ -P
+ Hide priority labels in list output. Use twice to show
+ priority labels (default).
+ -a
+ Don't auto-archive tasks automatically on completion
+ -A
+ Auto-archive tasks automatically on completion
+ -n
+ Don't preserve line numbers; automatically remove blank lines
+ on task deletion
+ -N
+ Preserve line numbers
+ -t
+ Prepend the current date to a task automatically
+ when it's added.
+ -T
+ Do not prepend the current date to a task automatically
+ when it's added.
+ -v
+ Verbose mode turns on confirmation messages
+ -vv
+ Extra verbose mode prints some debugging information and
+ additional help text
+ -V
+ Displays version, license and credits
+ -x
+ Disables TODOTXT_FINAL_FILTER
+
+
+ EndOptionsHelp
+
+ [ $TODOTXT_VERBOSE -gt 1 ] && cat <<-'EndVerboseHelp'
+ Environment variables:
+ TODOTXT_AUTO_ARCHIVE is same as option -a (0)/-A (1)
+ TODOTXT_CFG_FILE=CONFIG_FILE is same as option -d CONFIG_FILE
+ TODOTXT_FORCE=1 is same as option -f
+ TODOTXT_PRESERVE_LINE_NUMBERS is same as option -n (0)/-N (1)
+ TODOTXT_PLAIN is same as option -p (1)/-c (0)
+ TODOTXT_DATE_ON_ADD is same as option -t (1)/-T (0)
+ TODOTXT_VERBOSE=1 is same as option -v
+ TODOTXT_DISABLE_FILTER=1 is same as option -x
+ TODOTXT_DEFAULT_ACTION="" run this when called with no arguments
+ TODOTXT_SORT_COMMAND="sort ..." customize list output
+ TODOTXT_FINAL_FILTER="sed ..." customize list after color, P@+ hiding
+ TODOTXT_SOURCEVAR=\$DONE_FILE use another source for listcon, listproj
+
+
+ EndVerboseHelp
+ actionsHelp
+ addonHelp
+}
+
+actionsHelp()
+{
+ cat <<-EndActionsHelp
+ Built-in Actions:
+ add "THING I NEED TO DO +project @context"
+ a "THING I NEED TO DO +project @context"
+ Adds THING I NEED TO DO to your todo.txt file on its own line.
+ Project and context notation optional.
+ Quotes optional.
+
+ addm "FIRST THING I NEED TO DO +project1 @context
+ SECOND THING I NEED TO DO +project2 @context"
+ Adds FIRST THING I NEED TO DO to your todo.txt on its own line and
+ Adds SECOND THING I NEED TO DO to you todo.txt on its own line.
+ Project and context notation optional.
+
+ addto DEST "TEXT TO ADD"
+ Adds a line of text to any file located in the todo.txt directory.
+ For example, addto inbox.txt "decide about vacation"
+
+ append ITEM# "TEXT TO APPEND"
+ app ITEM# "TEXT TO APPEND"
+ Adds TEXT TO APPEND to the end of the task on line ITEM#.
+ Quotes optional.
+
+ archive
+ Moves all done tasks from todo.txt to done.txt and removes blank lines.
+
+ command [ACTIONS]
+ Runs the remaining arguments using only todo.sh builtins.
+ Will not call any .todo.actions.d scripts.
+
+ deduplicate
+ Removes duplicate lines from todo.txt.
+
+ del ITEM# [TERM]
+ rm ITEM# [TERM]
+ Deletes the task on line ITEM# in todo.txt.
+ If TERM specified, deletes only TERM from the task.
+
+ depri ITEM#[, ITEM#, ITEM#, ...]
+ dp ITEM#[, ITEM#, ITEM#, ...]
+ Deprioritizes (removes the priority) from the task(s)
+ on line ITEM# in todo.txt.
+
+ do ITEM#[, ITEM#, ITEM#, ...]
+ Marks task(s) on line ITEM# as done in todo.txt.
+
+ help [ACTION...]
+ Display help about usage, options, built-in and add-on actions,
+ or just the usage help for the passed ACTION(s).
+
+ list [TERM...]
+ ls [TERM...]
+ Displays all tasks that contain TERM(s) sorted by priority with line
+ numbers. Each task must match all TERM(s) (logical AND); to display
+ tasks that contain any TERM (logical OR), use
+ "TERM1\|TERM2\|..." (with quotes), or TERM1\\\|TERM2 (unquoted).
+ Hides all tasks that contain TERM(s) preceded by a
+ minus sign (i.e. -TERM). If no TERM specified, lists entire todo.txt.
+
+ listall [TERM...]
+ lsa [TERM...]
+ Displays all the lines in todo.txt AND done.txt that contain TERM(s)
+ sorted by priority with line numbers. Hides all tasks that
+ contain TERM(s) preceded by a minus sign (i.e. -TERM). If no
+ TERM specified, lists entire todo.txt AND done.txt
+ concatenated and sorted.
+
+ listaddons
+ Lists all added and overridden actions in the actions directory.
+
+ listcon [TERM...]
+ lsc [TERM...]
+ Lists all the task contexts that start with the @ sign in todo.txt.
+ If TERM specified, considers only tasks that contain TERM(s).
+
+ listfile [SRC [TERM...]]
+ lf [SRC [TERM...]]
+ Displays all the lines in SRC file located in the todo.txt directory,
+ sorted by priority with line numbers. If TERM specified, lists
+ all lines that contain TERM(s) in SRC file. Hides all tasks that
+ contain TERM(s) preceded by a minus sign (i.e. -TERM).
+ Without any arguments, the names of all text files in the todo.txt
+ directory are listed.
+
+ listpri [PRIORITIES] [TERM...]
+ lsp [PRIORITIES] [TERM...]
+ Displays all tasks prioritized PRIORITIES.
+ PRIORITIES can be a single one (A) or a range (A-C).
+ If no PRIORITIES specified, lists all prioritized tasks.
+ If TERM specified, lists only prioritized tasks that contain TERM(s).
+ Hides all tasks that contain TERM(s) preceded by a minus sign
+ (i.e. -TERM).
+
+ listproj [TERM...]
+ lsprj [TERM...]
+ Lists all the projects (terms that start with a + sign) in
+ todo.txt.
+ If TERM specified, considers only tasks that contain TERM(s).
+
+ move ITEM# DEST [SRC]
+ mv ITEM# DEST [SRC]
+ Moves a line from source text file (SRC) to destination text file (DEST).
+ Both source and destination file must be located in the directory defined
+ in the configuration directory. When SRC is not defined
+ it's by default todo.txt.
+
+ prepend ITEM# "TEXT TO PREPEND"
+ prep ITEM# "TEXT TO PREPEND"
+ Adds TEXT TO PREPEND to the beginning of the task on line ITEM#.
+ Quotes optional.
+
+ pri ITEM# PRIORITY
+ p ITEM# PRIORITY
+ Adds PRIORITY to task on line ITEM#. If the task is already
+ prioritized, replaces current priority with new PRIORITY.
+ PRIORITY must be a letter between A and Z.
+
+ replace ITEM# "UPDATED TODO"
+ Replaces task on line ITEM# with UPDATED TODO.
+
+ report
+ Adds the number of open tasks and done tasks to report.txt.
+
+ shorthelp
+ List the one-line usage of all built-in and add-on actions.
+
+ EndActionsHelp
+}
+
+addonHelp()
+{
+ if [ -d "$TODO_ACTIONS_DIR" ]; then
+ didPrintAddonActionsHeader=
+ for action in "$TODO_ACTIONS_DIR"/*
+ do
+ if [ -f "$action" -a -x "$action" ]; then
+ if [ ! "$didPrintAddonActionsHeader" ]; then
+ cat <<-EndAddonActionsHeader
+ Add-on Actions:
+ EndAddonActionsHeader
+ didPrintAddonActionsHeader=1
+ fi
+ "$action" usage
+ elif [ -d "$action" -a -x "$action/$(basename $action)" ]; then
+ if [ ! "$didPrintAddonActionsHeader" ]; then
+ cat <<-EndAddonActionsHeader
+ Add-on Actions:
+ EndAddonActionsHeader
+ didPrintAddonActionsHeader=1
+ fi
+ "$action/$(basename $action)" usage
+ fi
+ done
+ fi
+}
+
+actionUsage()
+{
+ for actionName
+ do
+ action="${TODO_ACTIONS_DIR}/${actionName}"
+ if [ -f "$action" -a -x "$action" ]; then
+ "$action" usage
+ elif [ -d "$action" -a -x "$action/$(basename $action)" ]; then
+ "$action/$(basename $action)" usage
+ else
+ builtinActionUsage=$(actionsHelp | sed -n -e "/^ ${actionName//\//\\/} /,/^\$/p" -e "/^ ${actionName//\//\\/}$/,/^\$/p")
+ if [ "$builtinActionUsage" ]; then
+ echo "$builtinActionUsage"
+ echo
+ else
+ die "TODO: No action \"${actionName}\" exists."
+ fi
+ fi
+ done
+}
+
+dieWithHelp()
+{
+ case "$1" in
+ help) help;;
+ shorthelp) shorthelp;;
+ esac
+ shift
+
+ die "$@"
+}
+die()
+{
+ echo "$*"
+ exit 1
+}
+
+cleaninput()
+{
+ # Parameters: When $1 = "for sed", performs additional escaping for use
+ # in sed substitution with "|" separators.
+ # Precondition: $input contains text to be cleaned.
+ # Postcondition: Modifies $input.
+
+ # Replace CR and LF with space; tasks always comprise a single line.
+ input=${input//$'\r'/ }
+ input=${input//$'\n'/ }
+
+ if [ "$1" = "for sed" ]; then
+ # This action uses sed with "|" as the substitution separator, and & as
+ # the matched string; these must be escaped.
+ # Backslashes must be escaped, too, and before the other stuff.
+ input=${input//\\/\\\\}
+ input=${input//|/\\|}
+ input=${input//&/\\&}
+ fi
+}
+
+getPrefix()
+{
+ # Parameters: $1: todo file; empty means $TODO_FILE.
+ # Returns: Uppercase FILE prefix to be used in place of "TODO:" where
+ # a different todo file can be specified.
+ local base=$(basename "${1:-$TODO_FILE}")
+ echo "${base%%.[^.]*}" | tr 'a-z' 'A-Z'
+}
+
+getTodo()
+{
+ # Parameters: $1: task number
+ # $2: Optional todo file
+ # Precondition: $errmsg contains usage message.
+ # Postcondition: $todo contains task text.
+
+ local item=$1
+ [ -z "$item" ] && die "$errmsg"
+ [ "${item//[0-9]/}" ] && die "$errmsg"
+
+ todo=$(sed "$item!d" "${2:-$TODO_FILE}")
+ [ -z "$todo" ] && die "$(getPrefix "$2"): No task $item."
+}
+getNewtodo()
+{
+ # Parameters: $1: task number
+ # $2: Optional todo file
+ # Precondition: None.
+ # Postcondition: $newtodo contains task text.
+
+ local item=$1
+ [ -z "$item" ] && die 'Programming error: $item should exist.'
+ [ "${item//[0-9]/}" ] && die 'Programming error: $item should be numeric.'
+
+ newtodo=$(sed "$item!d" "${2:-$TODO_FILE}")
+ [ -z "$newtodo" ] && die "$(getPrefix "$2"): No updated task $item."
+}
+
+replaceOrPrepend()
+{
+ action=$1; shift
+ case "$action" in
+ replace)
+ backref=
+ querytext="Replacement: "
+ ;;
+ prepend)
+ backref=' &'
+ querytext="Prepend: "
+ ;;
+ esac
+ shift; item=$1; shift
+ getTodo "$item"
+
+ if [[ -z "$1" && $TODOTXT_FORCE = 0 ]]; then
+ echo -n "$querytext"
+ read input
+ else
+ input=$*
+ fi
+
+ # Retrieve existing priority and prepended date
+ local -r priAndDateExpr='^\((.) \)\{0,1\}\([0-9]\{2,4\}-[0-9]\{2\}-[0-9]\{2\} \)\{0,1\}'
+ priority=$(sed -e "$item!d" -e "${item}s/${priAndDateExpr}.*/\\1/" "$TODO_FILE")
+ prepdate=$(sed -e "$item!d" -e "${item}s/${priAndDateExpr}.*/\\2/" "$TODO_FILE")
+
+ if [ "$prepdate" -a "$action" = "replace" ] && [ "$(echo "$input"|sed -e "s/${priAndDateExpr}.*/\\1\\2/")" ]; then
+ # If the replaced text starts with a [priority +] date, it will replace
+ # the existing date, too.
+ prepdate=
+ fi
+
+ # Temporarily remove any existing priority and prepended date, perform the
+ # change (replace/prepend) and re-insert the existing priority and prepended
+ # date again.
+ cleaninput "for sed"
+ sed -i.bak -e "$item s/^${priority}${prepdate}//" -e "$item s|^.*|${priority}${prepdate}${input}${backref}|" "$TODO_FILE"
+ if [ $TODOTXT_VERBOSE -gt 0 ]; then
+ getNewtodo "$item"
+ case "$action" in
+ replace)
+ echo "$item $todo"
+ echo "TODO: Replaced task with:"
+ echo "$item $newtodo"
+ ;;
+ prepend)
+ echo "$item $newtodo"
+ ;;
+ esac
+ fi
+}
+
+#Preserving environment variables so they don't get clobbered by the config file
+OVR_TODOTXT_AUTO_ARCHIVE="$TODOTXT_AUTO_ARCHIVE"
+OVR_TODOTXT_FORCE="$TODOTXT_FORCE"
+OVR_TODOTXT_PRESERVE_LINE_NUMBERS="$TODOTXT_PRESERVE_LINE_NUMBERS"
+OVR_TODOTXT_PLAIN="$TODOTXT_PLAIN"
+OVR_TODOTXT_DATE_ON_ADD="$TODOTXT_DATE_ON_ADD"
+OVR_TODOTXT_DISABLE_FILTER="$TODOTXT_DISABLE_FILTER"
+OVR_TODOTXT_VERBOSE="$TODOTXT_VERBOSE"
+OVR_TODOTXT_DEFAULT_ACTION="$TODOTXT_DEFAULT_ACTION"
+OVR_TODOTXT_SORT_COMMAND="$TODOTXT_SORT_COMMAND"
+OVR_TODOTXT_FINAL_FILTER="$TODOTXT_FINAL_FILTER"
+
+# Prevent GREP_OPTIONS from malforming grep's output
+GREP_OPTIONS=""
+
+# == PROCESS OPTIONS ==
+while getopts ":fhpcnNaAtTvVx+@Pd:" Option
+do
+ case $Option in
+ '@' )
+ ## HIDE_CONTEXT_NAMES starts at zero (false); increment it to one
+ ## (true) the first time this flag is seen. Each time the flag
+ ## is seen after that, increment it again so that an even
+ ## number shows context names and an odd number hides context
+ ## names.
+ : $(( HIDE_CONTEXT_NAMES++ ))
+ if [ $(( $HIDE_CONTEXT_NAMES % 2 )) -eq 0 ]
+ then
+ ## Zero or even value -- show context names
+ unset HIDE_CONTEXTS_SUBSTITUTION
+ else
+ ## One or odd value -- hide context names
+ export HIDE_CONTEXTS_SUBSTITUTION='[[:space:]]@[[:graph:]]\{1,\}'
+ fi
+ ;;
+ '+' )
+ ## HIDE_PROJECT_NAMES starts at zero (false); increment it to one
+ ## (true) the first time this flag is seen. Each time the flag
+ ## is seen after that, increment it again so that an even
+ ## number shows project names and an odd number hides project
+ ## names.
+ : $(( HIDE_PROJECT_NAMES++ ))
+ if [ $(( $HIDE_PROJECT_NAMES % 2 )) -eq 0 ]
+ then
+ ## Zero or even value -- show project names
+ unset HIDE_PROJECTS_SUBSTITUTION
+ else
+ ## One or odd value -- hide project names
+ export HIDE_PROJECTS_SUBSTITUTION='[[:space:]][+][[:graph:]]\{1,\}'
+ fi
+ ;;
+ a )
+ OVR_TODOTXT_AUTO_ARCHIVE=0
+ ;;
+ A )
+ OVR_TODOTXT_AUTO_ARCHIVE=1
+ ;;
+ c )
+ OVR_TODOTXT_PLAIN=0
+ ;;
+ d )
+ TODOTXT_CFG_FILE=$OPTARG
+ ;;
+ f )
+ OVR_TODOTXT_FORCE=1
+ ;;
+ h )
+ # Short-circuit option parsing and forward to the action.
+ # Cannot just invoke shorthelp() because we need the configuration
+ # processed to locate the add-on actions directory.
+ set -- '-h' 'shorthelp'
+ OPTIND=2
+ ;;
+ n )
+ OVR_TODOTXT_PRESERVE_LINE_NUMBERS=0
+ ;;
+ N )
+ OVR_TODOTXT_PRESERVE_LINE_NUMBERS=1
+ ;;
+ p )
+ OVR_TODOTXT_PLAIN=1
+ ;;
+ P )
+ ## HIDE_PRIORITY_LABELS starts at zero (false); increment it to one
+ ## (true) the first time this flag is seen. Each time the flag
+ ## is seen after that, increment it again so that an even
+ ## number shows priority labels and an odd number hides priority
+ ## labels.
+ : $(( HIDE_PRIORITY_LABELS++ ))
+ if [ $(( $HIDE_PRIORITY_LABELS % 2 )) -eq 0 ]
+ then
+ ## Zero or even value -- show priority labels
+ unset HIDE_PRIORITY_SUBSTITUTION
+ else
+ ## One or odd value -- hide priority labels
+ export HIDE_PRIORITY_SUBSTITUTION="([A-Z])[[:space:]]"
+ fi
+ ;;
+ t )
+ OVR_TODOTXT_DATE_ON_ADD=1
+ ;;
+ T )
+ OVR_TODOTXT_DATE_ON_ADD=0
+ ;;
+ v )
+ : $(( TODOTXT_VERBOSE++ ))
+ ;;
+ V )
+ version
+ ;;
+ x )
+ OVR_TODOTXT_DISABLE_FILTER=1
+ ;;
+ esac
+done
+shift $(($OPTIND - 1))
+
+# defaults if not yet defined
+TODOTXT_VERBOSE=${TODOTXT_VERBOSE:-1}
+TODOTXT_PLAIN=${TODOTXT_PLAIN:-0}
+TODOTXT_CFG_FILE=${TODOTXT_CFG_FILE:-$HOME/.todo/config}
+TODOTXT_FORCE=${TODOTXT_FORCE:-0}
+TODOTXT_PRESERVE_LINE_NUMBERS=${TODOTXT_PRESERVE_LINE_NUMBERS:-1}
+TODOTXT_AUTO_ARCHIVE=${TODOTXT_AUTO_ARCHIVE:-1}
+TODOTXT_DATE_ON_ADD=${TODOTXT_DATE_ON_ADD:-0}
+TODOTXT_DEFAULT_ACTION=${TODOTXT_DEFAULT_ACTION:-}
+TODOTXT_SORT_COMMAND=${TODOTXT_SORT_COMMAND:-env LC_COLLATE=C sort -f -k2}
+TODOTXT_DISABLE_FILTER=${TODOTXT_DISABLE_FILTER:-}
+TODOTXT_FINAL_FILTER=${TODOTXT_FINAL_FILTER:-cat}
+TODOTXT_GLOBAL_CFG_FILE=${TODOTXT_GLOBAL_CFG_FILE:-/etc/todo/config}
+
+# Export all TODOTXT_* variables
+export ${!TODOTXT_@}
+
+# Default color map
+export NONE=''
+export BLACK='\\033[0;30m'
+export RED='\\033[0;31m'
+export GREEN='\\033[0;32m'
+export BROWN='\\033[0;33m'
+export BLUE='\\033[0;34m'
+export PURPLE='\\033[0;35m'
+export CYAN='\\033[0;36m'
+export LIGHT_GREY='\\033[0;37m'
+export DARK_GREY='\\033[1;30m'
+export LIGHT_RED='\\033[1;31m'
+export LIGHT_GREEN='\\033[1;32m'
+export YELLOW='\\033[1;33m'
+export LIGHT_BLUE='\\033[1;34m'
+export LIGHT_PURPLE='\\033[1;35m'
+export LIGHT_CYAN='\\033[1;36m'
+export WHITE='\\033[1;37m'
+export DEFAULT='\\033[0m'
+
+# Default priority->color map.
+export PRI_A=$YELLOW # color for A priority
+export PRI_B=$GREEN # color for B priority
+export PRI_C=$LIGHT_BLUE # color for C priority
+export PRI_X=$WHITE # color unless explicitly defined
+
+# Default project and context colors.
+export COLOR_PROJECT=$NONE
+export COLOR_CONTEXT=$NONE
+
+# Default highlight colors.
+export COLOR_DONE=$LIGHT_GREY # color for done (but not yet archived) tasks
+
+# Default sentence delimiters for todo.sh append.
+# If the text to be appended to the task begins with one of these characters, no
+# whitespace is inserted in between. This makes appending to an enumeration
+# (todo.sh add 42 ", foo") syntactically correct.
+export SENTENCE_DELIMITERS=',.:;'
+
+[ -e "$TODOTXT_CFG_FILE" ] || {
+ CFG_FILE_ALT="$HOME/todo.cfg"
+
+ if [ -e "$CFG_FILE_ALT" ]
+ then
+ TODOTXT_CFG_FILE="$CFG_FILE_ALT"
+ fi
+}
+
+[ -e "$TODOTXT_CFG_FILE" ] || {
+ CFG_FILE_ALT="$HOME/.todo.cfg"
+
+ if [ -e "$CFG_FILE_ALT" ]
+ then
+ TODOTXT_CFG_FILE="$CFG_FILE_ALT"
+ fi
+}
+
+[ -e "$TODOTXT_CFG_FILE" ] || {
+ CFG_FILE_ALT=$(dirname "$0")"/todo.cfg"
+
+ if [ -e "$CFG_FILE_ALT" ]
+ then
+ TODOTXT_CFG_FILE="$CFG_FILE_ALT"
+ fi
+}
+
+[ -e "$TODOTXT_CFG_FILE" ] || {
+ CFG_FILE_ALT="$TODOTXT_GLOBAL_CFG_FILE"
+
+ if [ -e "$CFG_FILE_ALT" ]
+ then
+ TODOTXT_CFG_FILE="$CFG_FILE_ALT"
+ fi
+}
+
+
+if [ -z "$TODO_ACTIONS_DIR" -o ! -d "$TODO_ACTIONS_DIR" ]
+then
+ TODO_ACTIONS_DIR="$HOME/.todo/actions"
+ export TODO_ACTIONS_DIR
+fi
+
+[ -d "$TODO_ACTIONS_DIR" ] || {
+ TODO_ACTIONS_DIR_ALT="$HOME/.todo.actions.d"
+
+ if [ -d "$TODO_ACTIONS_DIR_ALT" ]
+ then
+ TODO_ACTIONS_DIR="$TODO_ACTIONS_DIR_ALT"
+ fi
+}
+
+# === SANITY CHECKS (thanks Karl!) ===
+[ -r "$TODOTXT_CFG_FILE" ] || dieWithHelp "$1" "Fatal Error: Cannot read configuration file $TODOTXT_CFG_FILE"
+
+. "$TODOTXT_CFG_FILE"
+
+# === APPLY OVERRIDES
+if [ -n "$OVR_TODOTXT_AUTO_ARCHIVE" ] ; then
+ TODOTXT_AUTO_ARCHIVE="$OVR_TODOTXT_AUTO_ARCHIVE"
+fi
+if [ -n "$OVR_TODOTXT_FORCE" ] ; then
+ TODOTXT_FORCE="$OVR_TODOTXT_FORCE"
+fi
+if [ -n "$OVR_TODOTXT_PRESERVE_LINE_NUMBERS" ] ; then
+ TODOTXT_PRESERVE_LINE_NUMBERS="$OVR_TODOTXT_PRESERVE_LINE_NUMBERS"
+fi
+if [ -n "$OVR_TODOTXT_PLAIN" ] ; then
+ TODOTXT_PLAIN="$OVR_TODOTXT_PLAIN"
+fi
+if [ -n "$OVR_TODOTXT_DATE_ON_ADD" ] ; then
+ TODOTXT_DATE_ON_ADD="$OVR_TODOTXT_DATE_ON_ADD"
+fi
+if [ -n "$OVR_TODOTXT_DISABLE_FILTER" ] ; then
+ TODOTXT_DISABLE_FILTER="$OVR_TODOTXT_DISABLE_FILTER"
+fi
+if [ -n "$OVR_TODOTXT_VERBOSE" ] ; then
+ TODOTXT_VERBOSE="$OVR_TODOTXT_VERBOSE"
+fi
+if [ -n "$OVR_TODOTXT_DEFAULT_ACTION" ] ; then
+ TODOTXT_DEFAULT_ACTION="$OVR_TODOTXT_DEFAULT_ACTION"
+fi
+if [ -n "$OVR_TODOTXT_SORT_COMMAND" ] ; then
+ TODOTXT_SORT_COMMAND="$OVR_TODOTXT_SORT_COMMAND"
+fi
+if [ -n "$OVR_TODOTXT_FINAL_FILTER" ] ; then
+ TODOTXT_FINAL_FILTER="$OVR_TODOTXT_FINAL_FILTER"
+fi
+
+ACTION=${1:-$TODOTXT_DEFAULT_ACTION}
+
+[ -z "$ACTION" ] && usage
+[ -d "$TODO_DIR" ] || mkdir -p $TODO_DIR 2> /dev/null || dieWithHelp "$1" "Fatal Error: $TODO_DIR is not a directory"
+( cd "$TODO_DIR" ) || dieWithHelp "$1" "Fatal Error: Unable to cd to $TODO_DIR"
+
+[ -f "$TODO_FILE" -o -c "$TODO_FILE" ] || > "$TODO_FILE"
+[ -f "$DONE_FILE" -o -c "$DONE_FILE" ] || > "$DONE_FILE"
+[ -f "$REPORT_FILE" -o -c "$REPORT_FILE" ] || > "$REPORT_FILE"
+
+if [ $TODOTXT_PLAIN = 1 ]; then
+ for clr in ${!PRI_@}; do
+ export $clr=$NONE
+ done
+ PRI_X=$NONE
+ DEFAULT=$NONE
+ COLOR_DONE=$NONE
+ COLOR_PROJECT=$NONE
+ COLOR_CONTEXT=$NONE
+fi
+
+[[ "$HIDE_PROJECTS_SUBSTITUTION" ]] && COLOR_PROJECT="$NONE"
+[[ "$HIDE_CONTEXTS_SUBSTITUTION" ]] && COLOR_CONTEXT="$NONE"
+
+_addto() {
+ file="$1"
+ input="$2"
+ cleaninput
+
+ if [[ $TODOTXT_DATE_ON_ADD = 1 ]]; then
+ now=$(date '+%Y-%m-%d')
+ input=$(echo "$input" | sed -e 's/^\(([A-Z]) \)\{0,1\}/\1'"$now /")
+ fi
+ echo "$input" >> "$file"
+ if [ $TODOTXT_VERBOSE -gt 0 ]; then
+ TASKNUM=$(sed -n '$ =' "$file")
+ echo "$TASKNUM $input"
+ echo "$(getPrefix "$file"): $TASKNUM added."
+ fi
+}
+
+shellquote()
+{
+ typeset -r qq=\'; printf %s\\n "'${1//\'/${qq}\\${qq}${qq}}'";
+}
+
+filtercommand()
+{
+ filter=${1:-}
+ shift
+ post_filter=${1:-}
+ shift
+
+ for search_term
+ do
+ ## See if the first character of $search_term is a dash
+ if [ "${search_term:0:1}" != '-' ]
+ then
+ ## First character isn't a dash: hide lines that don't match
+ ## this $search_term
+ filter="${filter:-}${filter:+ | }grep -i $(shellquote "$search_term")"
+ else
+ ## First character is a dash: hide lines that match this
+ ## $search_term
+ #
+ ## Remove the first character (-) before adding to our filter command
+ filter="${filter:-}${filter:+ | }grep -v -i $(shellquote "${search_term:1}")"
+ fi
+ done
+
+ [ -n "$post_filter" ] && {
+ filter="${filter:-}${filter:+ | }${post_filter:-}"
+ }
+
+ printf %s "$filter"
+}
+
+_list() {
+ local FILE="$1"
+ ## If the file starts with a "/" use absolute path. Otherwise,
+ ## try to find it in either $TODO_DIR or using a relative path
+ if [ "${1:0:1}" == / ]; then
+ ## Absolute path
+ src="$FILE"
+ elif [ -f "$TODO_DIR/$FILE" ]; then
+ ## Path relative to todo.sh directory
+ src="$TODO_DIR/$FILE"
+ elif [ -f "$FILE" ]; then
+ ## Path relative to current working directory
+ src="$FILE"
+ elif [ -f "$TODO_DIR/${FILE}.txt" ]; then
+ ## Path relative to todo.sh directory, missing file extension
+ src="$TODO_DIR/${FILE}.txt"
+ else
+ die "TODO: File $FILE does not exist."
+ fi
+
+ ## Get our search arguments, if any
+ shift ## was file name, new $1 is first search term
+
+ _format "$src" '' "$@"
+
+ if [ $TODOTXT_VERBOSE -gt 0 ]; then
+ echo "--"
+ echo "$(getPrefix "$src"): ${NUMTASKS:-0} of ${TOTALTASKS:-0} tasks shown"
+ fi
+}
+getPadding()
+{
+ ## We need one level of padding for each power of 10 $LINES uses.
+ LINES=$(sed -n '$ =' "${1:-$TODO_FILE}")
+ printf %s ${#LINES}
+}
+_format()
+{
+ # Parameters: $1: todo input file; when empty formats stdin
+ # $2: ITEM# number width; if empty auto-detects from $1 / $TODO_FILE.
+ # Precondition: None
+ # Postcondition: $NUMTASKS and $TOTALTASKS contain statistics (unless $TODOTXT_VERBOSE=0).
+
+ FILE=$1
+ shift
+
+ ## Figure out how much padding we need to use, unless this was passed to us.
+ PADDING=${1:-$(getPadding "$FILE")}
+ shift
+
+ ## Number the file, then run the filter command,
+ ## then sort and mangle output some more
+ if [[ $TODOTXT_DISABLE_FILTER = 1 ]]; then
+ TODOTXT_FINAL_FILTER="cat"
+ fi
+ items=$(
+ if [ "$FILE" ]; then
+ sed = "$FILE"
+ else
+ sed =
+ fi \
+ | sed -e '''
+ N
+ s/^/ /
+ s/ *\([ 0-9]\{'"$PADDING"',\}\)\n/\1 /
+ /^[ 0-9]\{1,\} *$/d
+ '''
+ )
+
+ ## Build and apply the filter.
+ filter_command=$(filtercommand "${pre_filter_command:-}" "${post_filter_command:-}" "$@")
+ if [ "${filter_command}" ]; then
+ filtered_items=$(echo -n "$items" | eval "${filter_command}")
+ else
+ filtered_items=$items
+ fi
+ filtered_items=$(
+ echo -n "$filtered_items" \
+ | sed '''
+ s/^ /00000/;
+ s/^ /0000/;
+ s/^ /000/;
+ s/^ /00/;
+ s/^ /0/;
+ ''' \
+ | eval ${TODOTXT_SORT_COMMAND} \
+ | awk '''
+ function highlight(colorVar, color) {
+ color = ENVIRON[colorVar]
+ gsub(/\\+033/, "\033", color)
+ return color
+ }
+ {
+ clr = ""
+ if (match($0, /^[0-9]+ x /)) {
+ clr = highlight("COLOR_DONE")
+ } else if (match($0, /^[0-9]+ \([A-Z]\) /)) {
+ clr = highlight("PRI_" substr($0, RSTART + RLENGTH - 3, 1))
+ clr = (clr ? clr : highlight("PRI_X"))
+ if (ENVIRON["HIDE_PRIORITY_SUBSTITUTION"] != "") {
+ $0 = substr($0, 1, RLENGTH - 4) substr($0, RSTART + RLENGTH)
+ }
+ }
+ end_clr = (clr ? highlight("DEFAULT") : "")
+
+ prj_beg = highlight("COLOR_PROJECT")
+ prj_end = (prj_beg ? (highlight("DEFAULT") clr) : "")
+
+ ctx_beg = highlight("COLOR_CONTEXT")
+ ctx_end = (ctx_beg ? (highlight("DEFAULT") clr) : "")
+
+ gsub(/[ \t][ \t]*/, "\n&\n")
+ len = split($0, words, /\n/)
+
+ printf "%s", clr
+ for (i = 1; i <= len; ++i) {
+ if (words[i] ~ /^[+].*[A-Za-z0-9_]$/) {
+ printf "%s", prj_beg words[i] prj_end
+ } else if (words[i] ~ /^[@].*[A-Za-z0-9_]$/) {
+ printf "%s", ctx_beg words[i] ctx_end
+ } else {
+ printf "%s", words[i]
+ }
+ }
+ printf "%s\n", end_clr
+ }
+ ''' \
+ | sed '''
+ s/'"${HIDE_PROJECTS_SUBSTITUTION:-^}"'//g
+ s/'"${HIDE_CONTEXTS_SUBSTITUTION:-^}"'//g
+ s/'"${HIDE_CUSTOM_SUBSTITUTION:-^}"'//g
+ ''' \
+ | eval ${TODOTXT_FINAL_FILTER} \
+ )
+ [ "$filtered_items" ] && echo "$filtered_items"
+
+ if [ $TODOTXT_VERBOSE -gt 0 ]; then
+ NUMTASKS=$( echo -n "$filtered_items" | sed -n '$ =' )
+ TOTALTASKS=$( echo -n "$items" | sed -n '$ =' )
+ fi
+ if [ $TODOTXT_VERBOSE -gt 1 ]; then
+ echo "TODO DEBUG: Filter Command was: ${filter_command:-cat}"
+ fi
+}
+
+listWordsWithSigil()
+{
+ sigil=$1
+ shift
+
+ FILE=$TODO_FILE
+ [ "$TODOTXT_SOURCEVAR" ] && eval "FILE=$TODOTXT_SOURCEVAR"
+ eval "$(filtercommand 'cat "${FILE[@]}"' '' "$@")" | grep -o "[^ ]*${sigil}[^ ]\\+" | grep "^$sigil" | sort -u
+}
+
+export -f cleaninput getPrefix getTodo getNewtodo shellquote filtercommand _list listWordsWithSigil getPadding _format die
+
+# == HANDLE ACTION ==
+action=$( printf "%s\n" "$ACTION" | tr 'A-Z' 'a-z' )
+
+## If the first argument is "command", run the rest of the arguments
+## using todo.sh builtins.
+## Else, run a actions script with the name of the command if it exists
+## or fallback to using a builtin
+if [ "$action" == command ]
+then
+ ## Get rid of "command" from arguments list
+ shift
+ ## Reset action to new first argument
+ action=$( printf "%s\n" "$1" | tr 'A-Z' 'a-z' )
+elif [ -d "$TODO_ACTIONS_DIR/$action" -a -x "$TODO_ACTIONS_DIR/$action/$action" ]
+then
+ "$TODO_ACTIONS_DIR/$action/$action" "$@"
+ exit $?
+elif [ -d "$TODO_ACTIONS_DIR" -a -x "$TODO_ACTIONS_DIR/$action" ]
+then
+ "$TODO_ACTIONS_DIR/$action" "$@"
+ exit $?
+fi
+
+## Only run if $action isn't found in .todo.actions.d
+case $action in
+"add" | "a")
+ if [[ -z "$2" && $TODOTXT_FORCE = 0 ]]; then
+ echo -n "Add: "
+ read input
+ else
+ [ -z "$2" ] && die "usage: $TODO_SH add \"TODO ITEM\""
+ shift
+ input=$*
+ fi
+ _addto "$TODO_FILE" "$input"
+ ;;
+
+"addm")
+ if [[ -z "$2" && $TODOTXT_FORCE = 0 ]]; then
+ echo -n "Add: "
+ read input
+ else
+ [ -z "$2" ] && die "usage: $TODO_SH addm \"TODO ITEM\""
+ shift
+ input=$*
+ fi
+
+ # Set Internal Field Seperator as newline so we can
+ # loop across multiple lines
+ SAVEIFS=$IFS
+ IFS=$'\n'
+
+ # Treat each line seperately
+ for line in $input ; do
+ _addto "$TODO_FILE" "$line"
+ done
+ IFS=$SAVEIFS
+ ;;
+
+"addto" )
+ [ -z "$2" ] && die "usage: $TODO_SH addto DEST \"TODO ITEM\""
+ dest="$TODO_DIR/$2"
+ [ -z "$3" ] && die "usage: $TODO_SH addto DEST \"TODO ITEM\""
+ shift
+ shift
+ input=$*
+
+ if [ -f "$dest" ]; then
+ _addto "$dest" "$input"
+ else
+ die "TODO: Destination file $dest does not exist."
+ fi
+ ;;
+
+"append" | "app" )
+ errmsg="usage: $TODO_SH append ITEM# \"TEXT TO APPEND\""
+ shift; item=$1; shift
+ getTodo "$item"
+
+ if [[ -z "$1" && $TODOTXT_FORCE = 0 ]]; then
+ echo -n "Append: "
+ read input
+ else
+ input=$*
+ fi
+ case "$input" in
+ [$SENTENCE_DELIMITERS]*) appendspace=;;
+ *) appendspace=" ";;
+ esac
+ cleaninput "for sed"
+
+ if sed -i.bak $item" s|^.*|&${appendspace}${input}|" "$TODO_FILE"; then
+ if [ $TODOTXT_VERBOSE -gt 0 ]; then
+ getNewtodo "$item"
+ echo "$item $newtodo"
+ fi
+ else
+ die "TODO: Error appending task $item."
+ fi
+ ;;
+
+"archive" )
+ # defragment blank lines
+ sed -i.bak -e '/./!d' "$TODO_FILE"
+ [ $TODOTXT_VERBOSE -gt 0 ] && grep "^x " "$TODO_FILE"
+ grep "^x " "$TODO_FILE" >> "$DONE_FILE"
+ sed -i.bak '/^x /d' "$TODO_FILE"
+ if [ $TODOTXT_VERBOSE -gt 0 ]; then
+ echo "TODO: $TODO_FILE archived."
+ fi
+ ;;
+
+"del" | "rm" )
+ # replace deleted line with a blank line when TODOTXT_PRESERVE_LINE_NUMBERS is 1
+ errmsg="usage: $TODO_SH del ITEM# [TERM]"
+ item=$2
+ getTodo "$item"
+
+ if [ -z "$3" ]; then
+ if [ $TODOTXT_FORCE = 0 ]; then
+ echo "Delete '$todo'? (y/n)"
+ read ANSWER
+ else
+ ANSWER="y"
+ fi
+ if [ "$ANSWER" = "y" ]; then
+ if [ $TODOTXT_PRESERVE_LINE_NUMBERS = 0 ]; then
+ # delete line (changes line numbers)
+ sed -i.bak -e $item"s/^.*//" -e '/./!d' "$TODO_FILE"
+ else
+ # leave blank line behind (preserves line numbers)
+ sed -i.bak -e $item"s/^.*//" "$TODO_FILE"
+ fi
+ if [ $TODOTXT_VERBOSE -gt 0 ]; then
+ echo "$item $todo"
+ echo "TODO: $item deleted."
+ fi
+ else
+ echo "TODO: No tasks were deleted."
+ fi
+ else
+ sed -i.bak \
+ -e $item"s/^\((.) \)\{0,1\} *$3 */\1/g" \
+ -e $item"s/ *$3 *\$//g" \
+ -e $item"s/ *$3 */ /g" \
+ -e $item"s/ *$3 */ /g" \
+ -e $item"s/$3//g" \
+ "$TODO_FILE"
+ getNewtodo "$item"
+ if [ "$todo" = "$newtodo" ]; then
+ [ $TODOTXT_VERBOSE -gt 0 ] && echo "$item $todo"
+ die "TODO: '$3' not found; no removal done."
+ fi
+ if [ $TODOTXT_VERBOSE -gt 0 ]; then
+ echo "$item $todo"
+ echo "TODO: Removed '$3' from task."
+ echo "$item $newtodo"
+ fi
+ fi
+ ;;
+
+"depri" | "dp" )
+ errmsg="usage: $TODO_SH depri ITEM#[, ITEM#, ITEM#, ...]"
+ shift;
+ [ $# -eq 0 ] && die "$errmsg"
+
+ # Split multiple depri's, if comma separated change to whitespace separated
+ # Loop the 'depri' function for each item
+ for item in ${*//,/ }; do
+ getTodo "$item"
+
+ if [[ "$todo" = \(?\)\ * ]]; then
+ sed -i.bak -e $item"s/^(.) //" "$TODO_FILE"
+ if [ $TODOTXT_VERBOSE -gt 0 ]; then
+ getNewtodo "$item"
+ echo "$item $newtodo"
+ echo "TODO: $item deprioritized."
+ fi
+ else
+ echo "TODO: $item is not prioritized."
+ fi
+ done
+ ;;
+
+"do" )
+ errmsg="usage: $TODO_SH do ITEM#[, ITEM#, ITEM#, ...]"
+ # shift so we get arguments to the do request
+ shift;
+ [ "$#" -eq 0 ] && die "$errmsg"
+
+ # Split multiple do's, if comma separated change to whitespace separated
+ # Loop the 'do' function for each item
+ for item in ${*//,/ }; do
+ getTodo "$item"
+
+ # Check if this item has already been done
+ if [ "${todo:0:2}" != "x " ]; then
+ now=$(date '+%Y-%m-%d')
+ # remove priority once item is done
+ sed -i.bak $item"s/^(.) //" "$TODO_FILE"
+ sed -i.bak $item"s|^|x $now |" "$TODO_FILE"
+ if [ $TODOTXT_VERBOSE -gt 0 ]; then
+ getNewtodo "$item"
+ echo "$item $newtodo"
+ echo "TODO: $item marked as done."
+ fi
+ else
+ echo "TODO: $item is already marked done."
+ fi
+ done
+
+ if [ $TODOTXT_AUTO_ARCHIVE = 1 ]; then
+ # Recursively invoke the script to allow overriding of the archive
+ # action.
+ "$TODO_FULL_SH" archive
+ fi
+ ;;
+
+"help" )
+ shift ## Was help; new $1 is first help topic / action name
+ if [ $# -gt 0 ]; then
+ # Don't use PAGER here; we don't expect much usage output from one / few actions.
+ actionUsage "$@"
+ else
+ if [ -t 1 ] ; then # STDOUT is a TTY
+ if which "${PAGER:-less}" >/dev/null 2>&1; then
+ # we have a working PAGER (or less as a default)
+ help | "${PAGER:-less}" && exit 0
+ fi
+ fi
+ help # just in case something failed above, we go ahead and just spew to STDOUT
+ fi
+ ;;
+
+"shorthelp" )
+ if [ -t 1 ] ; then # STDOUT is a TTY
+ if which "${PAGER:-less}" >/dev/null 2>&1; then
+ # we have a working PAGER (or less as a default)
+ shorthelp | "${PAGER:-less}" && exit 0
+ fi
+ fi
+ shorthelp # just in case something failed above, we go ahead and just spew to STDOUT
+ ;;
+
+"list" | "ls" )
+ shift ## Was ls; new $1 is first search term
+ _list "$TODO_FILE" "$@"
+ ;;
+
+"listall" | "lsa" )
+ shift ## Was lsa; new $1 is first search term
+
+ TOTAL=$( sed -n '$ =' "$TODO_FILE" )
+ PADDING=${#TOTAL}
+
+ post_filter_command="${post_filter_command:-}${post_filter_command:+ | }awk -v TOTAL=$TOTAL -v PADDING=$PADDING '{ \$1 = sprintf(\"%\" PADDING \"d\", (\$1 > TOTAL ? 0 : \$1)); print }' "
+ cat "$TODO_FILE" "$DONE_FILE" | TODOTXT_VERBOSE=0 _format '' "$PADDING" "$@"
+
+ if [ $TODOTXT_VERBOSE -gt 0 ]; then
+ TDONE=$( sed -n '$ =' "$DONE_FILE" )
+ TASKNUM=$(TODOTXT_PLAIN=1 TODOTXT_VERBOSE=0 _format "$TODO_FILE" 1 "$@" | sed -n '$ =')
+ DONENUM=$(TODOTXT_PLAIN=1 TODOTXT_VERBOSE=0 _format "$DONE_FILE" 1 "$@" | sed -n '$ =')
+ echo "--"
+ echo "$(getPrefix "$TODO_FILE"): ${TASKNUM:-0} of ${TOTAL:-0} tasks shown"
+ echo "$(getPrefix "$DONE_FILE"): ${DONENUM:-0} of ${TDONE:-0} tasks shown"
+ echo "total $((TASKNUM + DONENUM)) of $((TOTAL + TDONE)) tasks shown"
+ fi
+ ;;
+
+"listfile" | "lf" )
+ shift ## Was listfile, next $1 is file name
+ if [ $# -eq 0 ]; then
+ [ $TODOTXT_VERBOSE -gt 0 ] && echo "Files in the todo.txt directory:"
+ cd "$TODO_DIR" && ls -1 *.txt
+ else
+ FILE="$1"
+ shift ## Was filename; next $1 is first search term
+
+ _list "$FILE" "$@"
+ fi
+ ;;
+
+"listcon" | "lsc" )
+ shift
+ listWordsWithSigil '@' "$@"
+ ;;
+
+"listproj" | "lsprj" )
+ shift
+ listWordsWithSigil '+' "$@"
+ ;;
+
+"listpri" | "lsp" )
+ shift ## was "listpri", new $1 is priority to list or first TERM
+
+ pri=$(printf "%s\n" "$1" | tr 'a-z' 'A-Z' | grep -e '^[A-Z]$' -e '^[A-Z]-[A-Z]$') && shift || pri="A-Z"
+ post_filter_command="${post_filter_command:-}${post_filter_command:+ | }grep '^ *[0-9]\+ ([${pri}]) '"
+ _list "$TODO_FILE" "$@"
+ ;;
+
+"move" | "mv" )
+ # replace moved line with a blank line when TODOTXT_PRESERVE_LINE_NUMBERS is 1
+ errmsg="usage: $TODO_SH mv ITEM# DEST [SRC]"
+ item=$2
+ dest="$TODO_DIR/$3"
+ src="$TODO_DIR/$4"
+
+ [ -z "$4" ] && src="$TODO_FILE"
+ [ -z "$dest" ] && die "$errmsg"
+
+ [ -f "$src" ] || die "TODO: Source file $src does not exist."
+ [ -f "$dest" ] || die "TODO: Destination file $dest does not exist."
+
+ getTodo "$item" "$src"
+ [ -z "$todo" ] && die "$item: No such item in $src."
+ if [ $TODOTXT_FORCE = 0 ]; then
+ echo "Move '$todo' from $src to $dest? (y/n)"
+ read ANSWER
+ else
+ ANSWER="y"
+ fi
+ if [ "$ANSWER" = "y" ]; then
+ if [ $TODOTXT_PRESERVE_LINE_NUMBERS = 0 ]; then
+ # delete line (changes line numbers)
+ sed -i.bak -e $item"s/^.*//" -e '/./!d' "$src"
+ else
+ # leave blank line behind (preserves line numbers)
+ sed -i.bak -e $item"s/^.*//" "$src"
+ fi
+ echo "$todo" >> "$dest"
+
+ if [ $TODOTXT_VERBOSE -gt 0 ]; then
+ echo "$item $todo"
+ echo "TODO: $item moved from '$src' to '$dest'."
+ fi
+ else
+ echo "TODO: No tasks moved."
+ fi
+ ;;
+
+"prepend" | "prep" )
+ errmsg="usage: $TODO_SH prepend ITEM# \"TEXT TO PREPEND\""
+ replaceOrPrepend 'prepend' "$@"
+ ;;
+
+"pri" | "p" )
+ item=$2
+ newpri=$( printf "%s\n" "$3" | tr 'a-z' 'A-Z' )
+
+ errmsg="usage: $TODO_SH pri ITEM# PRIORITY
+note: PRIORITY must be anywhere from A to Z."
+
+ [ "$#" -ne 3 ] && die "$errmsg"
+ [[ "$newpri" = @([A-Z]) ]] || die "$errmsg"
+ getTodo "$item"
+
+ oldpri=
+ if [[ "$todo" = \(?\)\ * ]]; then
+ oldpri=${todo:1:1}
+ fi
+
+ if [ "$oldpri" != "$newpri" ]; then
+ sed -i.bak -e $item"s/^(.) //" -e $item"s/^/($newpri) /" "$TODO_FILE"
+ fi
+ if [ $TODOTXT_VERBOSE -gt 0 ]; then
+ getNewtodo "$item"
+ echo "$item $newtodo"
+ if [ "$oldpri" != "$newpri" ]; then
+ if [ "$oldpri" ]; then
+ echo "TODO: $item re-prioritized from ($oldpri) to ($newpri)."
+ else
+ echo "TODO: $item prioritized ($newpri)."
+ fi
+ fi
+ fi
+ if [ "$oldpri" = "$newpri" ]; then
+ echo "TODO: $item already prioritized ($newpri)."
+ fi
+ ;;
+
+"replace" )
+ errmsg="usage: $TODO_SH replace ITEM# \"UPDATED ITEM\""
+ replaceOrPrepend 'replace' "$@"
+ ;;
+
+"report" )
+ # archive first
+ # Recursively invoke the script to allow overriding of the archive
+ # action.
+ "$TODO_FULL_SH" archive
+
+ TOTAL=$( sed -n '$ =' "$TODO_FILE" )
+ TDONE=$( sed -n '$ =' "$DONE_FILE" )
+ NEWDATA="${TOTAL:-0} ${TDONE:-0}"
+ LASTREPORT=$(sed -ne '$p' "$REPORT_FILE")
+ LASTDATA=${LASTREPORT#* } # Strip timestamp.
+ if [ "$LASTDATA" = "$NEWDATA" ]; then
+ echo "$LASTREPORT"
+ [ $TODOTXT_VERBOSE -gt 0 ] && echo "TODO: Report file is up-to-date."
+ else
+ NEWREPORT="$(date +%Y-%m-%dT%T) ${NEWDATA}"
+ echo "${NEWREPORT}" >> "$REPORT_FILE"
+ echo "${NEWREPORT}"
+ [ $TODOTXT_VERBOSE -gt 0 ] && echo "TODO: Report file updated."
+ fi
+ ;;
+
+"deduplicate" )
+ if [ $TODOTXT_PRESERVE_LINE_NUMBERS = 0 ]; then
+ deduplicateSedCommand='d'
+ else
+ deduplicateSedCommand='s/^.*//; p'
+ fi
+
+ # To determine the difference when deduplicated lines are preserved, only
+ # non-empty lines must be counted.
+ originalTaskNum=$( sed -e '/./!d' "$TODO_FILE" | sed -n '$ =' )
+
+ # Look for duplicate lines and discard the second occurrence.
+ # We start with an empty hold space on the first line. For each line:
+ # G - appends newline + hold space to the pattern space
+ # s/\n/&&/; - double up the first new line so we catch adjacent dups
+ # /^\([^\n]*\n\).*\n\1/b dedup
+ # If the first line of the hold space shows up again later as an
+ # entire line, it's a duplicate. Jump to the "dedup" label, where
+ # either of the following is executed, depending on whether empty
+ # lines should be preserved:
+ # d - Delete the current pattern space, quit this line and
+ # move on to the next, or:
+ # s/^.*//; p - Clear the task text, print this line and move on to
+ # the next.
+ # s/\n//; - else (no duplicate), drop the doubled newline
+ # h; - replace the hold space with the expanded pattern space
+ # P; - print up to the first newline (that is, the input line)
+ # b - end processing of the current line
+ sed -i.bak -n \
+ -e 'G; s/\n/&&/; /^\([^\n]*\n\).*\n\1/b dedup' \
+ -e 's/\n//; h; P; b' \
+ -e ':dedup' \
+ -e "$deduplicateSedCommand" \
+ "$TODO_FILE"
+
+ newTaskNum=$( sed -e '/./!d' "$TODO_FILE" | sed -n '$ =' )
+ deduplicateNum=$(( originalTaskNum - newTaskNum ))
+ if [ $deduplicateNum -eq 0 ]; then
+ echo "TODO: No duplicate tasks found"
+ else
+ echo "TODO: $deduplicateNum duplicate task(s) removed"
+ fi
+ ;;
+
+"listaddons" )
+ if [ -d "$TODO_ACTIONS_DIR" ]; then
+ cd "$TODO_ACTIONS_DIR" || exit $?
+ for action in *
+ do
+ if [ -f "$action" -a -x "$action" ]; then
+ echo "$action"
+ elif [ -d "$action" -a -x "$action/$action" ]; then
+ echo "$action"
+ fi
+ done
+ fi
+ ;;
+
+* )
+ usage;;
+esac
diff --git a/.zshrc b/.zshrc
new file mode 100644
index 0000000..8078788
--- /dev/null
+++ b/.zshrc
@@ -0,0 +1,86 @@
+## ~/.zshrc
+## ZSH configuration file
+## oh-my-zsh: http://ohmyz.sh/
+
+# Path to your oh-my-zsh installation.
+export ZSH=$HOME/.oh-my-zsh
+
+# Set name of the theme to load.
+# Look in ~/.oh-my-zsh/themes/
+# Optionally, if you set this to "random", it'll load a random theme each
+# time that oh-my-zsh is loaded.
+#ZSH_THEME="robbyrussell"
+ZSH_THEME="gentoo"
+
+# Example aliases
+# alias zshconfig="mate ~/.zshrc"
+# alias ohmyzsh="mate ~/.oh-my-zsh"
+
+# Uncomment the following line to use case-sensitive completion.
+# CASE_SENSITIVE="true"
+
+# Uncomment the following line to disable bi-weekly auto-update checks.
+DISABLE_AUTO_UPDATE="true"
+
+# Uncomment the following line to change how often to auto-update (in days).
+# export UPDATE_ZSH_DAYS=13
+
+# Uncomment the following line to disable colors in ls.
+# DISABLE_LS_COLORS="true"
+
+# Uncomment the following line to disable auto-setting terminal title.
+# DISABLE_AUTO_TITLE="true"
+
+# Uncomment the following line to disable command auto-correction.
+# DISABLE_CORRECTION="true"
+
+# Uncomment the following line to display red dots whilst waiting for completion.
+# COMPLETION_WAITING_DOTS="true"
+
+# Uncomment the following line if you want to disable marking untracked files
+# under VCS as dirty. This makes repository status check for large repositories
+# much, much faster.
+# DISABLE_UNTRACKED_FILES_DIRTY="true"
+
+# Uncomment the following line if you want to change the command execution time
+# stamp shown in the history command output.
+# The optional three formats: "mm/dd/yyyy"|"dd.mm.yyyy"|"yyyy-mm-dd"
+# HIST_STAMPS="mm/dd/yyyy"
+
+# Would you like to use another custom folder than $ZSH/custom?
+# ZSH_CUSTOM=/path/to/new-custom-folder
+
+# Which plugins would you like to load? (plugins can be found in ~/.oh-my-zsh/plugins/*)
+# Custom plugins may be added to ~/.oh-my-zsh/custom/plugins/
+# Example format: plugins=(rails git textmate ruby lighthouse)
+#plugins=(fasd git suse tmux vi-mode)
+plugins=(fasd git tmux vi-mode)
+
+source $ZSH/oh-my-zsh.sh
+
+# User configuration
+
+#export PATH="$HOME/bin:/usr/local/texlive/bin/x86_64-linux:/usr/lib64/mpi/gcc/openmpi/bin:/usr/local/bin:/usr/bin:/bin:/usr/bin/X11:/usr/X11R6/bin:/usr/games:/usr/local/sbin:/usr/sbin:/sbin"
+# export MANPATH="/usr/local/man:$MANPATH"
+
+# You may need to manually set your language environment
+# export LANG=en_US.UTF-8
+
+# Preferred editor for local and remote sessions
+if [[ -n $SSH_CONNECTION ]]; then
+ export EDITOR='vim'
+else
+ export EDITOR='vim'
+fi
+
+# Compilation flags
+# export ARCHFLAGS="-arch x86_64"
+
+# ssh
+# export SSH_KEY_PATH="~/.ssh/dsa_id"
+
+# zsh local config
+if [ -r ~/.zshrc.local ]; then
+ source ~/.zshrc.local
+fi
+
diff --git a/.zshrc.local b/.zshrc.local
new file mode 100644
index 0000000..90db61b
--- /dev/null
+++ b/.zshrc.local
@@ -0,0 +1,118 @@
+## ~/.zshrc.local
+## ZSH local configuration file
+##
+## Weitian LI <liweitianux@gmail.com>
+## 2014/05/31
+
+### locale {{{
+export LANG="en_US.utf8"
+export LC_CTYPE="zh_CN.utf8"
+export LC_COLLATE="C"
+### }}}
+
+### environments {{{
+if [ -d "$HOME/bin" ]; then
+ export PATH="$HOME/bin:$PATH"
+fi
+# admin
+if `groups | grep -qE '\b(wheel|adm|sudo)\b'`; then
+ export PATH="$PATH:/usr/local/sbin:/usr/sbin:/sbin"
+fi
+
+# GREP_OPTIONS deprecated
+unset GREP_OPTIONS
+alias grep='grep --color=auto'
+### environments }}}
+
+### vi mode {{{
+# oh-my-zsh: plugin: vi-mode
+# Vim's text-objects-ish for zsh: https://github.com/hchbaw/opp.zsh
+
+#bindkey -v
+# Reduce <ESC> delay to 0.1 seconds
+export KEYTIMEOUT=1
+## Key Bindings
+# Use vim cli mode
+bindkey '^P' up-history
+bindkey '^N' down-history
+# backspace and ^h working even after
+# returning from command mode
+bindkey '^?' backward-delete-char
+bindkey '^h' backward-delete-char
+# ctrl-w removed word backwards
+bindkey '^w' backward-kill-word
+# ctrl-r starts searching history backward
+bindkey '^r' history-incremental-search-backward
+### vi mode }}}
+
+### python-virtualenv {{{
+if [ -x /usr/bin/virtualenvwrapper.sh ]; then
+ export WORKON_HOME="$HOME/.virtualenvs"
+ export PROJECT_HOME="$HOME/web"
+ source /usr/bin/virtualenvwrapper.sh
+fi
+### python-virtualenv }}}
+
+### astro {{{
+## DS9 settings
+#if [ -x $HOME/bin/ds9 ]; then
+# alias ds9="$HOME/bin/ds9"
+#fi
+
+# backup LD_LIBRARY_PATH settings
+LD_LIBRARY_PATH_BAK="${LD_LIBRARY_PATH}"
+
+## HEASOFT settings
+export HEADAS="$HOME/local/heasoft/heasoft-6.16/x86_64-unknown-linux-gnu"
+function heainit() {
+ if [ "x${CALDB}" = "x" ]; then
+ export CALDB="$HOME/local/CALDB"
+ export CALDBALIAS="${CALDB}/software/tools/alias_config.fits"
+ export CALDBCONFIG="${CALDB}/software/tools/caldb.config"
+ fi
+ HEA_STATE="`echo $PATH | tr ':' '\n' | grep 'heasoft'`"
+ if [ "x${HEA_STATE}" = "x" ]; then
+ source $HEADAS/headas-init.sh > /dev/null
+ fi
+ unset HEA_STATE
+ export LD_LIBRARY_PATH="${LD_LIBRARY_PATH_BAK}"
+}
+
+## CIAO settings
+export CIAO_PATH="$HOME/local/ciao/ciao-4.6"
+function ciaoinit() {
+ HEA_STATE="`echo $PATH | tr ':' '\n' | grep 'heasoft'`"
+ CIAO_STATE="`echo $PATH | tr ':' '\n' | grep 'ciao'`"
+ if [ "x${HEA_STATE}" = "x" ]; then
+ heainit > /dev/null
+ fi
+ if [ "x${CIAO_STATE}" = "x" ]; then
+ source $CIAO_PATH/bin/ciao.bash > /dev/null
+ else
+ source $CIAO_PATH/bin/ciao.bash -o
+ fi
+ unset HEA_STATE
+ unset CIAO_STATE
+ export CIAO_LD_LIBRARY_PATH="${ASCDS_INSTALL}/ots/lib"
+}
+
+## chandra_acis_process scripts
+export MASS_PROFILE_DIR="$HOME/bin/mass"
+export CHANDRA_SCRIPT_DIR="$HOME/bin"
+### astro }}}
+
+### aliases {{{
+alias qmass='qdp summary_mass_profile.qdp'
+alias qnfw='qdp nfw_fit_center.qdp'
+alias qsbp='qdp sbp_fit_center.qdp'
+alias qtpro='qdp wang2012_fit_center.qdp'
+alias fitwang="${MASS_PROFILE_DIR}/fit_wang2012_model tcl_temp_profile.txt"
+alias fitmass="${MASS_PROFILE_DIR}/fit_mass.sh"
+alias fitnfw="${MASS_PROFILE_DIR}/fit_nfw_mass mass_int.dat"
+alias fitsbp="${MASS_PROFILE_DIR}/fit_sbp.sh"
+alias calclxfx="${MASS_PROFILE_DIR}/calc_lxfx_simple.sh"
+alias getlxfx="${MASS_PROFILE_DIR}/get_lxfx_data.sh"
+alias chcld="${CHANDRA_SCRIPT_DIR}/chandra_collect_data_v3.sh"
+alias chr500="${CHANDRA_SCRIPT_DIR}/ciao_r500avgt_v3.sh"
+### aliases }}}
+