Initial commit - anmhi - nmh(7) interface that (ab)uses less, lesskey, tmux and entr (HTM) hg clone https://bitbucket.org/iamleot/anmhi (DIR) Log (DIR) Files (DIR) Refs (DIR) README --- (DIR) changeset 4ad0db62498dd4b842a995ba1c6ffddfc1cf66ac (HTM) Author: Leonardo Taccari <iamleot@gmail.com> Date: Tue, 3 Jul 2018 01:32:55 Initial commit Diffstat: README | 20 +++++ TODO | 10 ++ anmhi | 226 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ anmhi-scan | 67 ++++++++++++++++++ tanmhi | 37 +++++++++ 5 files changed, 360 insertions(+), 0 deletions(-) --- diff -r 000000000000 -r 4ad0db62498d README --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/README Tue Jul 03 01:32:55 2018 +0200 @@ -0,0 +1,20 @@ +anmhi is an interface to nmh(7) that (ab)uses less, lesskey, tmux +and entr. + +From a tmux session it can be simply invoked via tanmhi: + + % tanmhi + +tanmhi will split the current window in two panes: + - top pane: anmhi-scan + - bottom pane: anmhi + +anmhi-scan print via scan(1) an handle of previous, current and +next emails in the current folder. + +anmhi is used to perform several actions to the nmh messages/folders +by (ab)using less and lesskey. For a list of them please directly +read the source code. + +anmhi was inspired by ml written by paul fox. It is intended to be +simpler and avoid to define any custom sequence diff -r 000000000000 -r 4ad0db62498d TODO --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/TODO Tue Jul 03 01:32:55 2018 +0200 @@ -0,0 +1,10 @@ +anmhi +----- +- Honors possible all-uppercase environment variables to set the + lower-case ones locally used by anmhi +- Parametrize in variable the :-100 and :100 used in + and `L' action. +- Make the `fzy' dependency configurable via a variable (e.g. `dmenu' + can be used instead.) +- When marking a sequence interactively, reuse rlwrap - if available - + with the current sequences as history. diff -r 000000000000 -r 4ad0db62498d anmhi --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/anmhi Tue Jul 03 01:32:55 2018 +0200 @@ -0,0 +1,226 @@ +#!/bin/sh + +# +# Copyright (c) 2018 Leonardo Taccari +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# +# 1. Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# 2. Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in the +# documentation and/or other materials provided with the distribution. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED +# TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS +# BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +# POSSIBILITY OF SUCH DAMAGE. +# + + +anmhi_lesskey="$(mhpath +)/.lesskey" +anmhi_mark_sequence="marked" +anmhi_unseen_sequence="$(mhparam unseen-sequence)" +anmhi_scan_format='%<(cur)>%| %>%6(msg) %<(mymbox{from})%<{to}To: %13(unquote(decode(friendly{to})))%>%>%<(zero)%17(unquote(decode(friendly{from})))%> %3(day{date}) %3(month{date}) %02(mday{date}) %02(hour{date}):%02(min{date}) %(decode{subject})' +anmhi_lines=$(stty size | cut -d ' ' -f 1) + + +# +# Parse and do the next action. +# +anmhi_action() +{ + local a r + + a=$(printf "$(printf '\\%o' "$1")") + + case "${a}" in + C) + # Compose a message + comp ; show cur | anmhi_pager + r=$? + ;; + F) + # Fix current message + mhfixmsg ; show cur | anmhi_pager + r=$? + ;; + L) + # Select a message interactively + m="$(scan -format "${anmhi_scan_format}" cur:-100 cur:100 | + anmhi_menu | awk '/> / { print $2; next } { print $1 }')" + if [ "${m}" ]; then + show "${m}" | anmhi_pager + else + show cur | anmhi_pager + fi + r=$? + ;; + M) + # Mark current message with ${anmhi_mark_sequence} + mark -sequence "${anmhi_mark_sequence}" ; show cur | anmhi_pager + r=$? + ;; + N) + # Go to the next folder with unread messages + fnext ; show cur | anmhi_pager + r=$? + ;; + P) + # Go to the previous folder with unread messages + fprev ; show cur | anmhi_pager + r=$? + ;; + R) + # Reply (-nogroup) + repl -nogroup + show cur | anmhi_pager + r=$? + ;; + T) + # Mark a message interactively asking for a sequence + read sequence + if [ "${sequence}" ]; then + mark -sequence "${sequence}" + fi + show cur | anmhi_pager + r=$? + ;; + U) + # Show all unseen messages + unseen | anmhi_pager + r=$? + ;; + a) + # Mark all messages in the current folder as read + mark -sequence "${anmhi_unseen_sequence}" \ + -delete "${anmhi_unseen_sequence}" + show last | anmhi_pager + r=$? + ;; + c) + # Show the current message + show cur | anmhi_pager + r=$? + ;; + f) + # Select a folder interactively + f="$(folders -fast | anmhi_menu)" + + if [ "${f}" ]; then + folder -nocreate +"${f}" + fi + show cur | anmhi_pager + r=$? + ;; + n) + # Show the next message + { next || show cur ; } | anmhi_pager + r=$? + ;; + p) + # Show the previous message + { prev || show cur ; } | anmhi_pager + r=$? + ;; + u) + # Show all unseen messages in the current folder + scan unseen | anmhi_pager + r=$? + ;; + r) + # Reply (-group) + repl -group + show cur | anmhi_pager + r=$? + ;; + esac + + return ${r} +} + +# +# Generate a lesskey(1) file. +# +anmhi_lesskey() +{ + + if [ ! -f "${anmhi_lesskey}" ]; then + lesskey -o "${anmhi_lesskey}" - <<EOF + C quit C + F quit F + L quit L + M quit M + R quit R + T quit T + U quit U + ^n quit N + ^p quit P + \en quit n + \ep quit p + \kr quit n + \kl quit p + } quit n + { quit p + a quit a + c quit c + f quit f + h quit p + l quit n + r quit r + q quit +EOF + fi +} + +# +# Invoke text selector menu with the desidered options. +# +anmhi_menu() +{ + + fzy -l "${anmhi_lines}" +} + +# +# Invoke the PAGER with the desidered options. +# +anmhi_pager() +{ + + less -c -k "${anmhi_lesskey}" + return $? +} + + +# +# anmhi, a nmh(7) interface. anmhi is a simple interface to various nmh(7) +# tools to interactively manage emails with a PAGER. +# +main() +{ + anmhi_lesskey + + if [ $# -gt 0 ]; then + args="$@" + fi + + show $args | anmhi_pager + r=$? + + until anmhi_action ${r}; do + r=$? + done +} + +main $@ diff -r 000000000000 -r 4ad0db62498d anmhi-scan --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/anmhi-scan Tue Jul 03 01:32:55 2018 +0200 @@ -0,0 +1,67 @@ +#!/bin/sh + +# +# Copyright (c) 2018 Leonardo Taccari +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# +# 1. Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# 2. Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in the +# documentation and/or other materials provided with the distribution. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED +# TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS +# BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +# POSSIBILITY OF SUCH DAMAGE. +# + + +anmhi_scan_lines=$(stty size | cut -d ' ' -f 1) +anmhi_scan_context="$(mhpath +)/$(mhparam context)" +anmhi_scan_format="\ +%<(cur)%<(zputlit(underline))%>%>\ +%<(unseen)%<(zputlit(bold))%>%>\ +%<{status} %|N%>\ +%<{replied}R%?{encrypted}E%| %>\ +%6(msg) \ +%<(mymbox{from})%<{to}To: %13(unquote(decode(friendly{to})))%>%>\ +%<(zero)%17(unquote(decode(friendly{from})))%> \ +%3(day{date}) %3(month{date}) %02(mday{date}) \ +%02(hour{date}):%02(min{date}) \ +%(decode{subject})%(zputlit(resetterm))" + + +# +# Monitor context and mh-sequences files and continuosly update the screen when +# they change. +# +ls "${anmhi_scan_context}" "$(mhpath +)"/*/"$(mhparam mh-sequences)" | \ +entr -c sh -c \ +' + # Print current folder and (unread/total) messages + flist | awk \ + '"'"' + { + sub(/\+$/, "", $1); + printf("\033[1m%s (%d/%d)\033[0m\n", $1, $3, $9); + } + '"'"' + + # Print "current" emails + scan -format '"\"${anmhi_scan_format}\""' \ + cur:-$(('"${anmhi_scan_lines}"' / 2)) \ + cur:$(('"${anmhi_scan_lines}"' / 2 - 1)) +' \ +"anmhi-scan" /_ diff -r 000000000000 -r 4ad0db62498d tanmhi --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tanmhi Tue Jul 03 01:32:55 2018 +0200 @@ -0,0 +1,37 @@ +#!/bin/sh + +# +# Copyright (c) 2018 Leonardo Taccari +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# +# 1. Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# 2. Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in the +# documentation and/or other materials provided with the distribution. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED +# TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS +# BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +# POSSIBILITY OF SUCH DAMAGE. +# + + +# +# Split current tmux window and run `anmhi-scan' on the top and `anmhi' on the +# rest of the window. +# +tmux split-window -bd -t:.0 -v -l 10 "anmhi-scan ; $SHELL" +tmux rename-window 'mail' +exec anmhi