[PATCH] notmuch-emacs-mua: more options, some fixes
authorTomi Ollila <tomi.ollila@iki.fi>
Sat, 7 Mar 2015 10:36:45 +0000 (12:36 +0200)
committerW. Trevor King <wking@tremily.us>
Sat, 20 Aug 2016 21:48:18 +0000 (14:48 -0700)
48/c1e542a175bf201ac0257a3e49fad15326a810 [new file with mode: 0644]

diff --git a/48/c1e542a175bf201ac0257a3e49fad15326a810 b/48/c1e542a175bf201ac0257a3e49fad15326a810
new file mode 100644 (file)
index 0000000..068a3ef
--- /dev/null
@@ -0,0 +1,324 @@
+Return-Path: <too@guru-group.fi>\r
+X-Original-To: notmuch@notmuchmail.org\r
+Delivered-To: notmuch@notmuchmail.org\r
+Received: from localhost (localhost [127.0.0.1])\r
+       by olra.theworths.org (Postfix) with ESMTP id 119C6431FBC\r
+       for <notmuch@notmuchmail.org>; Sat,  7 Mar 2015 02:37:21 -0800 (PST)\r
+X-Virus-Scanned: Debian amavisd-new at olra.theworths.org\r
+X-Spam-Flag: NO\r
+X-Spam-Score: 2.438\r
+X-Spam-Level: **\r
+X-Spam-Status: No, score=2.438 tagged_above=-999 required=5\r
+       tests=[DNS_FROM_AHBL_RHSBL=2.438] autolearn=disabled\r
+Received: from olra.theworths.org ([127.0.0.1])\r
+       by localhost (olra.theworths.org [127.0.0.1]) (amavisd-new, port 10024)\r
+       with ESMTP id BFXoDf4rNSqF for <notmuch@notmuchmail.org>;\r
+       Sat,  7 Mar 2015 02:37:15 -0800 (PST)\r
+Received: from guru.guru-group.fi (guru.guru-group.fi [46.183.73.34])\r
+       by olra.theworths.org (Postfix) with ESMTP id 91162431FAE\r
+       for <notmuch@notmuchmail.org>; Sat,  7 Mar 2015 02:37:15 -0800 (PST)\r
+Received: by guru.guru-group.fi (Postfix, from userid 501)\r
+       id 6DC5C100293; Sat,  7 Mar 2015 12:36:49 +0200 (EET)\r
+From: Tomi Ollila <tomi.ollila@iki.fi>\r
+To: notmuch@notmuchmail.org\r
+Subject: [PATCH] notmuch-emacs-mua: more options, some fixes\r
+Date: Sat,  7 Mar 2015 12:36:45 +0200\r
+Message-Id: <1425724605-392-1-git-send-email-tomi.ollila@iki.fi>\r
+X-Mailer: git-send-email 2.0.0\r
+Cc: tomi.ollila@iki.fi\r
+X-BeenThere: notmuch@notmuchmail.org\r
+X-Mailman-Version: 2.1.13\r
+Precedence: list\r
+List-Id: "Use and development of the notmuch mail system."\r
+       <notmuch.notmuchmail.org>\r
+List-Unsubscribe: <http://notmuchmail.org/mailman/options/notmuch>,\r
+       <mailto:notmuch-request@notmuchmail.org?subject=unsubscribe>\r
+List-Archive: <http://notmuchmail.org/pipermail/notmuch>\r
+List-Post: <mailto:notmuch@notmuchmail.org>\r
+List-Help: <mailto:notmuch-request@notmuchmail.org?subject=help>\r
+List-Subscribe: <http://notmuchmail.org/mailman/listinfo/notmuch>,\r
+       <mailto:notmuch-request@notmuchmail.org?subject=subscribe>\r
+X-List-Received-Date: Sat, 07 Mar 2015 10:37:22 -0000\r
+\r
+Two new options added:\r
+   --from: specify alternate From: header\r
+   --bodytext: possibility to give body content from command line\r
+\r
+Non-forking escape() functionality, also escaping \ (backslash) characters.\r
+\r
+Without content arguments start emacs/emacsclient and run (notmuch-hello),\r
+in this case without assigning anything to message-exit-actions.\r
+\r
+Point is now positioned at the end of the content given last on command\r
+line, unless to: or subject: is missing -- in which case point is\r
+positioned at one of these headers (is both missing, at to:)\r
+\r
+The -nw option is now given to emacs in case --no-window-system command\r
+line option is provided (--no-window-system used to work with emacsclient\r
+only).\r
+\r
+In case EMACS or EMACSCLIENT environment variable was defined but being\r
+empty (null string), use emacs/emacsclient as command instead (null string\r
+as executable name gives confusing error message). Also $EMACS/$EMACSCLIENT\r
+executable name is now quoted to *NOT* split it to separate command line\r
+arguments on any $IFS variables there might be.\r
+\r
+Reorganized content argument handling to combine the content of same option\r
+given multiple times and make it look more readable when --print option is\r
+used. --body option also now checks the existence of the file to be\r
+included and if the file included does not end with newline trailing\r
+newline is inserted to the message buffer.\r
+\r
+As bash supports [[ ]] command and it's special expansion (or lack thereof)\r
+of variables (and ==, && and || inside) the few [ ]'s there were are now\r
+changed to this more advanced format.\r
+---\r
+\r
+The changes *NOT* taken from my 2 draft patches (*)\r
+\r
+1) no -nw hacking\r
+\r
+2) no mailto: handling\r
+\r
+(*) id:1421776424-24304-1-git-send-email-tomi.ollila@iki.fi (later, linking\r
+previous)\r
+\r
+\r
+ doc/man1/notmuch-emacs-mua.rst |   8 ++-\r
+ notmuch-emacs-mua              | 123 ++++++++++++++++++++++++++++++-----------\r
+ 2 files changed, 99 insertions(+), 32 deletions(-)\r
+\r
+diff --git a/doc/man1/notmuch-emacs-mua.rst b/doc/man1/notmuch-emacs-mua.rst\r
+index eb47098..29f7e0c 100644\r
+--- a/doc/man1/notmuch-emacs-mua.rst\r
++++ b/doc/man1/notmuch-emacs-mua.rst\r
+@@ -22,6 +22,9 @@ Supported options for **notmuch-emacs-mua** include\r
+         Use emacsclient, rather than emacs. This will start\r
+         an emacs daemon process if necessary.\r
\r
++    ``--from=``\ <from>\r
++        Specify alternate sender (From) of the message.\r
++\r
+     ``-s, --subject=``\ <subject>\r
+         Specify the subject of the message.\r
\r
+@@ -37,6 +40,9 @@ Supported options for **notmuch-emacs-mua** include\r
+     ``-i, --body=``\ <file>\r
+         Specify a file to include into the body of the message.\r
\r
++    ``--bodytext=``\ <text>\r
++        Specify text content to be inserted into the body of the message.\r
++\r
+     ``--no-window-system``\r
+         Even if a window system is available, use the current terminal\r
\r
+@@ -60,4 +66,4 @@ Name of emacsclient comment to invoke\r
+ SEE ALSO\r
+ ========\r
\r
+-**notmuch(1)**, **emacsclient(1)**, **mutt(1)**\r
++**notmuch(1)**, **emacs(1)**, **emacsclient(1)**, **mutt(1)**\r
+diff --git a/notmuch-emacs-mua b/notmuch-emacs-mua\r
+index b8cbc82..17365b9 100755\r
+--- a/notmuch-emacs-mua\r
++++ b/notmuch-emacs-mua\r
+@@ -1,4 +1,5 @@\r
+ #!/usr/bin/env bash\r
++# -*- mode: shell-script; sh-basic-offset: 4; tab-width: 8 -*-\r
+ #\r
+ # notmuch-emacs-mua - start composing a mail on the command line\r
+ #\r
+@@ -18,25 +19,47 @@\r
+ # along with this program.  If not, see http://www.gnu.org/licenses/ .\r
+ #\r
+ # Authors: Jani Nikula <jani@nikula.org>\r
++#          Tomi Ollila <tomi.ollila@iki.fi>\r
+ #\r
\r
+ set -eu\r
\r
++# escape: "expand" '\' to '\\' & '"' to '\"'\r
++# Calling convention: escape -v var "$arg" (like in bash printf).\r
+ escape ()\r
+ {\r
+-    echo "${1//\"/\\\"}"\r
++    local arg=${3//\\/\\\\}\r
++    eval $2='${arg//\"/\\\"}'\r
+ }\r
\r
+-EMACS=${EMACS-emacs}\r
+-EMACSCLIENT=${EMACSCLIENT-emacsclient}\r
++EMACS=${EMACS:-emacs}\r
++EMACSCLIENT=${EMACSCLIENT:-emacsclient}\r
\r
+ PRINT_ONLY=\r
+ USE_EMACSCLIENT=\r
+-CLIENT_TYPE="-c"\r
++EMACSCLIENT_TYPE='-c'\r
++EMACS_NW=\r
\r
+-# The crux of it all: construct an elisp progn and eval it.\r
+-ELISP="(prog1 'done (require 'notmuch) (notmuch-mua-new-mail)"\r
+-ELISP="${ELISP} (setq message-exit-actions (list #'save-buffers-kill-terminal))"\r
++exec_mua ()\r
++{\r
++    if [[ -n $PRINT_ONLY ]]; then\r
++      echo "$1"\r
++      exit\r
++    fi\r
++\r
++    if [[ -n $USE_EMACSCLIENT ]]; then\r
++      # Evaluate the progn.\r
++      exec "${EMACSCLIENT}" ${EMACSCLIENT_TYPE} -a '' --eval "$1"\r
++    else\r
++      exec "${EMACS}" ${EMACS_NW} --eval "$1"\r
++    fi\r
++    exit not reached\r
++}\r
++\r
++SUBJECT= TO= CC= BCC= BODY= FROM=\r
++\r
++unset message_goto # Final elisp function to execute, when defined.\r
++cddone=false\r
\r
+ while getopts :s:c:b:i:hC opt; do\r
+     # Handle errors and long options.\r
+@@ -47,14 +70,14 @@ while getopts :s:c:b:i:hC opt; do\r
+           ;;\r
+       \?)\r
+           opt=$1\r
+-          if [ "${OPTARG}" != "-" ]; then\r
++          if [[ ${OPTARG} != '-' ]]; then\r
+               echo "$0: unknown short option -${OPTARG}." >&2\r
+               exit 1\r
+           fi\r
\r
+           case "${opt}" in\r
+               # Long options with arguments.\r
+-              --subject=*|--to=*|--cc=*|--bcc=*|--body=*)\r
++              --subject=*|--to=*|--cc=*|--bcc=*|--body=*|--from=*|--bodytext=*)\r
+                   OPTARG=${opt#--*=}\r
+                   opt=${opt%%=*}\r
+                   ;;\r
+@@ -71,9 +94,7 @@ while getopts :s:c:b:i:hC opt; do\r
+           ;;\r
+     esac\r
\r
+-\r
+-    OPTARG="${OPTARG-none}"\r
+-    OPTARG="$(escape "${OPTARG}")"\r
++    escape -v OPTARG "${OPTARG-}"\r
\r
+     case "${opt}" in\r
+       --help|h)\r
+@@ -82,26 +103,48 @@ while getopts :s:c:b:i:hC opt; do\r
+       --client|C)\r
+           USE_EMACSCLIENT="yes"\r
+           ;;\r
++      --from)\r
++          FROM=${OPTARG}\r
++          ;;\r
+       --subject|s)\r
+-          ELISP="${ELISP} (message-goto-subject) (insert \"${OPTARG}\")"\r
++          SUBJECT=${SUBJECT:+$SUBJECT }${OPTARG}\r
++          message_goto='(message-goto-subject)'\r
+           ;;\r
+       --to)\r
+-          ELISP="${ELISP} (message-goto-to) (insert \"${OPTARG}, \")"\r
++          TO=${TO:+$TO, }${OPTARG}\r
++          message_goto='(message-goto-to)'\r
+           ;;\r
+       --cc|c)\r
+-          ELISP="${ELISP} (message-goto-cc) (insert \"${OPTARG}, \")"\r
++          CC=${CC:+$CC, }${OPTARG}\r
++          message_goto='(message-goto-cc)'\r
+           ;;\r
+       --bcc|b)\r
+-          ELISP="${ELISP} (message-goto-bcc) (insert \"${OPTARG}, \")"\r
++          BCC=${BCC:+$BCC, }${OPTARG}\r
++          message_goto='(message-goto-bcc)'\r
+           ;;\r
+       --body|i)\r
+-          ELISP="${ELISP} (message-goto-body) (cd \"${PWD}\") (insert-file \"${OPTARG}\")"\r
++          if [[ ! -f ${OPTARG} ]]; then\r
++              echo "$0: '${OPTARG}': no such file" >&2\r
++              exit 1\r
++          fi\r
++          if [[ $cddone == 'false' ]]; then\r
++              BODY=${BODY}$'\n'"  (cd \"${PWD}\")"\r
++              cddone=true\r
++          fi\r
++          BODY=${BODY}$'\n'"  (insert-file \"${OPTARG}\")"\r
++          BODY=${BODY}$'\n'"  (if (/= (point) (line-beginning-position)) (insert \"\\n\"))"\r
++          unset message_goto\r
++          ;;\r
++      --bodytext)\r
++          BODY=${BODY}$'\n'"  (insert \"${OPTARG}\\n\")"\r
++          unset message_goto\r
+           ;;\r
+       --print)\r
+           PRINT_ONLY=1\r
+           ;;\r
+       --no-window-system)\r
+-          CLIENT_TYPE="-t"\r
++          EMACSCLIENT_TYPE='-t'\r
++          EMACS_NW='-nw'\r
+           ;;\r
+       *)\r
+           # We should never end up here.\r
+@@ -116,21 +159,39 @@ done\r
\r
+ # Positional parameters.\r
+ for arg; do\r
+-    arg="$(escape "${arg}")"\r
+-    ELISP="${ELISP} (message-goto-to) (insert \"${arg}, \")"\r
++    escape -v _arg "${arg}"\r
++    TO=${TO:+$TO, }${_arg}\r
++    message_goto='(message-goto-to)'\r
+ done\r
\r
+-# End progn.\r
+-ELISP="${ELISP})"\r
++# The newlines are here for better user experience when --print option is used.\r
++NL=$'\n'\r
++ELISP="\\r
++${CC:+$NL  (message-goto-cc) (insert \"$CC\")}\\r
++${BCC:+$NL  (message-goto-bcc) (insert \"$BCC\")}\\r
++${BODY:+$NL  (message-goto-body)$BODY}"\r
\r
+-if [ -n "$PRINT_ONLY" ]; then\r
+-    echo ${ELISP}\r
+-    exit 0\r
+-fi\r
+-\r
+-if [ -n "$USE_EMACSCLIENT" ]; then\r
+-    # Evaluate the progn.\r
+-    exec ${EMACSCLIENT} ${CLIENT_TYPE} -a '' --eval "${ELISP}"\r
++if [[ $TO == '' && $SUBJECT == '' && $ELISP == '' ]]\r
++then\r
++    exec_mua "(prog1 'done (require 'notmuch) (notmuch-hello))"\r
+ else\r
+-    exec ${EMACS} --eval "${ELISP}"\r
++    [[ $FROM != '' ]] && OH="(list (cons 'From \"$FROM\"))" || OH=nil\r
++\r
++    if [[ $SUBJECT == '' ]]; then\r
++      SUBJECT=nil\r
++      message_goto='(message-goto-subject)'\r
++    else\r
++      SUBJECT=\"$SUBJECT\"\r
++    fi\r
++    if [[ $TO == '' ]]; then\r
++      TO=nil\r
++      message_goto='(message-goto-to)'\r
++    else\r
++      TO=\"$TO\"\r
++    fi\r
++    exec_mua "(prog1 'done (require 'notmuch)\r
++  (setq message-exit-actions (list #'save-buffers-kill-terminal))\r
++  (notmuch-mua-mail ${TO} ${SUBJECT}\r
++      ${OH} nil (notmuch-mua-get-switch-function))\\r
++${ELISP}${NL}  (set-buffer-modified-p nil)${message_goto+ $message_goto})"\r
+ fi\r
+-- \r
+2.1.0\r
+\r