feat: tag manipulation

This commit is contained in:
2026-03-12 18:17:03 +01:00
parent 1453fdb3ad
commit 8a0c8bc2d7
5 changed files with 99 additions and 5 deletions

View File

@@ -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)

View File

@@ -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

View File

@@ -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"
}

View File

@@ -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)
}