From a570474ee72605aed4553a5ac095c2aa6e2a4828 Mon Sep 17 00:00:00 2001 From: Tomi Ollila Date: Sat, 1 Nov 2014 10:51:51 +0200 Subject: [PATCH] Re: [DRAFT PATCH] modified notmuch-emacs-mua --- 32/e103d0c3cb44c9059d4bbca59edb8e76b0378b | 407 ++++++++++++++++++++++ 1 file changed, 407 insertions(+) create mode 100644 32/e103d0c3cb44c9059d4bbca59edb8e76b0378b diff --git a/32/e103d0c3cb44c9059d4bbca59edb8e76b0378b b/32/e103d0c3cb44c9059d4bbca59edb8e76b0378b new file mode 100644 index 000000000..8e8c611b2 --- /dev/null +++ b/32/e103d0c3cb44c9059d4bbca59edb8e76b0378b @@ -0,0 +1,407 @@ +Return-Path: +X-Original-To: notmuch@notmuchmail.org +Delivered-To: notmuch@notmuchmail.org +Received: from localhost (localhost [127.0.0.1]) + by olra.theworths.org (Postfix) with ESMTP id BCF75431FD0 + for ; Sat, 1 Nov 2014 01:52:20 -0700 (PDT) +X-Virus-Scanned: Debian amavisd-new at olra.theworths.org +X-Spam-Flag: NO +X-Spam-Score: 0 +X-Spam-Level: +X-Spam-Status: No, score=0 tagged_above=-999 required=5 tests=[none] + autolearn=disabled +Received: from olra.theworths.org ([127.0.0.1]) + by localhost (olra.theworths.org [127.0.0.1]) (amavisd-new, port 10024) + with ESMTP id eRUxqBiQPMvb for ; + Sat, 1 Nov 2014 01:52:12 -0700 (PDT) +Received: from guru.guru-group.fi (guru.guru-group.fi [46.183.73.34]) + by olra.theworths.org (Postfix) with ESMTP id 7B978431FAF + for ; Sat, 1 Nov 2014 01:52:12 -0700 (PDT) +Received: from guru.guru-group.fi (localhost [IPv6:::1]) + by guru.guru-group.fi (Postfix) with ESMTP id 547961000E0; + Sat, 1 Nov 2014 10:51:51 +0200 (EET) +From: Tomi Ollila +To: Jani Nikula , notmuch@notmuchmail.org, david@tethera.net, + jrollins@finestructure.net +Subject: Re: [DRAFT PATCH] modified notmuch-emacs-mua +In-Reply-To: <871tpq1vn4.fsf@nikula.org> +References: <1405026779-29966-1-git-send-email-tomi.ollila@iki.fi> + <871tpq1vn4.fsf@nikula.org> +User-Agent: Notmuch/0.18.1+130~ga61922f (http://notmuchmail.org) Emacs/24.3.1 + (x86_64-unknown-linux-gnu) +X-Face: HhBM'cA~ +MIME-Version: 1.0 +Content-Type: text/plain; charset=utf-8 +Content-Transfer-Encoding: quoted-printable +X-BeenThere: notmuch@notmuchmail.org +X-Mailman-Version: 2.1.13 +Precedence: list +List-Id: "Use and development of the notmuch mail system." + +List-Unsubscribe: , + +List-Archive: +List-Post: +List-Help: +List-Subscribe: , + +X-List-Received-Date: Sat, 01 Nov 2014 08:52:20 -0000 + +On Wed, Oct 29 2014, Jani Nikula wrote: + +Thanks for quick response.=20 + +There are only one (and half) thing that needs to be resolved before +first inclusion, the desire for more versatile options can be discussed +later... + +> On Fri, 11 Jul 2014, Tomi Ollila wrote: +>> Highlights: +>> +>> * notmuch-emacs-mua without arguments runs (notmuch-hello) +>> +>> * runs emacs(1) in case emacsclient(1) fails to connect to running emacs +>> +>> * takes -nw option +>> +>> * handles mailto: +>> +>> * --from option when sending non-mailto: way +>> +>> * -i includes file --body[=3D ]string inserts string +>> --- +>> notmuch-emacs-mua | 200 +++++++++++++++++++++++++++++++++++++++++++++++= ++++++++ +>> 1 file changed, 200 insertions(+) +>> create mode 100755 notmuch-emacs-mua +>> +>> diff --git a/notmuch-emacs-mua b/notmuch-emacs-mua +>> new file mode 100755 +>> index 0000000..b1696f7 +>> --- /dev/null +>> +++ b/notmuch-emacs-mua +>> @@ -0,0 +1,200 @@ +>> +#!/usr/bin/env bash +>> +# -*- mode: shell-script; sh-basic-offset: 4; tab-width: 8 -*- +>> +# +>> +# notmuch-emacs-mua - start composing a mail on the command line +>> +# +>> +# Copyright =C2=A9 2014 Jani Nikula +>> +# +>> +# This program is free software: you can redistribute it and/or modify +>> +# it under the terms of the GNU General Public License as published by +>> +# the Free Software Foundation, either version 3 of the License, or +>> +# (at your option) any later version. +>> +# +>> +# This program is distributed in the hope that it will be useful, +>> +# but WITHOUT ANY WARRANTY; without even the implied warranty of +>> +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +>> +# GNU General Public License for more details. +>> +# +>> +# You should have received a copy of the GNU General Public License +>> +# along with this program. If not, see http://www.gnu.org/licenses/ . +>> +# +>> +# Authors: Jani Nikula +>> +# Tomi Ollila +>> +# +>> + +>> +set -eu +>> + +>> +# "expand" '\' to '\\' & '"' to '\"' +>> +escape_optarg () +>> +{ +>> + OPTARG=3D${OPTARG//\\/\\\\}; OPTARG=3D${OPTARG//\"/\\\"} +>> +} +>> + +>> +# ditto, in case there is '\n' sequence in the source, otherwise +>> +# "expand" only trailing '\'s to '\\'s +>> +escape_body_optarg () +>> +{ +>> + case ${OPTARG} in +>> + *'\"'*) OPTARG=3D${OPTARG//\\/\\\\} ;; +>> + *'\') OPTARG=3D$( printf %s "${OPTARG}" | sed 's/\(\\*\)$/\1\1/' ) +>> + esac +>> + OPTARG=3D${OPTARG//\"/\\\"} +>> +} +>> + +>> +unset ALTERNATE_EDITOR +>> +exec_mua () +>> +{ +>> + if "${EMACSCLIENT:=3Demacsclient}" --eval t >/dev/null 2>&1 +>> + then +>> + emacs=3D$EMACSCLIENT +>> + # close stdout in case no -nw (and no --print) +>> + test -n "$W$X" || exec >/dev/null +>> + else +>> + emacs=3D${EMACS:-emacs} +>> + fi +>> + ${X:-exec} "$emacs" $W --eval "$*" +>> + exit +>> + ${X:-exec "$emacs" $W --eval} "$*" +>> +} +>> + +>> +X=3D +>> +W=3D +>> + +>> +SUBJECT=3D TO=3D CC=3D BCC=3D BODY=3D FROM=3D IB=3D +>> + +>> +while +>> + # first, handle "long" options which cannot be handled by getopts +>> + case ${1-} in +>> + -nw) +>> + W=3D-nw +>> + shift +>> + continue +>> + ;; +> +> How about generalizing this into letting the user pass arguments after a +> "--" separator to emacs(client)? Would that work? + +That would technically work and be very easy to do. I don't know whether +this is good option -- and such can be added later if decided. + +> Alternatively, why support -nw which is neither part of the mutt +> interface I was originally aiming at emulating nor conforms to notmuch +> style? Just go with --nw or the more verbose --no-window-system (which +> is also compatible with emacs). + +The original mutt interface is there -- as this is notmuch-*emacs*-mua +this could also have the original emacs -nw option (--nw came later, and +is supported by the loop). + +But, what is the option is not important, as long as there is at least one +emacs-compatible option to have this feature (--nw). (for now, Let's see +whether I get irritated that notmuch-emacs-mua -nw does not work -- as I +still have ESC g bound to goto-line as I cannot get used to ESC g g ;) + +>> + mailto:*) +>> + oIFS=3D$IFS; IFS=3D; OPTARG=3D"$*" IFS=3D$oIFS +>> + escape_optarg +>> + exec_mua "(progn (require 'notmuch) (browse-url-mail \"$OPTARG\"))" +>> + exit +>> + esac +> +> Why does mailto: need to be handled here? I think you could either make +> the usage have a special mailto: case where you only have mailto: at $1, +> or you handle mailto: as a positional parameter at the end. + +To handle this here is probably a slip as i started using notmuch-emacs-mua +as a drop-in replacement from notmuch-emacs-mailto (where I added +possibility to do -nw). + +I agree that it is better to just check first arg for mailto: prefix +and if matches, work accordingly.=20 + +> With these, you could drop this one extra case here, and go back to the +> more natural "while getopts" argument parsing loop. + +I agree to convert to "while getopts" loop which *apparently* feels more +natural to most of the developers ;D + +>> + +>> + getopts :s:c:b:i:h opt +>> +do +>> + # Handle errors and long options. +>> + case ${opt} in +>> + :) +>> + echo "$0: short option '-${OPTARG}' requires an argument." >&2 +>> + exit 1 +>> + ;; +>> + \?) +>> + opt=3D$1 +>> + if [[ ${OPTARG} !=3D '-' ]]; then +>> + echo "$0: unknown short option '-${OPTARG}'." >&2 +>> + exit 1 +>> + fi +>> + +>> + case ${opt} in +>> + # Long options with arguments. +>> + --subject=3D*|--to=3D*|--cc=3D*|--bcc=3D*|--body=3D*|--from=3D*) +>> + OPTARG=3D${opt#--*=3D} +>> + opt=3D${opt%%=3D*} +>> + ;; +>> + # Long options with argument in next arg. +>> + --subject |--to |--cc |--bcc |--body |--from ) +> +> This may be git-ish, but I don't think we should support this in +> notmuch. + +This is also emacs-ish, tar-ish, whatnot-ish (with notable exception of +google-chrome).=20 + +But we can go with only supporting --longarg=3Dval option now, and bikeshed +that more if anyone wants to -- From some reason when command starts with +'notmuch' I tend to write =3D to separate long option with arg (and have +always done so with this script when not testing), although SPC is easier +to press that shift-0 (which produces '=3D' on finnish keyboard ;) + +>> + if [[ $# < 2 ]]; then +>> + echo "$0: option '${opt}' requires an argument." >&2 +>> + exit 1 +>> + fi +>> + OPTARG=3D$2 +>> + OPTIND=3D$((OPTIND + 1)) +>> + ;; +>> + # Long options without arguments. +>> + --help|--nw|--print) +>> + ;; +>> + *) +>> + echo "$0: unknown long option '${opt}', or argument mismatch." >&2 +>> + exit 1 +>> + ;; +>> + esac +>> + # getopts does not do this for what it considers errors. +>> + OPTIND=3D$((OPTIND + 1)) +>> + ;; +>> + esac +>> + +>> + case ${opt} in +>> + --help|h) +>> + exec man notmuch-emacs-mua +>> + ;; +>> + --from) +>> + escape_optarg +>> + FROM=3D${OPTARG} +>> + ;; +>> + --subject|s) +>> + escape_optarg +>> + SUBJECT=3D${SUBJECT:+$SUBJECT }${OPTARG} +>> + ;; +>> + --to) +>> + escape_optarg +>> + TO=3D${TO:+$TO, }${OPTARG} +>> + ;; +>> + --cc|c) +>> + escape_optarg +>> + CC=3D${CC:+$CC, }${OPTARG} +>> + ;; +>> + --bcc|b) +>> + escape_optarg +>> + BCC=3D${BCC:+$BCC, }${OPTARG} +>> + ;; +>> + i) +>> + escape_optarg +>> + if [[ ! -f ${OPTARG} ]]; then +>> + echo "$0: '${OPTARG}': no such file" >&2 +>> + exit 1 +>> + fi +>> + IB=3D${IB}$'\n'" (insert-file \"${OPTARG}\")" +> +> This needs the (cd \"${PWD}\") bit because --body given here may be +> relative to the script, while emacs likely has a totally different cwd. + +Yes, the drop of that was accidental and not intentional. We could also +escape $PWD too, in case user does: + +mkdir '.")(shell-command "/bin/rm -rf ~'; cd ... + +although that is probably not accidental... well have to think for +cases user's PWD contains just one '"' for some reason.. + +>> + IB=3D${IB}$'\n'" (if /=3D (point) (line-beginning-position) (inse= +rt \"\\n\"))" +>> + ;; +>> + --body) +>> + escape_body_optarg +>> + IB=3D${IB}$'\n'" (insert \"${OPTARG}\\n\")" +> +> Why should --body and -i be different? + +Now, this is the one that is important to get decided now! + +The -i is different from other options as it loads a file to be added to +the mail buffer, when all other options put the option value to the buffer. +an analogous option to that would IMO be --insert (or --include).=20 + +Also, I desire an option to write mail content lines from command line +option directly. To me --body (which is not mutt(1) option) to work +as adding the variable to mail buffer is more consistent with the other +options -- and we could add this --insert as long option to -i. + +Anyway, whatever the option to be able to insert body content from command +line is desired -- if there is any better choice :) + +I also think that s/escape_body_optarg/escape_optarg/ (and dropping=20 +escape_body_optarg) should be done. escape_body_optarg would have +left e.g. "\n"s there and let emacs add newlines there. But this is +some hidden emacs-specific magic and might not be compatible with +e.g. notmuch-vim-mua (provided that someone(tm) will write such an utility). + +>> + ;; +>> + --nw) +>> + W=3D-nw + +I could change this to W=3D--nw :) + +>> + ;; +>> + --print) +>> + X=3Decho +>> + ;; +>> + *) +>> + # We should never end up here. +>> + echo "$0: internal error (option '${opt}')." >&2 +>> + exit 1 +>> + ;; +>> + esac +>> + +>> + shift $((OPTIND - 1)) +>> + OPTIND=3D1 +>> +done +>> + +>> +# Positional parameters. +>> +for arg; do +>> + arg=3D${arg//\\/\\\\}; arg=3D${arg//\"/\\\"} +>> + TO=3D${TO:+$TO, }${arg} +>> +done +>> + +>> +NL=3D$'\n' +>> +ELISP=3D"\ +>> +${CC:+$NL (message-goto-cc) (insert \"$CC\")}\ +>> +${BCC:+$NL (message-goto-bcc) (insert \"$BCC\")}\ +>> +${IB:+$NL (message-goto-body)$IB}" +>> + +>> +if [[ $TO =3D=3D '' && $SUBJECT =3D=3D '' && $ELISP =3D=3D '' ]] +>> +then +>> + exec_mua "(progn (require 'notmuch) (notmuch-hello))" +>> +else +>> + [[ $FROM !=3D '' ]] && OH=3D"(list (cons 'From \"$FROM\"))" || OH= +=3Dnil +>> + [[ $TO !=3D '' ]] && TO=3D\"$TO\" || TO=3Dnil +>> + [[ $SUBJECT !=3D '' ]] && SUBJECT=3D\"$SUBJECT\" || SUBJECT=3Dnil +>> + exec_mua "$NL(progn (require 'notmuch) +>> + (notmuch-mua-mail $TO $SUBJECT +>> + $OH nil (notmuch-mua-get-switch-function))\ +>> +$ELISP$NL (set-buffer-modified-p nil) (message-goto-to))" +> +> I think the newlines with $NL hurt readability in the script more than +> they help readability in the output... which is generally interpreted by +> emacs which doesn't really care about the newlines! ;) + +This is half thing left to be decided now. The $NL:s make --print -output +(very!) pretty.=20 + +I can make $NL be empty in case --print is not given -- and and another +variable to contain 0/2 spaces depending on --print value to make emacs +and human viewer happy... >;) + +I personally don't think those 4 $NL:s make the readability of the script +much worse -- but I can turn those to ${NL}:s if that help. It seems +your original code uses those more and I have not -- not because of a +style issue but because I am just so accustomed to do so... That said +I take more care of those in future versions... + +> +> BR, +> Jani. + +Tomi + +> +> +>> +fi +>> --=20 +>> 1.9.0 -- 2.26.2