diff --git a/.gitignore b/.gitignore index e3dde46..de83983 100644 --- a/.gitignore +++ b/.gitignore @@ -1 +1,2 @@ nmf +.tags diff --git a/src/main.sh b/src/main.sh index 647c3c7..f72baa6 100755 --- a/src/main.sh +++ b/src/main.sh @@ -29,6 +29,20 @@ set -eu # preview functions . "sh/preview.sh" +if [ "${1:-}" = "--list-threads" ]; then + shift + nmquery="$1" + list_threads "$nmquery" + exit +fi + +if [ "${1:-}" = "--list-messages-in-thread" ]; then + shift + thread="$1" + list_messages_in_thread "$thread" + exit +fi + if [ "${1:-}" = "--preview-thread" ]; then shift threadid="$1" @@ -116,6 +130,58 @@ if [ "${1:-}" = "--open-part" ]; then exit fi +if [ "${1:-}" = "--archive" ]; then + shift + [ "$1" = "thread" ] && thread=1 + shift + [ "${thread:-}" ] && field="thread" || field="id" + query="$(echo "$@" | sed "s/\s\(\S\)/ $field:\1/g" | sed "s/^/$field:/")" + nm_tag "-inbox" "$query" + nm_tag "-unread" "$query" + exit +fi + +if [ "${1:-}" = "--delete" ]; then + shift + [ "$1" = "thread" ] && thread=1 + shift + [ "${thread:-}" ] && field="thread" || field="id" + query="$(echo "$@" | sed "s/\s\(\S\)/ $field:\1/g" | sed "s/^/$field:/")" + nm_tag "-inbox" "$query" + nm_tag "+del" "$query" + exit +fi + +if [ "${1:-}" = "--tag-modify" ]; then + shift + [ "$1" = "thread" ] && thread=1 + shift + [ "$1" = "add" ] && sign=+ || sign=- + shift + [ "${thread:-}" ] && field="thread" || field="id" + query="$(echo "$@" | sed "s/\s\(\S\)/ $field:\1/g" | sed "s/^/$field:/")" + if [ "$sign" = "+" ]; then + tagquery="" + label_text="Add tag" + else + tagquery="$query" + label_text="Remove tag" + fi + res=$(list_tags "$tagquery" | $FZF \ + --color="border:$ANSICOLORTAGS" \ + --color="label:$ANSICOLORTAGS" \ + --tac \ + --bind='ctrl-d:half-page-down,ctrl-u:half-page-up' \ + --margin='20%' \ + --bind='enter:accept-or-print-query' \ + --border=double \ + --border-label=" $label_text " || true) + [ "$res" ] || exit + nm_tag "$sign$res" "$query" + exit +fi + + if [ "${1:-}" = "--show-thread" ]; then shift thread="$1" @@ -125,6 +191,7 @@ if [ "${1:-}" = "--show-thread" ]; then --multi \ --delimiter="$(printf '\t')" \ --with-nth="$FZF_DEFAULT_THREAD_LINE" \ + --bind="ctrl-r:reload:$0 --list-messages-in-thread \"$thread\"" \ --bind="alt-s:change-with-nth({1} {2} {3} ({4})|$FZF_DEFAULT_THREAD_LINE)" \ --accept-nth=5 \ --bind='alt-j:preview-down,alt-k:preview-up' \ @@ -135,6 +202,10 @@ if [ "${1:-}" = "--show-thread" ]; then --bind="alt-/:change-preview-window($FZF_ALTERNATE_PREVIEW_WINDOW|$FZF_DEFAULT_PREVIEW_WINDOW)" \ --bind="alt-v:execute:$0 --view-source {5}" \ --bind="alt-h:change-preview:$0 --preview-html-message {5}" \ + --bind="alt-+:execute($0 --tag-modify message add {+5})+reload:$0 --list-messages-in-thread \"$thread\"" \ + --bind="alt--:execute($0 --tag-modify message del {+5})+reload:$0 --list-messages-in-thread \"$thread\"" \ + --bind="alt-enter:execute($0 --archive message {+4})+reload:$0 --list-messages-in-thread \"$thread\"" \ + --bind="alt-delete:execute($0 --delete message {+4})+reload:$0 --list-messages-in-thread \"$thread\"" \ --bind="focus:change-preview($0 --preview-message {5})+transform-footer:printf '\033[4mMesssage parts\033[0m\n';$0 --show-message-parts {5}" \ --bind="ctrl-o:execute:$0 --open-part {5}" \ --preview="$0 --preview-message {5}" \ @@ -155,12 +226,14 @@ while true; do nmquery="${nmquery:-tag:inbox}" [ "$(tail -1 "$NMFHIST")" = "$nmquery" ] || echo "$nmquery" >> "$NMFHIST" cmd=$(list_threads "$nmquery" | $FZF \ + --header-first \ --header="Query: $nmquery" \ --tiebreak=index \ --reverse \ --multi \ --delimiter="$(printf '\t')" \ --with-nth="{1} {2} ({3})" \ + --bind="ctrl-r:reload:$0 --list-threads \"$nmquery\"" \ --bind="alt-t:print($CMD_SEARCH_TAG$NWSRCH)+accept" \ --bind="alt-T:print($CMD_SEARCH_TAG$APPEND)+accept" \ --bind="alt-s:print($CMD_SEARCH_ADDRESS$ADDRESS_FROM$NWSRCH)+accept" \ @@ -171,9 +244,13 @@ while true; do --bind='alt-j:preview-down,alt-k:preview-up' \ --bind='ctrl-d:half-page-down,ctrl-u:half-page-up' \ --bind='page-up:preview-half-page-up,page-down:preview-half-page-down' \ - --bind="enter,ctrl-l:execute:$0 --show-thread {4}" \ + --bind="enter,ctrl-l:execute($0 --show-thread {4})+reload:$0 --list-threads \"$nmquery\"" \ --bind="alt-/:change-preview-window($FZF_ALTERNATE_PREVIEW_WINDOW|$FZF_DEFAULT_PREVIEW_WINDOW)" \ --bind="alt-h:change-preview:$0 --preview-html-thread {4}" \ + --bind="alt-+:execute($0 --tag-modify thread add {+4})+reload:$0 --list-threads \"$nmquery\"" \ + --bind="alt--:execute($0 --tag-modify thread del {+4})+reload:$0 --list-threads \"$nmquery\"" \ + --bind="alt-enter:execute($0 --archive thread {+4})+reload:$0 --list-threads \"$nmquery\"" \ + --bind="alt-delete:execute($0 --delete thread {+4})+reload:$0 --list-threads \"$nmquery\"" \ --bind="focus:change-preview:$0 --preview-thread {4}" \ --preview="$0 --preview-thread {4}" \ --preview-window="$FZF_DEFAULT_PREVIEW_WINDOW" | head -1 || true) diff --git a/src/sh/lists.sh b/src/sh/lists.sh index 57bcb64..899fb40 100644 --- a/src/sh/lists.sh +++ b/src/sh/lists.sh @@ -16,9 +16,12 @@ list_threads() { | column -s "$(printf '\t')" -t -l 3 -R 1,2 } -# List all available tags +# List all tags of matching entries. If not query is provided, all tags are +# listed. +# @argument $1: query (optional) list_tags() { - $NOTMUCH search --output=tags tag:/./ + [ "${1:-}" ] && query="$1" || query="tag:/./" + $NOTMUCH search --output=tags "$query" } # List all email addresses diff --git a/src/sh/notmuch.sh b/src/sh/notmuch.sh index 55568af..9323e19 100644 --- a/src/sh/notmuch.sh +++ b/src/sh/notmuch.sh @@ -3,7 +3,8 @@ # Print the message id of the last message within a thread. # @argument $1: thread id nm_last_message_in_thread() { - $NOTMUCH search --output=messages --offset=-1 thread:"$1" | sed 's/^...//' + # TODO: We may be smarter here that just incorporating excluded messages + $NOTMUCH search --output=messages --offset=-1 --exclude=false thread:"$1" | sed 's/^...//' } # Print the header of a message (with trailing empty line) @@ -31,3 +32,10 @@ nm_message_part_nr() { nm_message_get_part() { $NOTMUCH show --part="$2" id:"$1" } + +# Add/remove a tag +# @argument $1: [+/-]tag +# @argument $2: query +nm_tag() { + $NOTMUCH tag "$1" "$2" +} diff --git a/src/sh/preview.sh b/src/sh/preview.sh index 8fd29ee..2c1ddeb 100644 --- a/src/sh/preview.sh +++ b/src/sh/preview.sh @@ -11,11 +11,16 @@ # @argument #3: if set, then the HTML messages will be taken preview_message() { [ "$1" = "id" ] && messageid="$2" || messageid="$(nm_last_message_in_thread "$2")" + echo "preview_message: messageid=$messageid" >> /tmp/foo parts="$(nm_message_parts "$messageid")" + echo "preview_message: parts=$parts" >> /tmp/foo html="${3:-}" + echo "preview_message: html=$html" >> /tmp/foo nr="$(nm_message_part_nr "$messageid" "$html")" + echo "preview_message: nr=$nr" >> /tmp/foo [ ! "$nr" ] && [ ! "$html" ] && html="html" && nr="$(nm_message_part_nr "$messageid" "html")" + echo "preview_message: nr=$nr" >> /tmp/foo [ "$html" ] && parser="$PANDOC" || parser="cat" nm_message_header "$messageid" | $CATEMAIL - nm_message_get_part "$messageid" "$nr" | $parser | $CATMD + [ "$nr" ] && (nm_message_get_part "$messageid" "$nr" | $parser | $CATMD) }