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 2DD90431FC2 for ; Wed, 29 Oct 2014 13:14:20 -0700 (PDT) X-Virus-Scanned: Debian amavisd-new at olra.theworths.org X-Spam-Flag: NO X-Spam-Score: -0.7 X-Spam-Level: X-Spam-Status: No, score=-0.7 tagged_above=-999 required=5 tests=[RCVD_IN_DNSWL_LOW=-0.7] 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 S-lI3oQpt4J5 for ; Wed, 29 Oct 2014 13:14:12 -0700 (PDT) Received: from mail-wi0-f175.google.com (mail-wi0-f175.google.com [209.85.212.175]) (using TLSv1 with cipher RC4-SHA (128/128 bits)) (No client certificate requested) by olra.theworths.org (Postfix) with ESMTPS id 02B06431FC7 for ; Wed, 29 Oct 2014 13:14:11 -0700 (PDT) Received: by mail-wi0-f175.google.com with SMTP id ex7so2741219wid.14 for ; Wed, 29 Oct 2014 13:14:10 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20130820; h=x-gm-message-state:from:to:cc:subject:in-reply-to:references :user-agent:date:message-id:mime-version:content-type :content-transfer-encoding; bh=3Ybmdmgr6oQVtB19jfX+kqNCZvOl5SFva54kFW337fc=; b=jVUK5WGYdXkNRL4R4W+Gak4oicDLULmAfgP11YqIvUIzxZJEkZBrE7R/C4ZwpGGyJa LIfkhPQW6UjlsCgbsfogaW5Boc14P/RbbAPWkcSp+D2QY/sE0jkysFHNMKvhpFVP2o71 C0WKvHldyXS63Pcdsi8G37jYOM5Mi2Ouw9jlIhps1i9Kv+2Jo3KK+RYzJ/4FXMJojm8z whDoO2ZF2iReDS6/pbojQDwOjPzRHiIoiTWiMX2xm9KbpsOV6G9JrLLnaaZQO7uRi2y0 C+iLQkQ3y1S09/RDeE0qsxoYxnrIBvgwcog3YmHEcr5/dtdjo/FYZp3NDtlKy7lzBhUA NX8Q== X-Gm-Message-State: ALoCoQmMljJY+DG6IC0DZITT+P91K+Xse2ujXMo2Sx8T9I126KWRB6QSoCEJxDvAJF1Vxoe+ViiK X-Received: by 10.180.79.38 with SMTP id g6mr14813444wix.42.1414613650477; Wed, 29 Oct 2014 13:14:10 -0700 (PDT) Received: from localhost (dsl-hkibrasgw2-58c36d-48.dhcp.inet.fi. [88.195.109.48]) by mx.google.com with ESMTPSA id ko10sm6274874wjb.48.2014.10.29.13.14.09 for (version=TLSv1.2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Wed, 29 Oct 2014 13:14:09 -0700 (PDT) From: Jani Nikula To: Tomi Ollila , notmuch@notmuchmail.org, david@tethera.net, jrollins@finestructure.net Subject: Re: [DRAFT PATCH] modified notmuch-emacs-mua In-Reply-To: <1405026779-29966-1-git-send-email-tomi.ollila@iki.fi> References: <1405026779-29966-1-git-send-email-tomi.ollila@iki.fi> User-Agent: Notmuch/0.18.2+148~g4214adf (http://notmuchmail.org) Emacs/24.3.1 (x86_64-pc-linux-gnu) Date: Wed, 29 Oct 2014 22:14:07 +0200 Message-ID: <871tpq1vn4.fsf@nikula.org> MIME-Version: 1.0 Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: quoted-printable Cc: tomi.ollila@iki.fi 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: Wed, 29 Oct 2014 20:14:20 -0000 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? 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). > + 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. With these, you could drop this one extra case here, and go back to the more natural "while getopts" argument parsing loop. > + > + 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. > + 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. > + IB=3D${IB}$'\n'" (if /=3D (point) (line-beginning-position) (inser= t \"\\n\"))" > + ;; > + --body) > + escape_body_optarg > + IB=3D${IB}$'\n'" (insert \"${OPTARG}\\n\")" Why should --body and -i be different? > + ;; > + --nw) > + 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=3D= nil > + [[ $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! ;) BR, Jani. > +fi > --=20 > 1.9.0