--- /dev/null
+Return-Path: <peterjohnhartman@gmail.com>\r
+X-Original-To: notmuch@notmuchmail.org\r
+Delivered-To: notmuch@notmuchmail.org\r
+Received: from localhost (localhost [127.0.0.1])\r
+ by olra.theworths.org (Postfix) with ESMTP id A0742429E25\r
+ for <notmuch@notmuchmail.org>; Sat, 1 Oct 2011 07:29:11 -0700 (PDT)\r
+X-Virus-Scanned: Debian amavisd-new at olra.theworths.org\r
+X-Spam-Flag: NO\r
+X-Spam-Score: -0.799\r
+X-Spam-Level: \r
+X-Spam-Status: No, score=-0.799 tagged_above=-999 required=5\r
+ tests=[DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1,\r
+ FREEMAIL_FROM=0.001, RCVD_IN_DNSWL_LOW=-0.7] autolearn=disabled\r
+Received: from olra.theworths.org ([127.0.0.1])\r
+ by localhost (olra.theworths.org [127.0.0.1]) (amavisd-new, port 10024)\r
+ with ESMTP id WRr-rh2U9lHW for <notmuch@notmuchmail.org>;\r
+ Sat, 1 Oct 2011 07:29:10 -0700 (PDT)\r
+Received: from mail-qw0-f53.google.com (mail-qw0-f53.google.com\r
+ [209.85.216.53]) (using TLSv1 with cipher RC4-SHA (128/128 bits))\r
+ (No client certificate requested)\r
+ by olra.theworths.org (Postfix) with ESMTPS id 9D017431FB6\r
+ for <notmuch@notmuchmail.org>; Sat, 1 Oct 2011 07:29:10 -0700 (PDT)\r
+Received: by qafi31 with SMTP id i31so1117678qaf.26\r
+ for <notmuch@notmuchmail.org>; Sat, 01 Oct 2011 07:29:09 -0700 (PDT)\r
+DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=gamma;\r
+ h=date:from:to:subject:message-id:mime-version:content-type\r
+ :content-disposition:content-transfer-encoding:user-agent;\r
+ bh=7Z16G0kWwpuK+c9yPTmsU3umWxcJOK2cpgqZtNsGHDg=;\r
+ b=ACef3DvQsWtCogz+nqTVnPumDuCW905jniOlWQPAyhz/uth5wafaHjCKepatrFs7zC\r
+ nEogpRCssCOyHKEPHS7s8uFk27A6LYIXxIjXJ6PJ4VbPUYxb5cup+cjdUqRQI8i4V+Ig\r
+ uvDsTyzZQWnZZoB1N8wtDT7ZFgEj2LciGR7cU=\r
+Received: by 10.224.203.196 with SMTP id fj4mr9875374qab.362.1317479348788;\r
+ Sat, 01 Oct 2011 07:29:08 -0700 (PDT)\r
+Received: from localhost (ip-64-134-98-119.public.wayport.net.\r
+ [64.134.98.119]) by mx.google.com with ESMTPS id\r
+ du5sm9189819qab.14.2011.10.01.07.29.07 (version=SSLv3 cipher=OTHER); Sat, 01\r
+ Oct 2011 07:29:08 -0700 (PDT)\r
+Date: Sat, 1 Oct 2011 10:29:06 -0400\r
+From: Peter John Hartman <peterjohnhartman@gmail.com>\r
+To: notmuch@notmuchmail.org\r
+Subject: an alternative commandline interface to notmuch\r
+Message-ID: <20111001142906.GA635@leneee.sbx07386.newyony.wayport.net>\r
+MIME-Version: 1.0\r
+Content-Type: text/plain; charset=iso-8859-1\r
+Content-Disposition: inline\r
+Content-Transfer-Encoding: 8bit\r
+User-Agent: Mutt/1.5.21 (2010-09-15)\r
+X-BeenThere: notmuch@notmuchmail.org\r
+X-Mailman-Version: 2.1.13\r
+Precedence: list\r
+List-Id: "Use and development of the notmuch mail system."\r
+ <notmuch.notmuchmail.org>\r
+List-Unsubscribe: <http://notmuchmail.org/mailman/options/notmuch>,\r
+ <mailto:notmuch-request@notmuchmail.org?subject=unsubscribe>\r
+List-Archive: <http://notmuchmail.org/pipermail/notmuch>\r
+List-Post: <mailto:notmuch@notmuchmail.org>\r
+List-Help: <mailto:notmuch-request@notmuchmail.org?subject=help>\r
+List-Subscribe: <http://notmuchmail.org/mailman/listinfo/notmuch>,\r
+ <mailto:notmuch-request@notmuchmail.org?subject=subscribe>\r
+X-List-Received-Date: Sat, 01 Oct 2011 14:29:11 -0000\r
+\r
+Hi folks,\r
+\r
+Rafa released slmenu, a dmenu-clone that runs on the commandline, and I\r
+contributed a couple of patches (verticality and tokens) to make it work\r
+nice with notmuch. So far, I'm pretty happy. To get slmenu:\r
+\r
+hg clone http://hg.suckless.org/slmenu\r
+\r
+You'll need to apply the patch at the bottom of this e-mail[1].\r
+You'll also want to use the shell script (nmsl) at the bottom of this e-mail[2].\r
+\r
+How it works:\r
+\r
+Basically, it pipes output (after being mangled a bit) from notmuch search\r
+into slmenu/dmenu (so you can select the thread) and then sends that output \r
+to mutt, either via mbox (if notmuch is hosted remote) or maildir (if local).\r
+It also allows you to prepend an entry with v (tag viewed), t +tag (tag\r
+tag), x (tag x-del).\r
+\r
+All this will be at:\r
+\r
+http://durandus.trilidun.org/durandus/code/notmuch-slmenu/\r
+Best,\r
+Peter\r
+\r
+\r
+\r
+[1] token.patch to slmenu\r
+\r
+diff -r 7896c4e3bf21 slmenu.c\r
+--- a/slmenu.c Thu Sep 29 12:45:34 2011 +0200\r
++++ b/slmenu.c Sat Oct 01 10:11:29 2011 -0400\r
+@@ -36,7 +36,7 @@\r
+ static void drawmenu(void);\r
+ static char *fstrstr(const char*, const char*);\r
+ static void insert(const char*, ssize_t);\r
+-static void match(int);\r
++static void match(void); \r
+ static size_t nextrune(int);\r
+ static void readstdin(void);\r
+ static int run(void);\r
+@@ -60,10 +60,10 @@\r
+ \r
+ void\r
+ appenditem(Item *item, Item **list, Item **last) {\r
+- if(!*last)\r
++ if(*last)\r
++ (*last)->right = item;\r
++ else\r
+ *list = item;\r
+- else\r
+- (*last)->right = item;\r
+ item->left = *last;\r
+ item->right = NULL;\r
+ *last = item;\r
+@@ -132,13 +132,17 @@\r
+ Item *item;\r
+ int rw;\r
+ \r
++ fprintf(stderr, "\033[H"); \r
++ fprintf(stderr, "\033[2J"); \r
++\r
+ /* use default colors */\r
+ fprintf(stderr, "\033[0m");\r
++/* setupterm(); \r
++ putp(clear_screen); */\r
+ \r
+ /* place cursor in first column, clear it */\r
+ fprintf(stderr, "\033[0G");\r
+ fprintf(stderr, "\033[K");\r
+-\r
+ if(prompt)\r
+ drawtext(prompt, promptw-4, C_Reverse);\r
+ \r
+@@ -188,9 +192,10 @@\r
+ if(n > 0)\r
+ memcpy(&text[cursor], str, n);\r
+ cursor += n;\r
+- match(n > 0 && text[cursor] == '\0');\r
++ match();\r
+ }\r
+ \r
++/*\r
+ void\r
+ match(int sub) {\r
+ size_t len = strlen(text);\r
+@@ -231,6 +236,60 @@\r
+ curr = sel = matches;\r
+ calcoffsets();\r
+ }\r
++*/\r
++\r
++void\r
++match(void) {\r
++ static char **tokv = NULL;\r
++ static int tokn = 0;\r
++\r
++ char buf[sizeof text], *s;\r
++ int i, tokc = 0;\r
++ size_t len;\r
++ Item *item, *lprefix, *lsubstr, *prefixend, *substrend;\r
++ \r
++ strcpy(buf, text);\r
++ for(s = strtok(buf, " "); s; tokv[tokc-1] = s, s = strtok(NULL, " "))\r
++ if(++tokc > tokn && !(tokv = realloc(tokv, ++tokn * sizeof *tokv)))\r
++ die("Can't realloc.");\r
++/* fprintf("cannot realloc %u bytes\n", tokn * sizeof *tokv); */\r
++ len = tokc ? strlen(tokv[0]) : 0;\r
++ \r
++ matches = lprefix = lsubstr = matchend = prefixend = substrend = NULL;\r
++ for(item = items; item && item->text; item++) {\r
++ for(i = 0; i < tokc; i++)\r
++ if(!fstrstr(item->text, tokv[i]))\r
++ break;\r
++ if (i != tokc)\r
++ continue;\r
++ if(!tokc || !fstrncmp(tokv[0], item->text, len+1))\r
++ appenditem(item, &matches, &matchend);\r
++ else if(!strncmp(tokv[0], item->text, len))\r
++ appenditem(item, &lprefix, &prefixend);\r
++ else\r
++ appenditem(item, &lsubstr, &substrend);\r
++ }\r
++ if(lprefix) {\r
++ if(matches) {\r
++ matchend->right = lprefix;\r
++ lprefix->left = matchend;\r
++ }\r
++ else\r
++ matches = lprefix;\r
++ matchend = prefixend;\r
++ }\r
++ if(lsubstr) {\r
++ if(matches) {\r
++ matchend->right = lsubstr;\r
++ lsubstr->left = matchend;\r
++ }\r
++ else\r
++ matches = lsubstr;\r
++ matchend = substrend;\r
++ }\r
++ curr = sel = matches;\r
++ calcoffsets();\r
++}\r
+ \r
+ size_t\r
+ nextrune(int inc) {\r
+@@ -371,7 +430,7 @@\r
+ case CONTROL('J'):\r
+ if(sel) strncpy(text, sel->text, sizeof text); /* Complete the input first, when hitting return */\r
+ cursor = strlen(text);\r
+- match(TRUE);\r
++ match();\r
+ drawmenu();\r
+ /* fallthrough */\r
+ case CONTROL(']'):\r
+@@ -441,11 +500,11 @@\r
+ break;\r
+ strncpy(text, sel->text, sizeof text);\r
+ cursor = strlen(text);\r
+- match(TRUE);\r
++ match(); \r
+ break;\r
+ case CONTROL('K'):\r
+ text[cursor] = '\0';\r
+- match(FALSE);\r
++ match(); \r
+ break;\r
+ case CONTROL('U'):\r
+ insert(NULL, 0 - cursor);\r
+@@ -514,7 +573,7 @@\r
+ lines=MIN(MAX(lines, 0), mh);\r
+ promptw=(prompt?textw(prompt):0);\r
+ inputw=MIN(inputw, mw/3);\r
+- match(FALSE);\r
++ match();\r
+ if(barpos!=0) resetline();\r
+ drawmenu();\r
+ }\r
+@@ -542,7 +601,7 @@\r
+ puts("slmenu, © 2011 slmenu engineers, see LICENSE for details");\r
+ exit(EXIT_SUCCESS);\r
+ }\r
+- else if(!strcmp(argv[i], "-i"))\r
++ else if(!strcmp(argv[i], "-i")) \r
+ fstrncmp = strncasecmp;\r
+ else if(!strcmp(argv[i], "-t"))\r
+ barpos=1;\r
+\r
+[2] nmsl shell script\r
+#!/bin/sh\r
+# Copyright (c) Peter John Hartman (peterjohnhartman at gmail dot com)\r
+#\r
+# * Permission to use, copy, modify, and distribute this software for any\r
+# * purpose with or without fee is hereby granted, provided that the above\r
+# * copyright notice and this permission notice appear in all copies.\r
+# *\r
+# * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES\r
+# * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF\r
+# * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR\r
+# * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES\r
+# * WHATSOEVER RESULTING FROM LOSS OF MIND, USE, DATA OR PROFITS, WHETHER\r
+# * IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING\r
+# * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.\r
+\r
+maildir="/tmp/maildir"\r
+slmenu="slmenu -i -l 30 -t -p [vtx]:"\r
+#slmenu="dmenu -i -l 30 -p [vtx]:"\r
+notmuch="/usr/local/bin/notmuch"\r
+use_maildir=1\r
+usage() {\r
+ cat << EOF\r
+ usage: $0 options\r
+\r
+ Example: nmsl `nmdate 3 days ago`..`nmdate yesterday` tag:inbox\r
+ Example: nmsl tag:inbox and tag:unread\r
+\r
+ nmdate = echo $(date +%s -d "$*")\r
+\r
+ OPTIONS:\r
+ -h Show this message\r
+ -s Use ssh\r
+EOF\r
+}\r
+\r
+while getopts "hsd:" OPTION\r
+do\r
+ case $OPTION in\r
+ h) \r
+ usage\r
+ exit 1\r
+ ;;\r
+ s)\r
+ notmuch="ssh trillap /usr/local/bin/notmuch"\r
+ use_maildir=0\r
+ ;;\r
+ esac\r
+done\r
+\r
+shift $((OPTIND-1))\r
+search=$@\r
+\r
+if [[ $search == "" ]]; then\r
+ search="tag:inbox and tag:unread"\r
+fi\r
+\r
+res=$($notmuch search $search |\\r
+ sed -r 's/([^ ]*) ([^[]*)([^]]*\]) ([^;]*); (.*) (\([^)]*\))/\2\5; \4 \3 \6 \1/' |\\r
+ $slmenu)\r
+\r
+if [[ $res != "" ]]; then\r
+ option=$(echo $res | cut -d' ' -f1)\r
+\r
+ case "$option" in\r
+ x) \r
+ # delete\r
+ thread=$(echo $res | awk -F' ' '{print $NF}')\r
+ notmuch tag -unread +x-del $thread\r
+ nmsl $*\r
+ ;;\r
+ t)\r
+ # tag;\r
+ thread=$(echo $res | awk -F' ' '{print $NF}')\r
+ notmuch tag $(echo $res | cut -d' ' -f2) -inbox $thread\r
+ nmsl $*\r
+ ;;\r
+ v)\r
+ # quick -unread\r
+ thread=$(echo $res | awk -F' ' '{print $NF}')\r
+ notmuch tag -unread $thread\r
+ nmsl $*\r
+ ;;\r
+ *)\r
+ thread=$(echo $res | awk -F' ' '{print $NF}')\r
+ clear\r
+ if [[ $use_maildir -eq 1 ]]; then\r
+ rm -rf $maildir\r
+ mkdir $maildir\r
+ mkdir $maildir/cur\r
+ mkdir $maildir/new\r
+ mkdir $maildir/tmp\r
+ $notmuch search --output=files $thread | sed -e 's: :\\ :g' |\\r
+ xargs --no-run-if-empty ln -s -t $maildir/cur/\r
+ mutt -f $maildir\r
+ else\r
+ $notmuch show --format=mbox $thread > /tmp/nmsearch.$$\r
+ mutt -f /tmp/nmsearch.$$\r
+ rm -f -- /tmp/nmsearch.$$\r
+ fi\r
+ nmsl $*\r
+ ;;\r
+ esac\r
+fi\r
+\r
+clear\r
+\r
+\r
+\r
+\r
+\r
+\r
+\r
+-- \r
+sic dicit magister P\r
+University of Toronto / Fordham University\r
+Collins Hall B06; Office Hours TF10-12\r
+http://individual.utoronto.ca/peterjh\r
+gpg 1024D/ED6EF59B (7D1A 522F D08E 30F6 FA42 B269 B860 352B ED6E F59B)\r
+gpg --keyserver pgp.mit.edu --recv-keys ED6EF59B\r