Re: [PATCH] cli: add a tool for starting new message in the emacs ui

Subject: Re: [PATCH] cli: add a tool for starting new message in the emacs ui

Date: Fri, 04 Jul 2014 20:36:38 +0300

To: David Bremner, notmuch@notmuchmail.org, Jani Nikula

Cc:

From: Tomi Ollila


On Tue, Jul 01 2014, David Bremner <david@tethera.net> wrote:

> From: Jani Nikula <jani@nikula.org>
>
> Add a tool to start composing an email in the Notmuch Emacs UI with
> the specified subject, recipients, and message body.
> ---
>
> I added the necessary lines to conf.py to get the man pages built and
> installed
>
> I'd be happier with this if it could start emacs. I tried adding "-a
> ''" to the emacsclient invokation, but that doesn't quite work; the
> message-mode buffer is created in emacs but no frame is displayed. It
> could be a peculiarity of my emacs setup, of course.

Ah, this -a '' is new acquaintance to me -- I tried -a emacs and that
obviously did not work. It would have been nicer is there is option
to just run emacs instead... (that's what I did in that mailto: patch).

But there are plenty of other options, which needs at least be discussed,
is some tolerable subset can be agreed.

First, this will "fail"

$ emacs --daemon
$ emacsclient --eval '(progn (require 'notmuch) (notmuch-hello))'

The window is "nowhere"

$ emacsclient -nw can be used to "attach" to the emacs session and then one
can switch to the ``notmuch-hello`` -window

-- but, someone may use such a supported setup using emacs/emacsclient

This "problem" could be tacled so that if emasclient is to be used,
option (to be added) ``-nw`` is not given and stdout (or stderr) is 
a tty (test -t 1 / test -t 2), after running emacsclient print
a message to the output with content something like:

"connected to running emacs ... if the access to that emacs is hidden
 you can run ``emacsclient -nw`` to find it..."

Ok. Using emacsclient could be opportunistic -- in case using it fails
emacs(1) were used instead. The code checking this could be (*):

  unset ALTERNATE_EDITOR
  if "${EMACSCLIENT:=emacsclient}" --eval t >/dev/null 2>&1
  then	exec >/dev/null # (ok, use stderr for msg, or change this :D)
 	editor=$EMACSCLIENT
  else	editor=${EMACS:-emacs}
  fi

(*) to save my time, copied from id:1404237992-9456-1-git-send-email-tomi.ollila@iki.fi

When running emacs there is question whether to run it in background or
foreground. Probably the only always working option is to run in foreground
(unless adding an option) -- backgrounding would be possible only when all
of these apply:
   1) user did not give ``-nw`` option
   2) DISPLAY is not null or unset
   3) emacs(1) does have X support!

3 cannot be determined trivially.

If backgrounding were supported the only way I see it can be done is:

bg () {
   perl -e 'use POSIX; exit if fork; POSIX::setsid(); exec @ARGV' "$@"
}

Ok, then about the tool:

>  doc/conf.py                    |   4 ++
>  doc/man1/notmuch-emacs-mua.rst |  50 +++++++++++++++++
>  notmuch-emacs-mua              | 122 +++++++++++++++++++++++++++++++++++++++++
>  3 files changed, 176 insertions(+)
>  create mode 100644 doc/man1/notmuch-emacs-mua.rst
>  create mode 100755 notmuch-emacs-mua
>
> diff --git a/doc/conf.py b/doc/conf.py
> index 70ba1b8..8ee19f4 100644
> --- a/doc/conf.py
> +++ b/doc/conf.py
> @@ -74,6 +74,10 @@ man_pages = [
>          u'creates a plain-text dump of the tags of each message',
>          [u'Carl Worth and many others'], 1),
>  
> +('man1/notmuch-emacs-mua','notmuch-emacs-mua',
> +        u'send mail with notmuch and emacs',
> +        [u'Carl Worth and many others'], 1),
> +
>  ('man5/notmuch-hooks','notmuch-hooks',
>          u'hooks for notmuch',
>          [u'Carl Worth and many others'], 5),
> diff --git a/doc/man1/notmuch-emacs-mua.rst b/doc/man1/notmuch-emacs-mua.rst
> new file mode 100644
> index 0000000..6e63818
> --- /dev/null
> +++ b/doc/man1/notmuch-emacs-mua.rst
> @@ -0,0 +1,50 @@
> +=================
> +notmuch-emacs-mua
> +=================
> +
> +SYNOPSIS
> +========
> +
> +**notmuch-emacs-mua** [options ...] [<to-address> ...]
> +
> +DESCRIPTION
> +===========
> +
> +Start composing an email in the Notmuch Emacs UI with the specified
> +subject, recipients, and message body.
> +
> +For **notmuch-emacs-mua** to work, you need **emacsclient** and an
> +already running Emacs with a server.
> +
> +Supported options for **notmuch-emacs-mua** include
> +
> +    ``-h, --help``
> +        Display help.
> +
> +    ``-s, --subject=``\ <subject>
> +        Specify the subject of the message.
> +
> +    ``--to=``\ <to-address>
> +        Specify a recipient (To).
> +
> +    ``-c, --cc=``\ <cc-address>
> +        Specify a carbon-copy (Cc) recipient.
> +
> +    ``-b, --bcc=``\ <bcc-address>
> +        Specify a blind-carbon-copy (Bcc) recipient.
> +
> +    ``-i, --body=``\ <file>
> +        Specify a file to include into the body of the message.

-i option is consistent with mutt(1). mutt(1) does not have --body option.
therefore I'd suggest that --body takes the body content from command line
instead from file. If there is to be long-option along with -i it could
be --include or --insert..

> +
> +    ``--print``
> +        Output the resulting elisp to stdout instead of evaluating it.
> +
> +The supported positional parameters and short options are a compatible
> +subset of the **mutt** MUA command-line options.
> +
> +Options may be specified multiple times.
> +
> +SEE ALSO
> +========
> +
> +**notmuch(1)**, **emacsclient(1)**, **mutt(1)**
> diff --git a/notmuch-emacs-mua b/notmuch-emacs-mua
> new file mode 100755
> index 0000000..7f94271
> --- /dev/null
> +++ b/notmuch-emacs-mua
> @@ -0,0 +1,122 @@
> +#!/usr/bin/env bash
> +#
> +# notmuch-emacs-mua - start composing a mail on the command line
> +#
> +# Copyright © 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 <jani@nikula.org>
> +#
> +
> +set -eu
> +
> +escape ()
> +{
> +    echo "${1//\"/\\\"}"
> +}

This has 3 issues:

  1) This does not quote '\' which can be used to execute arbitrary code
     (is that a feature)
  2) echo may escape things differently in other bashes
  3) running subshell just to this escape all args is not required,
     there are bash builtins to do that during same process.

If one wants to use function, escape -v var arg syntax could be deviced
with

escape () {
       local var=${3//\"/\\\"}; var=${var//\\/\\\\}
       eval $2=\$var
}

> +PRINT_ONLY=
> +


Tomi

Thread: