aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--.mutt/attachments2
-rw-r--r--.mutt/colors1
-rw-r--r--.mutt/mailcap7
-rwxr-xr-x.mutt/mutt-xlabel.py164
-rwxr-xr-x.mutt/mutt_bgrun.sh4
-rw-r--r--.mutt/muttrc19
6 files changed, 186 insertions, 11 deletions
diff --git a/.mutt/attachments b/.mutt/attachments
index 6535626..74575de 100644
--- a/.mutt/attachments
+++ b/.mutt/attachments
@@ -61,4 +61,4 @@ attachments -I message/external-body
## your current settings in Muttrc format, so that it can be pasted
## elsewhere.
-# vim: filetype=muttrc
+# vim: set ts=8 sw=4 tw=0 fenc=utf-8 ft=muttrc: #
diff --git a/.mutt/colors b/.mutt/colors
index c709d50..de2f902 100644
--- a/.mutt/colors
+++ b/.mutt/colors
@@ -36,6 +36,7 @@ color header brightmagenta default "^(From|Subject):"
color header brightyellow default "^Date:"
color header brightblue default "^To:"
color header brightcyan default "^Cc:"
+color header brightblue default "^X-Label:"
mono header bold "^(From|Subject):"
diff --git a/.mutt/mailcap b/.mutt/mailcap
index fd1db6d..d531285 100644
--- a/.mutt/mailcap
+++ b/.mutt/mailcap
@@ -45,6 +45,9 @@ application/msword; word2text %s; copiousoutput
application/vnd.msword; ~/.mutt/mutt_bgrun.sh libreoffice %s; \
test=sh -c 'test -n "${DISPLAY}"'
application/vnd.msword; word2text %s; copiousoutput
+application/vnd.openxmlformats-officedocument.wordprocessingml.document; \
+ ~/.mutt/mutt_bgrun.sh libreoffice %s; \
+ test=sh -c 'test -n "${DISPLAY}"'
#
application/excel; ~/.mutt/mutt_bgrun.sh libreoffice %s; \
test=sh -c 'test -n "${DISPLAY}"'
@@ -103,8 +106,8 @@ video/*; ~/.mutt/mutt_bgrun.sh vlc %s; \
# Show archive conents.
#
application/x-compressed-tar; tar -tf %s; copiousoutput
-application/x-gnuzip; gzcat; copiousoutput
-application/x-bzip; bunzip2 -c %s | tar -tf -; copiousoutput
+application/x-bzip-compressed-tar; \
+ bunzip2 -c %s | tar -tf -; copiousoutput
application/x-tar-gz; gunzip -c %s | tar -tf -; copiousoutput
application/x-7z-compressed; 7z l %s; copiousoutput
diff --git a/.mutt/mutt-xlabel.py b/.mutt/mutt-xlabel.py
new file mode 100755
index 0000000..ea96e37
--- /dev/null
+++ b/.mutt/mutt-xlabel.py
@@ -0,0 +1,164 @@
+#!/usr/bin/env python3
+#
+# Add/Modify 'X-Label' header for mutt.
+# Label mails with mutt.
+#
+# Reference:
+# [1] GTD (Getting Things Done) and Mutt
+# https://docwhat.org/gtd-and-mutt/
+#
+# muttrc settings:
+# unignore X-Label:
+# macro index,pager x '<enter-command>set my_oldeditor=$editor<enter><enter-command>set editor="~/.mutt/mutt-xlabel.py"<enter><edit><previous-undeleted><clear-flag>N<sync-mailbox><enter-command>set editor=$my_oldeditor<enter>' \
+# "edit X-Label"
+# macro index \Cx "<limit>~y " \
+# "limit view to label"
+#
+# Weitian LI <liweitianux@gmail.com>
+# 2015/02/06
+#
+
+import sys
+import os
+import email
+import readline
+
+
+# Settings
+HISTFILE = os.path.join(os.environ["HOME"], ".mutt/xlabel_history")
+LABELFILE = os.path.join(os.environ["HOME"], ".mutt/xlabels")
+
+
+class MyCompleter(object):
+ """
+ Comstom completer for readline.
+
+ Reference:
+ [1] autocomplete - How to code autocompletion in python?
+ http://stackoverflow.com/a/7821956
+ """
+ def __init__(self, options):
+ self.options = sorted(options)
+
+ def complete(self, text, state):
+ if state == 0: # on first trigger, build possible matches
+ if text: # cache matches (entries that start with entered text)
+ self.matches = [s for s in self.options
+ if s and s.startswith(text)]
+ else: # no text entered, all matches possible
+ self.matches = self.options[:]
+
+ # return match indexed by state
+ try:
+ return self.matches[state]
+ except IndexError:
+ return None
+
+
+def my_input(prompt, default=None, completer=None):
+ if default is not None:
+ def pre_input_hook():
+ readline.insert_text(default)
+ readline.redisplay()
+ readline.set_pre_input_hook(pre_input_hook)
+ # completer
+ if completer:
+ readline.set_completer(completer)
+ readline.parse_and_bind('tab: complete')
+ return input(prompt)
+
+
+def load_labels(labelfile):
+ """
+ Load saved labels from given labelfile,
+ return a list of labels.
+ """
+ try:
+ with open(labelfile, 'r') as f:
+ label_list = f.read().split()
+ label_list = list(set(label_list))
+ except FileNotFoundError:
+ label_list = []
+ return label_list
+
+
+def update_labels(labelfile, label_list, new_label_list):
+ """
+ Save labels for later autocompletion.
+ """
+ labels = sorted(list(set(label_list).union(set(new_label_list))))
+ with open(labelfile, 'w') as f:
+ f.write(' '.join(labels))
+
+
+def get_xlabel(message):
+ """
+ Get 'X-Label:' values from given Message object.
+ """
+ labels = message.get_all('X-Label')
+ if labels:
+ label_str = ' '.join(labels)
+ else:
+ label_str = ''
+ # remove duplicates and sort
+ label_list = sorted(list(set(label_str.split())))
+ return label_list
+
+
+def write_xlabel(message, old_label_list, new_label_list, outfile):
+ """
+ Update 'X-Label' value of given Message object;
+ then write Message object to outfile.
+ """
+ # remove duplicates and sort
+ new_label_list = sorted(list(set(new_label_list)))
+ if set(old_label_list) != set(new_label_list):
+ # delete original 'X-Label' header (all occurences)
+ del message['X-Label']
+ # add new 'X-Label' header
+ message['X-Label'] = ' '.join(new_label_list)
+ # write to outfile (Just OVERWRITE, OK??)
+ fp_out = open(outfile, 'w')
+ fp_out.write(message.as_string())
+ fp_out.close()
+
+
+def main():
+ if len(sys.argv) != 2 and len(sys.argv) != 3:
+ print("Usage: %s <mail> [ outmail ]" % sys.argv[0])
+ sys.exit(1)
+
+ inmail = sys.argv[1]
+ if len(sys.argv) == 3:
+ outmail = sys.argv[2]
+ else:
+ outmail = inmail
+
+ if hasattr(readline, 'read_history_file'):
+ try:
+ readline.read_history_file(HISTFILE)
+ except IOError:
+ pass
+
+ # get all recorded labels for readline autocompletion
+ all_labels = load_labels(LABELFILE)
+ completer = MyCompleter(all_labels)
+
+ # open mail and create email.message.Message object
+ msg = email.message_from_file(open(inmail, 'r'))
+ # get original labels
+ label_list = get_xlabel(msg)
+ # get user provided labels
+ new_label = my_input(prompt='X-Label: ', default=' '.join(label_list),
+ completer=completer.complete)
+ # write new labels to mail
+ write_xlabel(msg, label_list, new_label.split(), outmail)
+ # save readline history
+ readline.write_history_file(HISTFILE)
+ # save labels
+ update_labels(LABELFILE, all_labels, new_label.split())
+
+
+if "__main__" == __name__:
+ main()
+
diff --git a/.mutt/mutt_bgrun.sh b/.mutt/mutt_bgrun.sh
index 08d5e6b..0b2c651 100755
--- a/.mutt/mutt_bgrun.sh
+++ b/.mutt/mutt_bgrun.sh
@@ -88,7 +88,7 @@ do
shift
done
-file=$1
+file="$1"
# Create a temporary directory for our copy of the temporary file.
#
@@ -99,6 +99,8 @@ tmpdir=/tmp/$LOGNAME$$
umask 077
mkdir "$tmpdir" || exit 1
tmpfile="$tmpdir/${file##*/}"
+#echo "file: ${file}" > ~/debug.$$.log
+#echo "tmpfile: ${tmpfile}" >> ~/debug.$$.log
# Copy mutt's temporary file to our temporary directory so that we can
# let mutt overwrite and delete it when we exit.
diff --git a/.mutt/muttrc b/.mutt/muttrc
index 6c640b7..cf30a88 100644
--- a/.mutt/muttrc
+++ b/.mutt/muttrc
@@ -88,9 +88,9 @@ unset mime_forward # forward attachments as part of body
### Headers
ignore *
-unignore from: to: cc: bcc: date: subject:
+unignore from: to: cc: bcc: date: subject: X-Label:
unhdr_order *
-hdr_order from: to: cc: date: subject:
+hdr_order from: to: cc: date: subject: X-Label:
### Encoding
set send_charset = "us-ascii:utf-8"
@@ -101,7 +101,7 @@ set rfc2047_parameters # to fix attachment filename encoding
### Index view
# first bang ("!") to expand month week names in the C locale
set date_format = "!%a %m/%d %I:%M"
-set index_format = "[%Z] %d %3M %-15.15L (%4c) %s"
+set index_format = "[%Z] %d %2M %-15.15L %4c%?X?[%X]& ? %s"
set folder_format = "%2C %t %N %8s %f"
set sort = threads
set sort_aux = reverse-last-date-received
@@ -166,7 +166,7 @@ macro index B "<limit>~b " \
macro index I "<change-folder>!<enter>" \
"go to Inbox"
# Save a decoded copy in ~/
-macro index > "<pipe-message>cat > ~/" \
+macro index,pager > "<pipe-message>cat > ~/" \
"save message as"
# Open in vim
macro index,pager V "<pipe-message>vim -c 'setlocal ft=mail buftype=nofile' -<enter>" \
@@ -188,6 +188,11 @@ macro pager ';' "<exit><tag-prefix>" \
# notmuch
macro index s "<enter-command>unset wait_key<enter><shell-escape>~/.mutt/mutt-notmuch.py -G $folder/search<enter><change-folder-readonly>+search<enter>" \
"search mail (using notmuch)"
+# labels
+macro index,pager x '<enter-command>set my_oldeditor=$editor<enter><enter-command>set editor="~/.mutt/mutt-xlabel.py"<enter><edit><previous-undeleted><clear-flag>N<sync-mailbox><enter-command>set editor=$my_oldeditor<enter>' \
+ "edit X-Label"
+macro index \Cx "<limit>~y " \
+ "limit view to label"
### aliases
set sort_alias = alias # sort alias file by alias
@@ -216,7 +221,7 @@ macro index,pager P "<shell-escape>tmux new-window -a -t mutt 'mutt -F ~
"recall postponed message in new tmux window"
# Set the editor for for editing messages in-place,
# allows re-editing before sending, e.g. for use in forwarding messages.
-macro compose E '<enter-command>set my_oldeditor=$editor<enter><enter-command>set editor="vim"<enter><edit-message><enter-command>set editor=$my_oldeditor<enter>' \
+macro compose E '<enter-command>set my_oldeditor=$editor<enter><enter-command>set editor="vim"<enter><edit><enter-command>set editor=$my_oldeditor<enter>' \
"edit message in-place"
# open mailbox listing in a new window
macro index,pager Y '<shell-escape>tmux new-window -a -t mutt "mutt -y"<enter>' \
@@ -232,8 +237,8 @@ source ~/.mutt/colors
source ~/.mutt/gpg.rc
## auto view
-auto_view text/html application/x-gunzip application/x-bzip \
- application/x-tar-gz application/x-compressed-tar
+auto_view text/html application/x-tar-gz application/x-compressed-tar \
+ application/x-bzip-compressed-tar
## MIME types that should *not* be treated according to their mailcap entry
mime_lookup application/octet-stream application/X-Lotus-Manuscript