commit 85fff4dcda76c804ab3707b095b0b2e68b3d593b
parent 429b71eef4ff09198fbd477d226a592573525d60
Author: Jaromil <jaromil@dyne.org>
Date:   Tue, 30 Dec 2014 15:32:29 +0100
several changes for notmuch integration, also gnupg address extraction
Diffstat:
6 files changed, 327 insertions(+), 272 deletions(-)
diff --git a/src/jaro b/src/jaro
@@ -451,7 +451,9 @@ a pipe | in front indicate they take an email body from stdin
 
  list     prints to console all the entries in $list
 
- search   search into $list using a string parameter
+ index    index fetched email archives for search
+
+ search   search using a string parameter
 
 |isknown  read e-mail from stdin, return 0 if sender is known
 
@@ -532,6 +534,7 @@ main()
 
     subcommands_opts[stat]=""
 
+    subcommands_opts[index]=""
     subcommands_opts[search]=""
 
     subcommands_opts[learn]=""
@@ -548,6 +551,8 @@ main()
     subcommands_opts[preview]=""
 
     subcommands_opts[later]=""
+    subcommands_opts[remember]=""
+
     subcommands_opts[backup]=""
     subcommands_opts[rmdupes]=""
     subcommands_opts[merge]=""
@@ -675,7 +680,7 @@ main()
     send)    send ${PARAM} ;; # was checking is_online
     peek)    peek ${PARAM} ;; # was checking is_online
 
-    later)   later ${PARAM} ;;
+    later|remember) cat | deliver remember ;;
 
     update|init)
         init_inbox
@@ -686,6 +691,7 @@ main()
 
     help) CLEANEXIT=0; usage ;;
 
+    index) CLEANEXIT=0; nm_index ${PARAM} ;;
     search)  CLEANEXIT=0; search ${PARAM} ;;
 
     stat)   CLEANEXIT=0; stats ${PARAM} ;;
@@ -783,7 +789,7 @@ main()
         ;;
 
     list|extract)
-            extract ${=PARAM}
+            extract ${PARAM}
             exitcode=$?
             ;;
 
diff --git a/src/zlibs/addressbook b/src/zlibs/addressbook
@@ -74,13 +74,13 @@ remove_address() {
 }
 
 search_addressbook() {
-    func "search \"$1\" in $list"
-    abook --datafile "$ADDRESSBOOK" --mutt-query "$1"
+    func "search \"$@\" in $list"
+    abook --datafile "$ADDRESSBOOK" --mutt-query "$@"
 }
 
 
 lookup_email() {
-    func "lookup email $1 in $list"
+    func "lookup address $1 in $list"
     abook --datafile "$ADDRESSBOOK" \
         --mutt-query "$1" > /dev/null
     return $?
@@ -101,6 +101,7 @@ complete() {
                 act "Searching for \"$needle\" in mailout groups"
                 matches=`${=find} "$MAILDIRS/Groups" -type f -name \"*$needle*\"`
             fi
+
             print "Groups: `print $matches | wc -l` matches"
             print
             for i in ${(f)matches}; do
@@ -144,7 +145,7 @@ learn() {
 
     case ${what} in
 
-        sender) # simple: one address only on From:
+        sender|from) # simple: one address only on From:
             head="`print $buffer | ${WORKDIR}/bin/fetchaddr -x From -a`"
             # (Q) eliminates quotes, then word split
             email="${(Q)head[(ws:,:)1]}"
@@ -174,7 +175,7 @@ learn() {
             return 0
             ;;
 
-        recipient) # complex: more addresses in To: and Cc:
+        recipient|to) # complex: more addresses in To: and Cc:
             head="`print $buffer | ${WORKDIR}/bin/fetchaddr -x To -a`"
             for h in ${(f)head}; do
                 # (Q) eliminates quotes, then word split
@@ -221,13 +222,78 @@ forget() {
     # remove_address "${head[(ws:,:)1]}"
 }
 
+# extract all addresses found into a maildir
+extract_maildir() {
+    ## first arg is a directory
+    md="$1"
+    func "extract maildir: $md"
+    ## extract from a maildir
+    maildircheck "$md" && {
+        _action="$2"
+        case $_action in
+            all) ;;
+            recipient) ;;
+            sender) ;;
+            *) _action="all" ;;
+        esac
+
+        # search files
+        _mails=`find $md -type f`
+        # search symlinks
+        _mails+=`find $md -type l`
+
+        # TODO ismailfile() to check if file is a mail?
+        
+        # we switch dryrun temporarily off to use learn()
+        # without modifying the addressbook
+        _dryrun=$DRYRUN
+        DRYRUN=1
+        
+        notice "Extracting and listing $_action in maildir: $md"
+        act "please wait while scanning `print $_mails | wc -l` mail files..."
+        typeset -a learned
+        
+        for i in ${(f)_mails}; do
+            _l=`hdr $i | learn $_action`
+            # handles results on multiple lines (recipients, all)
+            for ii in ${(f)_l}; do
+                learned+=("$ii")
+            done
+        done
+        
+        DRYRUN=$_dryrun
+        # eliminates duplicates
+        typeset -A result
+        for i in ${learned}; do
+            _e=${i[(ws:,:)1]}
+            [[ "${result[$_e]}" = "" ]] && {
+                _n=${i[(ws:,:)2]}
+                result+=("$_e" "$_n")
+                print - "$_n <$_e>"
+            }
+        done
+        notice "Unique $_action found: ${#result}"
+        # counts which addresses are known to us
+        _known=0
+        for i in ${(k)result}; do
+            lookup_email ${i}
+            [[ $? = 0 ]] && {
+                _known=$(( $_known + 1 )) }
+        done
+        act "addresses known: $_known"
+        return 0
+    }
+}
+
 # extract all entries in addressbook or all addresses in a pgp keyring
 # or all signatures on a pgp key (even without importing it)
 extract() {
-    func "extract() $@"
+    func "calling extract() $PARAM"
+
     # without arguments just list all entries in the active list
     # default is whitelist
     [[ "$1" = "" ]] && {
+        func "extract all from list $list"
         awk -F'=' '
 /^name/  { printf("%s ",$2)    }
 /^email/ { printf("<%s>\n",$2) }
@@ -235,140 +301,97 @@ extract() {
         return 0
     }
 
-    # a map to eliminate duplicates
-    typeset -AU result
 
-    [[ -r "$1" ]] || {
-        error "file not found: $1"
-        error "nothing to extract."
-        return 1
-    }
+    [[ -r "$1" ]] && { # first arg is a file
 
-    ## arg is a directory
-    [[ -d "$1" ]] && { 
-        func "extract maildir: $1"
-        ## extract from a maildir
-        maildircheck "$1" && {
-            _action="$2"
-            case $_action in
-                all) ;;
-                recipient) ;;
-                sender) ;;
-                *) _action="all" ;;
-            esac
-            _mails=`find $1 -type f`
-            # TODO ismailfile() to check if file is a mail?
-
-            # we switch dryrun temporarily off to use learn()
-            # without modifying the addressbook
-            _dryrun=$DRYRUN
-            DRYRUN=1
-            
-            notice "Extracting and listing $_action in maildir: $2"
-            act "please wait while scanning ${#_mails} mail files..."
-            typeset -a learned
-
-            for i in ${(f)_mails}; do
-                _l=`hdr $i | learn $_action`
-                # handles results on multiple lines (recipients, all)
-                for i in ${(f)_l}; do
-                    learned+=("$i")
-                done
-            done
-            
-            DRYRUN=$_dryrun
-            # eliminates duplicates
-            typeset -A result
-            for i in ${learned}; do
-                _e=${i[(ws:,:)1]}
+        # a map to eliminate duplicates
+        typeset -AU result
+        
+        # if first arg is a directory then extract from maildir
+        [[ -d "$1" ]] && { 
+            extract_maildir "$1" "$2"
+            return $?
+        }
+
+        func "testing argument with file magic"
+        _magic=`file "$1"`
+
+        ######### GPG
+        # first arg is a GnuPG key ring
+        [[ "$_magic" =~ "GPG key public ring" ]] && {
+
+            notice "Listing addresses found in GPG keyring: $1"
+            _addrs=`gpg --list-keys --with-colons | awk -F: '{print $10}'`
+            for i in ${(f)_addrs}; do
+                _parsed=`print "From: $i" | ${WORKDIR}/bin/fetchaddr -a -x from`
+                _e="${_parsed[(ws:,:)1]}"
+                isemail "$_e"
+                [[ $? = 0 ]] || continue
+                # check if the email is not already parsed
                 [[ "${result[$_e]}" = "" ]] && {
-                    _n=${i[(ws:,:)2]}
+                    _n="${_parsed[(ws:,:)2]}"
                     result+=("$_e" "$_n")
                     print - "$_n <$_e>"
                 }
             done
-            notice "Unique $_action found: ${#result}"
+
+            notice "Unique addresses found: ${#result}"
             # counts which addresses are known to us
             _known=0
             for i in ${(k)result}; do
                 lookup_email ${i}
-                [[ $? = 0 ]] && {
-            _known=$(( $_known + 1 )) }
+                [[ $? = 0 ]] || {
+                    _known=$(( $_known + 1 )) }
             done
-            act "addresses known: $_known"
+            act "new addresses: $_known"
             return 0
         }
-    }
-
-    ######### GPG
-    [[ `file "$1"` =~ "GPG key public ring" ]] && {
-
-        notice "Listing addresses found in GPG keyring: $1"
-        _addrs=`gpg --list-keys --with-colons | awk -F: '{print $10}'`
-        for i in ${(f)_addrs}; do
-            _parsed=`print "From: $i" | ${WORKDIR}/bin/fetchaddr -a -x from`
-            _e="${_parsed[(ws:,:)1]}"
-            isemail "$_e"
-            [[ $? = 0 ]] || continue
-            # check if the email is not already parsed
-            [[ "${result[$_e]}" = "" ]] && {
-                _n="${_parsed[(ws:,:)2]}"
-                result+=("$_e" "$_n")
-                print - "$_n <$_e>"
-            }
-        done
 
-        notice "Unique addresses found: ${#result}"
+        # first arg is a GnuPG public key
+        [[ "$_magic" =~ "PGP public key" ]] && {
+            _gpg="gpg --no-default-keyring --keyring $MAILDIRS/cache/pubkey.gpg --batch --with-colons"
+            rm -f $MAILDIRS/cache/pubkey.gpg
+            ${=_gpg} --import "$1"
+            # first make sure all unknown keys are imported
+            _addrs=`${=_gpg} --list-sigs | awk -F: '{print $5 " " $10}'`
+            for i in ${(f)_addrs}; do
+                [[ "$i" =~ "[User ID not found]" ]] && {
+                    act "looking up: $i"
+                    ${=_gpg} --recv-key ${i[(w)1]}
+                }
+            done
+            
+            _addrs=`${=_gpg} --list-sigs | awk -F: '{print $10}'`
+            for i in ${(f)_addrs}; do
+                _parsed=`print "From: $i" | ${WORKDIR}/bin/fetchaddr -a -x from`
+                _e="${_parsed[(ws:,:)1]}"
+                isemail "$_e"
+                [[ $? = 0 ]] || continue
+                # check if the email is not already parsed
+                [[ "${result[$_e]}" = "" ]] && {
+                    _n="${_parsed[(ws:,:)2]}"
+                    result+=("$_e" "$_n")
+                    print - "$_n <$_e>"
+                }
+            done
+            
+            notice "Unique addresses found: ${#result}"
             # counts which addresses are known to us
-        _known=0
-        for i in ${(k)result}; do
-            lookup_email ${i}
-            [[ $? = 0 ]] || {
-                _known=$(( $_known + 1 )) }
-        done
-        act "new addresses: $_known"
-        return 0
+            _known=0
+            for i in ${(k)result}; do
+                lookup_email ${i}
+                [[ $? = 0 ]] || {
+                    _known=$(( $_known + 1 )) }
+            done
+            act "new addresses: $_known"
+            return 0
+        }
     }
 
-    [[ `file "$1"` =~ "PGP public key" ]] && {
-        _gpg="gpg --no-default-keyring --keyring $MAILDIRS/cache/pubkey.gpg --batch --with-colons"
-        rm -f $MAILDIRS/cache/pubkey.gpg
-        ${=_gpg} --import "$1"
-        # first make sure all unknown keys are imported
-        _addrs=`${=_gpg} --list-sigs | awk -F: '{print $5 " " $10}'`
-        for i in ${(f)_addrs}; do
-            [[ "$i" =~ "[User ID not found]" ]] && {
-                act "looking up: $i"
-                ${=_gpg} --recv-key ${i[(w)1]}
-            }
-        done
-        
-        _addrs=`${=_gpg} --list-sigs | awk -F: '{print $10}'`
-        for i in ${(f)_addrs}; do
-            _parsed=`print "From: $i" | ${WORKDIR}/bin/fetchaddr -a -x from`
-            _e="${_parsed[(ws:,:)1]}"
-            isemail "$_e"
-            [[ $? = 0 ]] || continue
-            # check if the email is not already parsed
-            [[ "${result[$_e]}" = "" ]] && {
-                _n="${_parsed[(ws:,:)2]}"
-                result+=("$_e" "$_n")
-                print - "$_n <$_e>"
-            }
-        done
-        
-        notice "Unique addresses found: ${#result}"
-        # counts which addresses are known to us
-        _known=0
-        for i in ${(k)result}; do
-            lookup_email ${i}
-            [[ $? = 0 ]] || {
-                _known=$(( $_known + 1 )) }
-        done
-        act "new addresses: $_known"
-        return 0
-    }
-    
+    func "extract from search query"
+    # args are simply strings, then run a search and extract addresses
+    nm_search ${=PARAM}
+    extract_maildir "$MAILDIRS"/cache/notmuch/results all
 }
 
 
diff --git a/src/zlibs/email b/src/zlibs/email
@@ -168,6 +168,9 @@ fetch() {
         return 1
     }
 
+    # updates the notmuch configuration
+    nm_setup
+
     notice "Fetching email for account ${account}"
 
     is_online ${imap} ${imap_port}
@@ -506,12 +509,3 @@ EOF
     return $?
 }
 
-later() {
-    func "Saving message from stdin into remember"
-    filename=$USER.${hostname}.$datestamp.$RANDOM
-    # hostname was set by the main jaro routine
-    func "Filename: $filename"
-
-    { maildircheck "${MAILDIRS}/remember" } || { maildirmake "${MAILDIRS}/remember" }
-    cat > "${MAILDIRS}/remember/new/$filename"
-}
diff --git a/src/zlibs/filters b/src/zlibs/filters
@@ -457,6 +457,7 @@ EOF
 
 }
 
+    
 # sieve_filter() gets an array of patterns to match and builds a long rule
 # for which if they match the conditional directive they all go in one folder
 # $1 = conditional directive
diff --git a/src/zlibs/maildirs b/src/zlibs/maildirs
@@ -87,30 +87,6 @@ list_maildirs() {
     return ${#maildirs}
 }
 
-maildirs_lastlog() {
-    # returns an array of destinations maildirs touched by the last filtering operation
-    # based on the procmail log format
-    typeset -alU dests prio lasts
-    _folders=`cat "${MAILDIRS}/logs/procmail.log"|awk '/Folder:/ {print $2}' | cut -d/ -f1`
-    for d in ${(f)_folders}; do
-    func "maildir touched by last operation: $d"
-    # skip procmail glitch
-    { test "$d" = "procmail" } && { continue }
-    # put filtered to last
-    [[ ${PARAM} == *${d}* ]] && { lasts=($lasts $d); continue }
-    # always give priority to known, then to priv, then the rest
-    { test "$d" = "known" } && { prio=(known $prio); continue }
-    { test "$d" = "priv" } && { prio=($prio priv); continue }
-    # skip zz. trash
-    [[ $d == zz.* ]] && { continue }
-    # put them to filter
-        dests+=($d)
-    done
-    print "${=prio} ${=dests} ${=lasts}"
-    unset dests
-    unset prio
-    unset lasts
-}
 
 rmdupes() {
 
@@ -236,34 +212,29 @@ merge() {
 # so that fetchmail does not deletes mail from server
 deliver() {
     if [ "$1" = "" ]; then
-    dest="$MAILDIRS/incoming"
+        dest="$MAILDIRS/incoming"
     else
-    dest="$MAILDIRS/$1"
-    { test -d "$dest" } || { dest="$1"
-        { test -d "$dest" } || {
-        error "delivery destination path invalid: $1"
-        return 1; } }
+        dest="$MAILDIRS/$1"
+        { test -d "$dest" } || { dest="$1"
+            { test -d "$dest" } || {
+                error "delivery destination path invalid: $1"
+                return 1
+            }
+        }
     fi
-
+    
     # create destination maildir if not existing
     [[ -r "$dest" ]] || {
         act "creating destination maildir: $dest"
-        maildirmake "$dest" }
+        maildirmake "$dest"
+    }
 
     maildircheck "$dest"
     [[ $? = 0 ]] || {
         error "Invalid maildir destination for delivery, operation aborted."
         func "Returning error to caller."
-        return 1; }
-
-    base="`hostname`_jaro_`date +%Y-%m-%d_%H-%M-%S`_$RANDOM"
-
-    cat > "$dest/new/$base"
-    [[ $? = 0 ]] || {
-        error "Could not write email file into maildir, operation aborted."
-        func "Returning error to caller."
-    return 1; }
-
+        return 1
+    }
 
     [[ $DEBUG = 0 ]] || {
         func "Delivery successful, log: $MAILDIRS/logs/jaro-deliver.log"
@@ -273,6 +244,60 @@ BEGIN { print "Delivery to maildir: '"$1"'" }
 /^$/ { exit }
 ' "$MAILDIRS/$1/new/$base" >> "$MAILDIRS/logs/jaro-deliver.log"
     }
+    
+    # destinations excluded from notmuch indexing
+    [[ "$dest" = "outbox" ]] \
+        || [[ "$dest" =~ "^zz." ]] \
+        || [[ "$dest" = "incoming" ]] && {
+        
+        base="`hostname`_jaro_`date +%Y-%m-%d_%H-%M-%S`_$RANDOM"
+        
+        cat > "$dest/new/$base"
+        [[ $? = 0 ]] || {
+            error "Could not write email file into maildir $dest."
+            func "Returning error to caller."
+            return 1
+        }
+        return 0
+    }
 
+    #########
+    # notmuch indexing from here
+    NOTMUCH_CONFIG="$MAILDIRS"/cache/notmuch/rc
+
+    # tag +inbox
+    [[ "$dest" = "known" ]] \
+        || [[ "$dest" = "priv" ]] \
+        || [[ "$dest" = "sent" ]] && {
+
+        cat | notmuch-insert --folder="$dest" +inbox
+        [[ $? = 0 ]] || {
+            error "Could not write email file into maildir $dest using notmuch-insert."
+            func "Returning error to caller."
+            return 1
+        }
+        return 0
+    }
+
+    # tag +unsorted
+    [[ "$dest" = "unsorted" ]] \
+        || [[ "$dest" =~ "^lists." ]] && {
+
+        cat | notmuch-insert --folder="$dest" +unsorted
+        [[ $? = 0 ]] || {
+            error "Could not write email file into maildir $dest using notmuch-insert."
+            func "Returning error to caller."
+            return 1
+        }
+        return 0
+    }
+
+    # anything else +filters
+    cat | notmuch-insert --folder="$dest" +filters
+    [[ $? = 0 ]] || {
+        error "Could not write email file into maildir $dest using notmuch-insert."
+        func "Returning error to caller."
+        return 1
+    }
     return 0
 }
diff --git a/src/zlibs/search b/src/zlibs/search
@@ -22,108 +22,114 @@
 
 #######################
 ## Search into maildirs
-# using mairix
-search() {
-    # check if the name of a maildir is among params
-    # we need at least 2 maildirs, the second is the destination
-    typeset -al fold
-    typeset -al term
-    # intelligent parse of args, position independent
-    # check if its a folder, if not is an expression
-    for p in ${PARAM}; do
-	if [ -r ${p} ]; then
-	    { maildircheck ${p} } && {
-		func "param ${p} is a maildir"
-		fold+=(${p}) }
-	elif  [ -r "${MAILDIRS}/${p}" ]; then
-	    { maildircheck ${MAILDIRS}/${p} } && {
-		func "param ${p} is a jaro maildir"
-		fold+=(${MAILDIRS}/${p}) }
-	else
-	    func "param ${p} is a search term"
-	    term+=(${p})
-	fi
+# using notmuch
+
+nm_dir="$MAILDIRS"/cache/notmuch
+
+nm_setup() {
+    mkdir -p "$nm_dir"
+
+    # read if there are other email aliases configured
+    [[ -r "$MAILDIRS"/Aliases.txt ]] && {
+        other_email="other_email"
+        _aliases=`cat "$MAILDIRS"/Aliases.txt`
+        _sep=\=
+        for i in ${(f)_aliases}; do
+            other_email+="${_sep}${i}"
+            _sep=";"
+        done
+    }
+
+    rm -f "$nm_dir"/rc
+    cat <<EOF > "$nm_dir"/rc
+[database]
+path=$MAILDIRS
+
+[user]
+name=$name
+primary_email=$email
+$other_email
+
+[new]
+tags=unread
+ignore=zz.;log;cache;Accounts;Groups;.mutt;webnomad;.abook;.txt;.pdf;.html;.png;.js
+
+[maildir]
+synchronize_flags=true
+EOF
+}
+
+nm_index() {
+    read_account
+    nm_setup
+    func "notmuch --config=${nm_dir}/rc new"
+
+    notmuch --config="${nm_dir}/rc" new
+}
+
+nm_search() {
+    read_account
+    nm_setup
+    
+    notice "Searching emails for: $=PARAM"
+    local search_results
+    func "notmuch --config=${nm_dir}/rc search --output=files ${=PARAM}"
+
+    # launch the search with notmuch
+    search_results=`notmuch --config="${nm_dir}/rc" search --output=files ${=PARAM}`
+    act "`print ${search_results} | wc -l` results found"
+    [[ $? = 0 ]] || {
+        error "notmuch search failed with an error"
+        return 1 }
+
+    # populate the maildir with results
+    _resdir="${nm_dir}/results"
+    func "notmuch results in $_resdir"
+    rm -rf "$_resdir"
+    act "populating a maildir with results"
+    maildirmake $_resdir
+    for i in ${(f)search_results}; do
+        ln -s $i "$_resdir/new/`basename $i`"
     done
-    # now fold is an array of specified folders
-    # term is an array of specified search expressions
+}
 
-    { test "${#term}" = "0" } && {
-	error "No search terms specified."
-	act "Parameters: ${PARAM}"
-	return 1
+search() {
+    
+    [[ "$PARAM" = "" ]] && {
+	    error "No search terms specified."
+	    return 1
     }
-
-    # no folders specified, search into the addressbook
-    { test "${#fold}" = "0" } && {
+    
+    typeset -al term
 	typeset -alU results
-	notice "Searching addressbook for: ${PARAM}"
-	res=""
-
-	for t in ${term}; do
-	    res+=`search_addressbook ${t}`
-	done
-
-	for rr in ${(f)res}; do
-	    _email=`print $rr | awk '{ print $1 }'`
-	    _name=`print $rr | awk '{ for(c=2;c<=NF;c++) printf "%s ", $c }'`
-	    results+=("$_name <$_email>")
-	done
-
-	{ test "${#results}" = "0" } || {
-	    act "${#results} matches found:"
-	    for i in ${results}; do
-		print "$i"; done
-	    return 0
-	}
-	notice "No matches found."
-	return 1
+    
+    for p in ${PARAM}; do
+        func "param ${p} is a search term"
+        term+=(${p})
+    done
+    
+    [[ "$PARAM" =~ "addr" ]] && {
+        # if addr specified search into the addressbook
+	    notice "Searching addressbook for: ${PARAM//addr/}"
+	    res=""
+	    for t in ${term}; do
+            [[ "$t" =~ "addr" ]] && continue
+            # res+=`search_addressbook ${t}`
+	        search_addressbook ${t} | awk '
+/^$/ { next }
+{ for(c=2;c<=NF;c++) printf "%s ", $c
+  print "<" $1 ">" }'
+	    done
+        return 0
     }
     
-    # base path is the dir of the first folder
-    pushd `dirname ${fold[1]}`
-    basedir=`pwd`
-    popd
-
-    notice "Searching ${#fold} folders in $basedir for: ${term}"
-    { command -v mairix > /dev/null } || {
-	error "Mairix not found, operation aborted."
-	return 1 }
-    act "Searching through: ${fold}"
-    act "Please wait..."
-    id=$datestamp.$RANDOM
-    rc=$TMPDIR/search.conf.$id
-    # forge the folder string for mairix conf
-    folders=""; for f in ${fold}; do folders="$folders`basename $f`:"; done
-    cat <<EOF > $rc
-base=$basedir
-database=$TMPDIR/search.db.$id
-maildir=${folders}
-mfolder=$TMPDIR/search.result.$id
-mformat=maildir
-EOF
-    { test $DEBUG = 1 } && {
-	func "Mairix conf (debug output)"
-	cat $rc }
-
-    exitcode=0
-    { test "$DRYRUN" = "1" } || {
-	exitcode=1
-	mairix -F -f $rc 2>/dev/null
-	{ test $? = 0 } && {
-	    found=`mairix -F -f $rc ${=term} 2> /dev/null | awk '{ print $2}'`
-	    if [ "$found" = "0" ]; then
-		error "No matches found."
-	    else
-		${=mutt} -F $MUTTDIR/rc -R -f $TMPDIR/search.result.$id
-		notice "Found $found matches looking for '$term' in $folders"
-		exitcode=0
-	    fi
-	}
-    } # DRYRUN
-    ${=rm} $TMPDIR/search.db.$id
-    ${=rm} $TMPDIR/search.conf.$id
-    ${=rm} -r $TMPDIR/search.result.$id
-    return $exitcode
+    # run search across emails
+    nm_search ${=PARAM}
+    
+    # open the results maildir
+    ${=mutt} -F "$MUTTDIR"/rc ${=muttflags} \
+        -f "$MAILDIRS"/cache/notmuch/results
+    
 }
 
 backup() {