From 1564aa81763602adfdc408da9aa5a36986cb99bc Mon Sep 17 00:00:00 2001 From: Marty Oehme Date: Thu, 17 Sep 2020 12:02:42 +0200 Subject: [PATCH] mail: Add fzfmail script `fzfmail` allows searching, previewing, displaying and tagging mail through the fzf interface. --- mail/.config/sh/alias.d/fzfmail.sh | 79 ++++++++++++++++++++++++++++++ 1 file changed, 79 insertions(+) create mode 100644 mail/.config/sh/alias.d/fzfmail.sh diff --git a/mail/.config/sh/alias.d/fzfmail.sh b/mail/.config/sh/alias.d/fzfmail.sh new file mode 100644 index 0000000..7e55433 --- /dev/null +++ b/mail/.config/sh/alias.d/fzfmail.sh @@ -0,0 +1,79 @@ +#!/usr/bin/env sh +# Fzf searching notmuch email database + +# Search with notmuch queries +# You can either invoke: +# `fzfmail` -> and then interactively create a notmuch query (not fuzzy searching) +# or: +# `fzfmail [notmuchquery]` -> pre-craft a query and then use fzf to filter it further, e.g. +# fzfmail tag:archived and subject:Important and not tag:flagged +# +# select as many mails as you wish (ctrl-a for all current results) +# preview mails with ? +# +# read with +# re-tag with + +if exist fzf; then + # Allow fuzzy search filtering of a notmuch search query + fzfmail() { + # shellcheck disable=2016 # we only want the expression to expand when fzf preview is actually called not by the shell + if [ -z "$1" ]; then + # interactive query + fzfmail_mails=$( + printf " +\nStart a notmuch search query:\n" | + fzf --multi \ + --header "tag: | from: | to: | subject: | folder: | date: || and | not | or | near | adj || read | tag" \ + --bind "change:reload:notmuch search {q} || true" \ + --bind "ctrl-a:toggle-all" \ + --bind '?:toggle-preview' \ + --expect 'ctrl-t,esc' \ + --preview='notmuch show --part=1 $(echo {} | cut -d" " -f1)' \ + --preview-window hidden \ + --phony | + cut -d" " -f1 + ) + else + # pre-queried fuzzy search + fzfmail_mails=$( + notmuch search "$*" | + fzf --multi \ + --header " read | tag" \ + --bind "ctrl-a:toggle-all" \ + --bind '?:toggle-preview' \ + --expect 'ctrl-t,esc' \ + --preview='notmuch show --part=1 $(echo {} | cut -d" " -f1)' \ + --preview-window hidden | + cut -d" " -f1 + ) + fi + + # find out expected action + fzfmail_action=$(echo "$fzfmail_mails" | head -n1) + # quit on esc pressed -- do not do anything with selected results + if echo "$fzfmail_action" | grep -qe 'esc'; then return 0; fi + + # get the selected mails + fzfmail_mails=$(echo "$fzfmail_mails" | tail -n+2) + + # tag mails + if echo "$fzfmail_action" | grep -qe 'ctrl-t'; then + printf "current tags: %s\n" "$(notmuch search --output=tags "$fzfmail_mails" | tr '\n' ' ')" + printf "add tags with +tag; remove with -tag\n" + printf "apply tags: " + read -r fzfmail_tags + notmuch tag "$fzfmail_tags" -- "$fzfmail_mails" + return 0 + fi + + # display the mails, in semi-readable format + # highlight subject line in color + # allow moving through results with n/p + notmuch show "$fzfmail_mails" | sed -e 's/^\fmessage{.*$/MESSAGE:/' -e '/^\f[a-z]/d' -e 's/^Subject:/\o033[41mSubject:\o033[0m/' | less --pattern '^MESSAGE:$' -R + + unset fzfmail_mails + unset fzfmail_action + unset fzfmail_tags + } +fi