unofficial mirror of notmuch@notmuchmail.org
 help / color / mirror / code / Atom feed
* [PATCH] cli: add a tool for starting new message in the emacs ui
@ 2014-03-19 19:25 Jani Nikula
  2014-03-19 21:24 ` Tomi Ollila
  0 siblings, 1 reply; 17+ messages in thread
From: Jani Nikula @ 2014-03-19 19:25 UTC (permalink / raw)
  To: notmuch

Add a tool to start composing an email in the Notmuch Emacs UI with
the specified subject, recipients, and message body.

---

I need something like this to script some mails, particularly with the
mutt compatible options, but I also think notmuch must have long
options. I then got a little carried away with figuring out how to
support both. I think it turned out pretty neat, except due to some
subtlety it only works with bash.

I didn't integrate this in the man build or install or anything,
because I wanted to get feedback first on whether we want to have this
at all. Or if it should live in contrib or something.

BR,
Jani.
---
 doc/man1/notmuch-emacs-mua.rst |  50 ++++++++++++++++++
 notmuch-emacs-mua              | 113 +++++++++++++++++++++++++++++++++++++++++
 2 files changed, 163 insertions(+)
 create mode 100644 doc/man1/notmuch-emacs-mua.rst
 create mode 100755 notmuch-emacs-mua

diff --git a/doc/man1/notmuch-emacs-mua.rst b/doc/man1/notmuch-emacs-mua.rst
new file mode 100644
index 000000000000..6e63818492fb
--- /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.
+
+    ``--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 000000000000..a482fe1a8eca
--- /dev/null
+++ b/notmuch-emacs-mua
@@ -0,0 +1,113 @@
+#!/bin/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 -e
+
+# The crux of it all: construct an elisp progn and eval it.
+ELISP="(progn (notmuch-mua-new-mail)"
+
+while 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=$1
+	    if [ "${OPTARG}" != "-" ]; then
+		echo "$0: unknown short option -${OPTARG}." >&2
+		exit 1
+	    fi
+
+	    case "${opt}" in
+		# Long options with arguments.
+		--subject=*|--to=*|--cc=*|--bcc=*|--body=*)
+		    OPTARG=${opt#--*=}
+		    opt=${opt%%=*}
+		    ;;
+		# Long options without arguments.
+		--help|--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=$((OPTIND + 1))
+	    ;;
+    esac
+
+    case "${opt}" in
+	--help|h)
+	    exec man notmuch-search
+	    ;;
+	--subject|s)
+	    ELISP="${ELISP} (message-goto-subject) (insert \"${OPTARG}\")"
+	    ;;
+	--to)
+	    ELISP="${ELISP} (message-goto-to) (insert \"${OPTARG}, \")"
+	    ;;
+	--cc|c)
+	    ELISP="${ELISP} (message-goto-cc) (insert \"${OPTARG}, \")"
+	    ;;
+	--bcc|b)
+	    ELISP="${ELISP} (message-goto-bcc) (insert \"${OPTARG}, \")"
+	    ;;
+	--body|i)
+	    ELISP="${ELISP} (message-goto-body) (cd \"${PWD}\") (insert-file \"${OPTARG}\")"
+	    ;;
+	--print)
+	    PRINT_ONLY=1
+	    ;;
+	*)
+	    # We should never end up here.
+	    echo "$0: internal error (option ${opt})." >&2
+	    exit 1
+	    ;;
+    esac
+
+    shift $((OPTIND - 1))
+    OPTIND=1
+done
+
+# Positional parameters.
+while [ $# -gt 0 ]; do
+    ELISP="${ELISP} (message-goto-to) (insert \"${1}, \")"
+    shift
+done
+
+# End progn.
+ELISP="${ELISP})"
+
+if [ -n "$PRINT_ONLY" ]; then
+    echo ${ELISP}
+    exit 0
+fi
+
+# Evaluate the progn.
+emacsclient --eval "${ELISP}" &>/dev/null
+if [ $? -ne 0 ]; then
+    echo "$0: emacsclient failed" >&2
+    exit 1
+fi
-- 
1.9.0

^ permalink raw reply related	[flat|nested] 17+ messages in thread

* Re: [PATCH] cli: add a tool for starting new message in the emacs ui
  2014-03-19 19:25 [PATCH] cli: add a tool for starting new message in the emacs ui Jani Nikula
@ 2014-03-19 21:24 ` Tomi Ollila
  2014-03-19 21:54   ` Jani Nikula
  0 siblings, 1 reply; 17+ messages in thread
From: Tomi Ollila @ 2014-03-19 21:24 UTC (permalink / raw)
  To: Jani Nikula, notmuch

On Wed, Mar 19 2014, Jani Nikula <jani@nikula.org> wrote:

> Add a tool to start composing an email in the Notmuch Emacs UI with
> the specified subject, recipients, and message body.
>
> ---
>
> I need something like this to script some mails, particularly with the
> mutt compatible options, but I also think notmuch must have long
> options. I then got a little carried away with figuring out how to
> support both. I think it turned out pretty neat, except due to some
> subtlety it only works with bash.
>
> I didn't integrate this in the man build or install or anything,
> because I wanted to get feedback first on whether we want to have this
> at all. Or if it should live in contrib or something.
>
> BR,
> Jani.
> ---

Quick glance to the code and some thoughts.

>  doc/man1/notmuch-emacs-mua.rst |  50 ++++++++++++++++++
>  notmuch-emacs-mua              | 113 +++++++++++++++++++++++++++++++++++++++++
>  2 files changed, 163 insertions(+)
>  create mode 100644 doc/man1/notmuch-emacs-mua.rst
>  create mode 100755 notmuch-emacs-mua
>
> diff --git a/doc/man1/notmuch-emacs-mua.rst b/doc/man1/notmuch-emacs-mua.rst
> new file mode 100644
> index 000000000000..6e63818492fb
> --- /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.
> +
> +    ``--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)**

It would be convenient to the user to have the manual embedded in
the script in case no args are given or so (or that is convenient
to me ;) and no namual page at all...

> diff --git a/notmuch-emacs-mua b/notmuch-emacs-mua
> new file mode 100755
> index 000000000000..a482fe1a8eca
> --- /dev/null
> +++ b/notmuch-emacs-mua
> @@ -0,0 +1,113 @@
> +#!/bin/bash

#!/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 -e

set -eu would be nice IMO...

... then initialize all vars to empty strings, like PRINT_ONLY=
... and in cases not possible syntax ${1-} can be used.

> +
> +# The crux of it all: construct an elisp progn and eval it.
> +ELISP="(progn (notmuch-mua-new-mail)"

ELISP="(progn (require 'notmuch) (notmuch-mua-new-mail)"

> +
> +while 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=$1
> +	    if [ "${OPTARG}" != "-" ]; then
> +		echo "$0: unknown short option -${OPTARG}." >&2
> +		exit 1
> +	    fi
> +
> +	    case "${opt}" in
> +		# Long options with arguments.
> +		--subject=*|--to=*|--cc=*|--bcc=*|--body=*)
> +		    OPTARG=${opt#--*=}
> +		    opt=${opt%%=*}
> +		    ;;
> +		# Long options without arguments.
> +		--help|--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=$((OPTIND + 1))
> +	    ;;
> +    esac
> +
> +    case "${opt}" in
> +	--help|h)
> +	    exec man notmuch-search
> +	    ;;
> +	--subject|s)
> +	    ELISP="${ELISP} (message-goto-subject) (insert \"${OPTARG}\")"
> +	    ;;
> +	--to)
> +	    ELISP="${ELISP} (message-goto-to) (insert \"${OPTARG}, \")"
> +	    ;;
> +	--cc|c)
> +	    ELISP="${ELISP} (message-goto-cc) (insert \"${OPTARG}, \")"
> +	    ;;
> +	--bcc|b)
> +	    ELISP="${ELISP} (message-goto-bcc) (insert \"${OPTARG}, \")"
> +	    ;;
> +	--body|i)
> +	    ELISP="${ELISP} (message-goto-body) (cd \"${PWD}\") (insert-file \"${OPTARG}\")"
> +	    ;;
> +	--print)
> +	    PRINT_ONLY=1
> +	    ;;
> +	*)
> +	    # We should never end up here.
> +	    echo "$0: internal error (option ${opt})." >&2
> +	    exit 1
> +	    ;;
> +    esac
> +
> +    shift $((OPTIND - 1))
> +    OPTIND=1
> +done
> +
> +# Positional parameters.
> +while [ $# -gt 0 ]; do
> +    ELISP="${ELISP} (message-goto-to) (insert \"${1}, \")"
> +    shift
> +done

for arg; do
   ELISP="${ELISP} (message-goto-to) (insert \"${arg}, \")"
done

I tried to address Austin's comment on IRC with 
printf -v qarg %q "$arg"  -- that has problem if there is whitespace
in arg. maybe  printf -v qarg '%q ' "$arg" -- then there is always one
trailing ws (and spaces are always prefixed w/ \ -- (insert "foo\ bar")
just makes the ' ' disappear (which is not good...).

maybe arg=${arg//\\/\\\\}; arg=${arg//"/\\"}; 

${parameter/pattern/string} -- Pattern substition in bash manual.


> +# End progn.
> +ELISP="${ELISP})"
> +
> +if [ -n "$PRINT_ONLY" ]; then
> +    echo ${ELISP}
> +    exit 0
> +fi
> +
> +# Evaluate the progn.
> +emacsclient --eval "${ELISP}" &>/dev/null

emacsclient --eval "${ELISP}" >/dev/null 2>&1

(why do you want to redirect stdout & stderr to devnull ?)

> +if [ $? -ne 0 ]; then
> +    echo "$0: emacsclient failed" >&2
> +    exit 1
> +fi
> -- 
> 1.9.0

^ permalink raw reply	[flat|nested] 17+ messages in thread

* Re: [PATCH] cli: add a tool for starting new message in the emacs ui
  2014-03-19 21:24 ` Tomi Ollila
@ 2014-03-19 21:54   ` Jani Nikula
  2014-03-20 10:31     ` Tomi Ollila
  0 siblings, 1 reply; 17+ messages in thread
From: Jani Nikula @ 2014-03-19 21:54 UTC (permalink / raw)
  To: Tomi Ollila, notmuch

On Wed, 19 Mar 2014, Tomi Ollila <tomi.ollila@iki.fi> wrote:
> On Wed, Mar 19 2014, Jani Nikula <jani@nikula.org> wrote:
>
>> Add a tool to start composing an email in the Notmuch Emacs UI with
>> the specified subject, recipients, and message body.
>>
>> ---
>>
>> I need something like this to script some mails, particularly with the
>> mutt compatible options, but I also think notmuch must have long
>> options. I then got a little carried away with figuring out how to
>> support both. I think it turned out pretty neat, except due to some
>> subtlety it only works with bash.
>>
>> I didn't integrate this in the man build or install or anything,
>> because I wanted to get feedback first on whether we want to have this
>> at all. Or if it should live in contrib or something.
>>
>> BR,
>> Jani.
>> ---
>
> Quick glance to the code and some thoughts.

Thanks!

>
>>  doc/man1/notmuch-emacs-mua.rst |  50 ++++++++++++++++++
>>  notmuch-emacs-mua              | 113 +++++++++++++++++++++++++++++++++++++++++
>>  2 files changed, 163 insertions(+)
>>  create mode 100644 doc/man1/notmuch-emacs-mua.rst
>>  create mode 100755 notmuch-emacs-mua
>>
>> diff --git a/doc/man1/notmuch-emacs-mua.rst b/doc/man1/notmuch-emacs-mua.rst
>> new file mode 100644
>> index 000000000000..6e63818492fb
>> --- /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.
>> +
>> +    ``--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)**
>
> It would be convenient to the user to have the manual embedded in
> the script in case no args are given or so (or that is convenient
> to me ;) and no namual page at all...

If this is to become part of notmuch, I think a separate man page is in
order. Otherwise, agreed (and even had that in an earlier version).

>
>> diff --git a/notmuch-emacs-mua b/notmuch-emacs-mua
>> new file mode 100755
>> index 000000000000..a482fe1a8eca
>> --- /dev/null
>> +++ b/notmuch-emacs-mua
>> @@ -0,0 +1,113 @@
>> +#!/bin/bash
>
> #!/usr/bin/env bash

Agreed.

>
>> +#
>> +# 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 -e
>
> set -eu would be nice IMO...
>
> ... then initialize all vars to empty strings, like PRINT_ONLY=
> ... and in cases not possible syntax ${1-} can be used.

Agreed.

>
>> +
>> +# The crux of it all: construct an elisp progn and eval it.
>> +ELISP="(progn (notmuch-mua-new-mail)"
>
> ELISP="(progn (require 'notmuch) (notmuch-mua-new-mail)"

Right.

>
>> +
>> +while 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=$1
>> +	    if [ "${OPTARG}" != "-" ]; then
>> +		echo "$0: unknown short option -${OPTARG}." >&2
>> +		exit 1
>> +	    fi
>> +
>> +	    case "${opt}" in
>> +		# Long options with arguments.
>> +		--subject=*|--to=*|--cc=*|--bcc=*|--body=*)
>> +		    OPTARG=${opt#--*=}
>> +		    opt=${opt%%=*}
>> +		    ;;
>> +		# Long options without arguments.
>> +		--help|--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=$((OPTIND + 1))
>> +	    ;;
>> +    esac
>> +
>> +    case "${opt}" in
>> +	--help|h)
>> +	    exec man notmuch-search
>> +	    ;;
>> +	--subject|s)
>> +	    ELISP="${ELISP} (message-goto-subject) (insert \"${OPTARG}\")"
>> +	    ;;
>> +	--to)
>> +	    ELISP="${ELISP} (message-goto-to) (insert \"${OPTARG}, \")"
>> +	    ;;
>> +	--cc|c)
>> +	    ELISP="${ELISP} (message-goto-cc) (insert \"${OPTARG}, \")"
>> +	    ;;
>> +	--bcc|b)
>> +	    ELISP="${ELISP} (message-goto-bcc) (insert \"${OPTARG}, \")"
>> +	    ;;
>> +	--body|i)
>> +	    ELISP="${ELISP} (message-goto-body) (cd \"${PWD}\") (insert-file \"${OPTARG}\")"
>> +	    ;;
>> +	--print)
>> +	    PRINT_ONLY=1
>> +	    ;;
>> +	*)
>> +	    # We should never end up here.
>> +	    echo "$0: internal error (option ${opt})." >&2
>> +	    exit 1
>> +	    ;;
>> +    esac
>> +
>> +    shift $((OPTIND - 1))
>> +    OPTIND=1
>> +done
>> +
>> +# Positional parameters.
>> +while [ $# -gt 0 ]; do
>> +    ELISP="${ELISP} (message-goto-to) (insert \"${1}, \")"
>> +    shift
>> +done
>
> for arg; do

for arg in $@; ?

>    ELISP="${ELISP} (message-goto-to) (insert \"${arg}, \")"
> done
>
> I tried to address Austin's comment on IRC with 
> printf -v qarg %q "$arg"  -- that has problem if there is whitespace
> in arg. maybe  printf -v qarg '%q ' "$arg" -- then there is always one
> trailing ws (and spaces are always prefixed w/ \ -- (insert "foo\ bar")
> just makes the ' ' disappear (which is not good...).
>
> maybe arg=${arg//\\/\\\\}; arg=${arg//"/\\"}; 
>
> ${parameter/pattern/string} -- Pattern substition in bash manual.

I'm inclined to go with "don't do that then" ;)

>
>
>> +# End progn.
>> +ELISP="${ELISP})"
>> +
>> +if [ -n "$PRINT_ONLY" ]; then
>> +    echo ${ELISP}
>> +    exit 0
>> +fi
>> +
>> +# Evaluate the progn.
>> +emacsclient --eval "${ELISP}" &>/dev/null
>
> emacsclient --eval "${ELISP}" >/dev/null 2>&1
>
> (why do you want to redirect stdout & stderr to devnull ?)

Okay, maybe it could be just stdout (which will be the eval result, in
this case nil).

>
>> +if [ $? -ne 0 ]; then
>> +    echo "$0: emacsclient failed" >&2
>> +    exit 1
>> +fi
>> -- 
>> 1.9.0

^ permalink raw reply	[flat|nested] 17+ messages in thread

* Re: [PATCH] cli: add a tool for starting new message in the emacs ui
  2014-03-19 21:54   ` Jani Nikula
@ 2014-03-20 10:31     ` Tomi Ollila
  2014-04-06 15:43       ` [PATCH v2] " Jani Nikula
  0 siblings, 1 reply; 17+ messages in thread
From: Tomi Ollila @ 2014-03-20 10:31 UTC (permalink / raw)
  To: Jani Nikula, notmuch

On Wed, Mar 19 2014, Jani Nikula <jani@nikula.org> wrote:

> On Wed, 19 Mar 2014, Tomi Ollila <tomi.ollila@iki.fi> wrote:
>> On Wed, Mar 19 2014, Jani Nikula <jani@nikula.org> wrote:
>>
>>> +
>>> +# Positional parameters.
>>> +while [ $# -gt 0 ]; do
>>> +    ELISP="${ELISP} (message-goto-to) (insert \"${1}, \")"
>>> +    shift
>>> +done
>>
>> for arg; do
>
> for arg in $@; ?


Yes, that is less obfuscated version of that, whichever you feel more
comfortable with... for more discussion about the alternatives here see:
  http://www.in-ulm.de/~mascheck/various/bourne_args/
(but don't look that -- it is unnecessary and only causes headache ;D)


>> maybe arg=${arg//\\/\\\\}; arg=${arg//"/\\"}; 
>>
>> ${parameter/pattern/string} -- Pattern substition in bash manual.
>
> I'm inclined to go with "don't do that then" ;)

$ bash -c 'arg=${0//\\/\\\\}; echo ${arg//\"/\\\"}' 'this"is\a test'
this\"is\\a test
$ zsh -c 'arg=${0//\\/\\\\}; echo ${arg//\"/\\\"}' 'this"is\a test' 
this\"is\a test 
$ ksh -c 'arg=${0//\\/\\\\}; echo ${arg//\"/\\\"}' 'this"is\a test' 
this\"is\\a test

Interestigly zsh on Scientific Linux 6.2 fails here (zsh 4.3.10) -- I tried
various tricks and none helped. Hmm also zsh 4.3.17 on Ubuntu 12.04 fails.
zsh 5.0.2 on Fedora 20 works OK. ksh & bash installed on all these 3
systems work OK (and also bash 3.2.51... on Mac OS X). 

IMO this quoting should be done -- so I can send you email with:

$ notmuch-emacs-mua '"Jani Nikula" <jani@nikula.org>'


Tomi

^ permalink raw reply	[flat|nested] 17+ messages in thread

* [PATCH v2] cli: add a tool for starting new message in the emacs ui
  2014-03-20 10:31     ` Tomi Ollila
@ 2014-04-06 15:43       ` Jani Nikula
  2014-04-07  3:59         ` Jameson Graef Rollins
  2014-07-01 20:02         ` [PATCH] " David Bremner
  0 siblings, 2 replies; 17+ messages in thread
From: Jani Nikula @ 2014-04-06 15:43 UTC (permalink / raw)
  To: notmuch, Tomi Ollila

Add a tool to start composing an email in the Notmuch Emacs UI with
the specified subject, recipients, and message body.
---
 doc/man1/notmuch-emacs-mua.rst |  50 +++++++++++++++++
 notmuch-emacs-mua              | 122 +++++++++++++++++++++++++++++++++++++++++
 2 files changed, 172 insertions(+)
 create mode 100644 doc/man1/notmuch-emacs-mua.rst
 create mode 100755 notmuch-emacs-mua

diff --git a/doc/man1/notmuch-emacs-mua.rst b/doc/man1/notmuch-emacs-mua.rst
new file mode 100644
index 000000000000..6e63818492fb
--- /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.
+
+    ``--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 000000000000..7f94271d8a44
--- /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//\"/\\\"}"
+}
+
+PRINT_ONLY=
+
+# The crux of it all: construct an elisp progn and eval it.
+ELISP="(progn (require 'notmuch) (notmuch-mua-new-mail)"
+
+while 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=$1
+	    if [ "${OPTARG}" != "-" ]; then
+		echo "$0: unknown short option -${OPTARG}." >&2
+		exit 1
+	    fi
+
+	    case "${opt}" in
+		# Long options with arguments.
+		--subject=*|--to=*|--cc=*|--bcc=*|--body=*)
+		    OPTARG=${opt#--*=}
+		    opt=${opt%%=*}
+		    ;;
+		# Long options without arguments.
+		--help|--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=$((OPTIND + 1))
+	    ;;
+    esac
+
+    OPTARG="$(escape "${OPTARG}")"
+
+    case "${opt}" in
+	--help|h)
+	    exec man notmuch-emacs-mua
+	    ;;
+	--subject|s)
+	    ELISP="${ELISP} (message-goto-subject) (insert \"${OPTARG}\")"
+	    ;;
+	--to)
+	    ELISP="${ELISP} (message-goto-to) (insert \"${OPTARG}, \")"
+	    ;;
+	--cc|c)
+	    ELISP="${ELISP} (message-goto-cc) (insert \"${OPTARG}, \")"
+	    ;;
+	--bcc|b)
+	    ELISP="${ELISP} (message-goto-bcc) (insert \"${OPTARG}, \")"
+	    ;;
+	--body|i)
+	    ELISP="${ELISP} (message-goto-body) (cd \"${PWD}\") (insert-file \"${OPTARG}\")"
+	    ;;
+	--print)
+	    PRINT_ONLY=1
+	    ;;
+	*)
+	    # We should never end up here.
+	    echo "$0: internal error (option ${opt})." >&2
+	    exit 1
+	    ;;
+    esac
+
+    shift $((OPTIND - 1))
+    OPTIND=1
+done
+
+# Positional parameters.
+for arg; do
+    arg="$(escape "${arg}")"
+    ELISP="${ELISP} (message-goto-to) (insert \"${arg}, \")"
+done
+
+# End progn.
+ELISP="${ELISP})"
+
+if [ -n "$PRINT_ONLY" ]; then
+    echo ${ELISP}
+    exit 0
+fi
+
+# Evaluate the progn.
+emacsclient --eval "${ELISP}" >/dev/null
+if [ $? -ne 0 ]; then
+    echo "$0: emacsclient failed" >&2
+    exit 1
+fi
-- 
1.9.1

^ permalink raw reply related	[flat|nested] 17+ messages in thread

* Re: [PATCH v2] cli: add a tool for starting new message in the emacs ui
  2014-04-06 15:43       ` [PATCH v2] " Jani Nikula
@ 2014-04-07  3:59         ` Jameson Graef Rollins
  2014-07-01 20:02         ` [PATCH] " David Bremner
  1 sibling, 0 replies; 17+ messages in thread
From: Jameson Graef Rollins @ 2014-04-07  3:59 UTC (permalink / raw)
  To: Jani Nikula, notmuch, Tomi Ollila

[-- Attachment #1: Type: text/plain, Size: 592 bytes --]

On Sun, Apr 06 2014, Jani Nikula <jani@nikula.org> wrote:
> Add a tool to start composing an email in the Notmuch Emacs UI with
> the specified subject, recipients, and message body.

Hey, Jani.  You might be interested in checking out a patch I submitted
a while back to support "mailto:" urls in notmuch-mua.el:

id:1327865624-7673-1-git-send-email-jrollins@finestructure.net

That, combined with your new ui interface would make handling mailto:
urls in say browsers very convenient, e.g.:

  ELISP="(notmuch-mua-mailto \"$URL\")"

for:

  notmuch-emacs-mua mailto:foo@example.com

jamie.

[-- Attachment #2: Type: application/pgp-signature, Size: 818 bytes --]

^ permalink raw reply	[flat|nested] 17+ messages in thread

* [PATCH] cli: add a tool for starting new message in the emacs ui
  2014-04-06 15:43       ` [PATCH v2] " Jani Nikula
  2014-04-07  3:59         ` Jameson Graef Rollins
@ 2014-07-01 20:02         ` David Bremner
  2014-07-04 17:36           ` Tomi Ollila
  2015-01-18 16:21           ` David Bremner
  1 sibling, 2 replies; 17+ messages in thread
From: David Bremner @ 2014-07-01 20:02 UTC (permalink / raw)
  To: notmuch

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.


 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.
+
+    ``--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//\"/\\\"}"
+}
+
+PRINT_ONLY=
+
+# The crux of it all: construct an elisp progn and eval it.
+ELISP="(progn (require 'notmuch) (notmuch-mua-new-mail)"
+
+while 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=$1
+	    if [ "${OPTARG}" != "-" ]; then
+		echo "$0: unknown short option -${OPTARG}." >&2
+		exit 1
+	    fi
+
+	    case "${opt}" in
+		# Long options with arguments.
+		--subject=*|--to=*|--cc=*|--bcc=*|--body=*)
+		    OPTARG=${opt#--*=}
+		    opt=${opt%%=*}
+		    ;;
+		# Long options without arguments.
+		--help|--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=$((OPTIND + 1))
+	    ;;
+    esac
+
+    OPTARG="$(escape "${OPTARG}")"
+
+    case "${opt}" in
+	--help|h)
+	    exec man notmuch-emacs-mua
+	    ;;
+	--subject|s)
+	    ELISP="${ELISP} (message-goto-subject) (insert \"${OPTARG}\")"
+	    ;;
+	--to)
+	    ELISP="${ELISP} (message-goto-to) (insert \"${OPTARG}, \")"
+	    ;;
+	--cc|c)
+	    ELISP="${ELISP} (message-goto-cc) (insert \"${OPTARG}, \")"
+	    ;;
+	--bcc|b)
+	    ELISP="${ELISP} (message-goto-bcc) (insert \"${OPTARG}, \")"
+	    ;;
+	--body|i)
+	    ELISP="${ELISP} (message-goto-body) (cd \"${PWD}\") (insert-file \"${OPTARG}\")"
+	    ;;
+	--print)
+	    PRINT_ONLY=1
+	    ;;
+	*)
+	    # We should never end up here.
+	    echo "$0: internal error (option ${opt})." >&2
+	    exit 1
+	    ;;
+    esac
+
+    shift $((OPTIND - 1))
+    OPTIND=1
+done
+
+# Positional parameters.
+for arg; do
+    arg="$(escape "${arg}")"
+    ELISP="${ELISP} (message-goto-to) (insert \"${arg}, \")"
+done
+
+# End progn.
+ELISP="${ELISP})"
+
+if [ -n "$PRINT_ONLY" ]; then
+    echo ${ELISP}
+    exit 0
+fi
+
+# Evaluate the progn.
+emacsclient --eval "${ELISP}" >/dev/null
+if [ $? -ne 0 ]; then
+    echo "$0: emacsclient failed" >&2
+    exit 1
+fi
-- 
2.0.0.rc2

^ permalink raw reply related	[flat|nested] 17+ messages in thread

* Re: [PATCH] cli: add a tool for starting new message in the emacs ui
  2014-07-01 20:02         ` [PATCH] " David Bremner
@ 2014-07-04 17:36           ` Tomi Ollila
  2015-01-18 16:21           ` David Bremner
  1 sibling, 0 replies; 17+ messages in thread
From: Tomi Ollila @ 2014-07-04 17:36 UTC (permalink / raw)
  To: David Bremner, notmuch, Jani Nikula

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

^ permalink raw reply	[flat|nested] 17+ messages in thread

* [PATCH] cli: add a tool for starting new message in the emacs ui
  2014-07-01 20:02         ` [PATCH] " David Bremner
  2014-07-04 17:36           ` Tomi Ollila
@ 2015-01-18 16:21           ` David Bremner
  2015-01-18 21:07             ` Tomi Ollila
                               ` (3 more replies)
  1 sibling, 4 replies; 17+ messages in thread
From: David Bremner @ 2015-01-18 16:21 UTC (permalink / raw)
  To: notmuch

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.
---

This version fixes my complaint about the previous version not
starting emacs.  It does this by starting a new "frame", either at the
window system level, or in the current terminal.  The traditional
"-nw" short form of the argument "--no-window-system" seems maybe more
work to parse than it's worth.

 doc/conf.py                    |   4 ++
 doc/man1/notmuch-emacs-mua.rst |  53 ++++++++++++++++++
 notmuch-emacs-mua              | 122 +++++++++++++++++++++++++++++++++++++++++
 3 files changed, 179 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 fb49f6e..8fbc854 100644
--- a/doc/conf.py
+++ b/doc/conf.py
@@ -78,6 +78,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..bf8c3aa
--- /dev/null
+++ b/doc/man1/notmuch-emacs-mua.rst
@@ -0,0 +1,53 @@
+=================
+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.
+
+    ``--no-window-system``
+        Even if a window system is available, use the current terminal
+
+    ``--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..fdf4024
--- /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//\"/\\\"}"
+}
+
+PRINT_ONLY=
+CLIENT_TYPE="-c"
+
+# The crux of it all: construct an elisp progn and eval it.
+ELISP="(prog1 'done (require 'notmuch) (notmuch-mua-new-mail)"
+
+while 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=$1
+	    if [ "${OPTARG}" != "-" ]; then
+		echo "$0: unknown short option -${OPTARG}." >&2
+		exit 1
+	    fi
+
+	    case "${opt}" in
+		# Long options with arguments.
+		--subject=*|--to=*|--cc=*|--bcc=*|--body=*)
+		    OPTARG=${opt#--*=}
+		    opt=${opt%%=*}
+		    ;;
+		# Long options without arguments.
+		--help|--print|--no-window-system)
+		    ;;
+		*)
+		    echo "$0: unknown long option ${opt}, or argument mismatch." >&2
+		    exit 1
+		    ;;
+	    esac
+	    # getopts does not do this for what it considers errors.
+	    OPTIND=$((OPTIND + 1))
+	    ;;
+    esac
+
+    OPTARG="$(escape "${OPTARG}")"
+
+    case "${opt}" in
+	--help|h)
+	    exec man notmuch-emacs-mua
+	    ;;
+	--subject|s)
+	    ELISP="${ELISP} (message-goto-subject) (insert \"${OPTARG}\")"
+	    ;;
+	--to)
+	    ELISP="${ELISP} (message-goto-to) (insert \"${OPTARG}, \")"
+	    ;;
+	--cc|c)
+	    ELISP="${ELISP} (message-goto-cc) (insert \"${OPTARG}, \")"
+	    ;;
+	--bcc|b)
+	    ELISP="${ELISP} (message-goto-bcc) (insert \"${OPTARG}, \")"
+	    ;;
+	--body|i)
+	    ELISP="${ELISP} (message-goto-body) (cd \"${PWD}\") (insert-file \"${OPTARG}\")"
+	    ;;
+	--print)
+	    PRINT_ONLY=1
+	    ;;
+	--no-window-system)
+	    CLIENT_TYPE="-t"
+	    ;;
+	*)
+	    # We should never end up here.
+	    echo "$0: internal error (option ${opt})." >&2
+	    exit 1
+	    ;;
+    esac
+
+    shift $((OPTIND - 1))
+    OPTIND=1
+done
+
+# Positional parameters.
+for arg; do
+    arg="$(escape "${arg}")"
+    ELISP="${ELISP} (message-goto-to) (insert \"${arg}, \")"
+done
+
+# End progn.
+ELISP="${ELISP})"
+
+if [ -n "$PRINT_ONLY" ]; then
+    echo ${ELISP}
+    exit 0
+fi
+
+# Evaluate the progn.
+exec emacsclient ${CLIENT_TYPE} -a '' --eval "${ELISP}"
-- 
2.1.4

^ permalink raw reply related	[flat|nested] 17+ messages in thread

* Re: [PATCH] cli: add a tool for starting new message in the emacs ui
  2015-01-18 16:21           ` David Bremner
@ 2015-01-18 21:07             ` Tomi Ollila
  2015-01-19 16:32             ` Tomi Ollila
                               ` (2 subsequent siblings)
  3 siblings, 0 replies; 17+ messages in thread
From: Tomi Ollila @ 2015-01-18 21:07 UTC (permalink / raw)
  To: David Bremner, notmuch

On Sun, Jan 18 2015, 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.
> ---
>
> This version fixes my complaint about the previous version not
> starting emacs.  It does this by starting a new "frame", either at the
> window system level, or in the current terminal.  The traditional
> "-nw" short form of the argument "--no-window-system" seems maybe more
> work to parse than it's worth.

Well, id:1405026779-29966-1-git-send-email-tomi.ollila@iki.fi (*) had -nw
parsing, but I can live without...

But more than that one important feature has to be agreed before initial
interface is locked down -- how to provide body content from command line
without resorting to temporary files. In (*) --body was adding those lines
instead of reading file and I later suggested that --include or --insert
could do the same as -i ... but I am open to any solution that gives me
opportunity to provide body *content* from command line.

Tomi

>
>  doc/conf.py                    |   4 ++
>  doc/man1/notmuch-emacs-mua.rst |  53 ++++++++++++++++++
>  notmuch-emacs-mua              | 122 +++++++++++++++++++++++++++++++++++++++++
>  3 files changed, 179 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 fb49f6e..8fbc854 100644
> --- a/doc/conf.py
> +++ b/doc/conf.py
> @@ -78,6 +78,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..bf8c3aa
> --- /dev/null
> +++ b/doc/man1/notmuch-emacs-mua.rst
> @@ -0,0 +1,53 @@
> +=================
> +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.
> +
> +    ``--no-window-system``
> +        Even if a window system is available, use the current terminal
> +
> +    ``--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..fdf4024
> --- /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//\"/\\\"}"
> +}
> +
> +PRINT_ONLY=
> +CLIENT_TYPE="-c"
> +
> +# The crux of it all: construct an elisp progn and eval it.
> +ELISP="(prog1 'done (require 'notmuch) (notmuch-mua-new-mail)"
> +
> +while 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=$1
> +	    if [ "${OPTARG}" != "-" ]; then
> +		echo "$0: unknown short option -${OPTARG}." >&2
> +		exit 1
> +	    fi
> +
> +	    case "${opt}" in
> +		# Long options with arguments.
> +		--subject=*|--to=*|--cc=*|--bcc=*|--body=*)
> +		    OPTARG=${opt#--*=}
> +		    opt=${opt%%=*}
> +		    ;;
> +		# Long options without arguments.
> +		--help|--print|--no-window-system)
> +		    ;;
> +		*)
> +		    echo "$0: unknown long option ${opt}, or argument mismatch." >&2
> +		    exit 1
> +		    ;;
> +	    esac
> +	    # getopts does not do this for what it considers errors.
> +	    OPTIND=$((OPTIND + 1))
> +	    ;;
> +    esac
> +
> +    OPTARG="$(escape "${OPTARG}")"
> +
> +    case "${opt}" in
> +	--help|h)
> +	    exec man notmuch-emacs-mua
> +	    ;;
> +	--subject|s)
> +	    ELISP="${ELISP} (message-goto-subject) (insert \"${OPTARG}\")"
> +	    ;;
> +	--to)
> +	    ELISP="${ELISP} (message-goto-to) (insert \"${OPTARG}, \")"
> +	    ;;
> +	--cc|c)
> +	    ELISP="${ELISP} (message-goto-cc) (insert \"${OPTARG}, \")"
> +	    ;;
> +	--bcc|b)
> +	    ELISP="${ELISP} (message-goto-bcc) (insert \"${OPTARG}, \")"
> +	    ;;
> +	--body|i)
> +	    ELISP="${ELISP} (message-goto-body) (cd \"${PWD}\") (insert-file \"${OPTARG}\")"
> +	    ;;
> +	--print)
> +	    PRINT_ONLY=1
> +	    ;;
> +	--no-window-system)
> +	    CLIENT_TYPE="-t"
> +	    ;;
> +	*)
> +	    # We should never end up here.
> +	    echo "$0: internal error (option ${opt})." >&2
> +	    exit 1
> +	    ;;
> +    esac
> +
> +    shift $((OPTIND - 1))
> +    OPTIND=1
> +done
> +
> +# Positional parameters.
> +for arg; do
> +    arg="$(escape "${arg}")"
> +    ELISP="${ELISP} (message-goto-to) (insert \"${arg}, \")"
> +done
> +
> +# End progn.
> +ELISP="${ELISP})"
> +
> +if [ -n "$PRINT_ONLY" ]; then
> +    echo ${ELISP}
> +    exit 0
> +fi
> +
> +# Evaluate the progn.
> +exec emacsclient ${CLIENT_TYPE} -a '' --eval "${ELISP}"
> -- 
> 2.1.4

^ permalink raw reply	[flat|nested] 17+ messages in thread

* Re: [PATCH] cli: add a tool for starting new message in the emacs ui
  2015-01-18 16:21           ` David Bremner
  2015-01-18 21:07             ` Tomi Ollila
@ 2015-01-19 16:32             ` Tomi Ollila
  2015-01-20 17:53             ` [DRAFT PATCH v2] modified notmuch-emacs-mua v2 Tomi Ollila
  2015-02-22 20:34             ` [PATCH] cli: add a tool for starting new message in the emacs ui David Bremner
  3 siblings, 0 replies; 17+ messages in thread
From: Tomi Ollila @ 2015-01-19 16:32 UTC (permalink / raw)
  To: David Bremner, Jani Nikula, notmuch

On Sun, Jan 18 2015, 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've given this quite a lot of thought today (while commuting on the bus),
and at some (late) moment of time I started to think about security 
(command line options are visible in ps(1) output), and based on that the
naive user option --body taking content from a file is tol^H^H^Hgood idea
after all. 

Therefore, the current command line interface gets +1 from me.

I'll use this as a base for further work after this is committed to
the repository.

(I am now on a terminal unsuitable for yet another review round; I'll
do that tomorrow)

Tomi




>
> This version fixes my complaint about the previous version not
> starting emacs.  It does this by starting a new "frame", either at the
> window system level, or in the current terminal.  The traditional
> "-nw" short form of the argument "--no-window-system" seems maybe more
> work to parse than it's worth.
>
>  doc/conf.py                    |   4 ++
>  doc/man1/notmuch-emacs-mua.rst |  53 ++++++++++++++++++
>  notmuch-emacs-mua              | 122 +++++++++++++++++++++++++++++++++++++++++
>  3 files changed, 179 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 fb49f6e..8fbc854 100644
> --- a/doc/conf.py
> +++ b/doc/conf.py
> @@ -78,6 +78,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..bf8c3aa
> --- /dev/null
> +++ b/doc/man1/notmuch-emacs-mua.rst
> @@ -0,0 +1,53 @@
> +=================
> +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.
> +
> +    ``--no-window-system``
> +        Even if a window system is available, use the current terminal
> +
> +    ``--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..fdf4024
> --- /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//\"/\\\"}"
> +}
> +
> +PRINT_ONLY=
> +CLIENT_TYPE="-c"
> +
> +# The crux of it all: construct an elisp progn and eval it.
> +ELISP="(prog1 'done (require 'notmuch) (notmuch-mua-new-mail)"
> +
> +while 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=$1
> +	    if [ "${OPTARG}" != "-" ]; then
> +		echo "$0: unknown short option -${OPTARG}." >&2
> +		exit 1
> +	    fi
> +
> +	    case "${opt}" in
> +		# Long options with arguments.
> +		--subject=*|--to=*|--cc=*|--bcc=*|--body=*)
> +		    OPTARG=${opt#--*=}
> +		    opt=${opt%%=*}
> +		    ;;
> +		# Long options without arguments.
> +		--help|--print|--no-window-system)
> +		    ;;
> +		*)
> +		    echo "$0: unknown long option ${opt}, or argument mismatch." >&2
> +		    exit 1
> +		    ;;
> +	    esac
> +	    # getopts does not do this for what it considers errors.
> +	    OPTIND=$((OPTIND + 1))
> +	    ;;
> +    esac
> +
> +    OPTARG="$(escape "${OPTARG}")"
> +
> +    case "${opt}" in
> +	--help|h)
> +	    exec man notmuch-emacs-mua
> +	    ;;
> +	--subject|s)
> +	    ELISP="${ELISP} (message-goto-subject) (insert \"${OPTARG}\")"
> +	    ;;
> +	--to)
> +	    ELISP="${ELISP} (message-goto-to) (insert \"${OPTARG}, \")"
> +	    ;;
> +	--cc|c)
> +	    ELISP="${ELISP} (message-goto-cc) (insert \"${OPTARG}, \")"
> +	    ;;
> +	--bcc|b)
> +	    ELISP="${ELISP} (message-goto-bcc) (insert \"${OPTARG}, \")"
> +	    ;;
> +	--body|i)
> +	    ELISP="${ELISP} (message-goto-body) (cd \"${PWD}\") (insert-file \"${OPTARG}\")"
> +	    ;;
> +	--print)
> +	    PRINT_ONLY=1
> +	    ;;
> +	--no-window-system)
> +	    CLIENT_TYPE="-t"
> +	    ;;
> +	*)
> +	    # We should never end up here.
> +	    echo "$0: internal error (option ${opt})." >&2
> +	    exit 1
> +	    ;;
> +    esac
> +
> +    shift $((OPTIND - 1))
> +    OPTIND=1
> +done
> +
> +# Positional parameters.
> +for arg; do
> +    arg="$(escape "${arg}")"
> +    ELISP="${ELISP} (message-goto-to) (insert \"${arg}, \")"
> +done
> +
> +# End progn.
> +ELISP="${ELISP})"
> +
> +if [ -n "$PRINT_ONLY" ]; then
> +    echo ${ELISP}
> +    exit 0
> +fi
> +
> +# Evaluate the progn.
> +exec emacsclient ${CLIENT_TYPE} -a '' --eval "${ELISP}"
> -- 
> 2.1.4
>
> _______________________________________________
> notmuch mailing list
> notmuch@notmuchmail.org
> http://notmuchmail.org/mailman/listinfo/notmuch

^ permalink raw reply	[flat|nested] 17+ messages in thread

* [DRAFT PATCH v2] modified notmuch-emacs-mua v2
  2015-01-18 16:21           ` David Bremner
  2015-01-18 21:07             ` Tomi Ollila
  2015-01-19 16:32             ` Tomi Ollila
@ 2015-01-20 17:53             ` Tomi Ollila
  2015-01-20 18:58               ` David Bremner
  2015-02-22 20:34             ` [PATCH] cli: add a tool for starting new message in the emacs ui David Bremner
  3 siblings, 1 reply; 17+ messages in thread
From: Tomi Ollila @ 2015-01-20 17:53 UTC (permalink / raw)
  To: David Bremner, notmuch, Jani Nikula; +Cc: tomi.ollila

This is second draft patch of (first being)

id:1405026779-29966-1-git-send-email-tomi.ollila@iki.fi

I saw potential problem with only supporting emacsclient(1) in
the version David sent:
id:1421598115-4889-1-git-send-email-david@tethera.net

(no emacs server running and no tty -- new X client not started)

therefore I started to modify that part -- and soon adding all features
I'd like to see there. As I expect some bikeshedding to continue I skip
doc update for the time being (to avoid unnecessary work), therefore
calling this as "draft patch".

This implIments many of my first draft features:

mailto: is handled if given as first argument (not yet all the nice stuff
Jameson suggested, we'll perhaps get there later...)

--from option when sending non-mailto: way

And, -nw (*) in a new way...

The -i and --body are done as in initial Jani's version ( also as in
id:1421598115-4889-1-git-send-email-david@tethera.net )

Also, --long SPC value is not implemented, format is --long=value

In case emacsclient(1) is used and no --no-window-system, '-c' arg is
given to emacsclient like in the version David sent.

(this means that if emacs is not running on X, user may get this message:
 "emacsclient: could not get terminal name" -- we need to document user
 to give -nw (--no-window-system) option then)

Other "new" things:

Option --bodytext to give body content from command line (not documented
yet, but I'll add privacy warning when updating NaMual page.

Final cursor position goes based on last option given from command line,
unless to: or subject: is missing -- cursor is positioned after these
headers in this case.

(*) -nw works so that the 'n' is given to getopts and it expects an
argument; the argument is checked being w (this means -nw and -n w are
accepted). this also gives interesting output when one attempts to use
plain '-n' (error message shows next arg concatenated into this or...
"./notmuch-emacs-mua: short option -n requires an argument." -- OK,
forgot to handle this special case at this time...)

Anyway, I'd rather have -nw and some peculiarity than no -nw at all ;)

Tomi
---
 notmuch-emacs-mua | 217 ++++++++++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 217 insertions(+)
 create mode 100755 notmuch-emacs-mua

diff --git a/notmuch-emacs-mua b/notmuch-emacs-mua
new file mode 100755
index 000000000000..42275cd1a563
--- /dev/null
+++ b/notmuch-emacs-mua
@@ -0,0 +1,217 @@
+#!/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 © 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>
+#          Tomi Ollila <tomi.ollila@iki.fi>
+#
+
+set -eu
+
+# Cannot use [[ ]] until we know we have bash.
+case ${BASH_VERSION-} in '')
+    echo "Not BASH!" >&2
+    exit 1
+esac
+
+# escape: "expand" '\' to '\\' & '"' to '\"'
+# Calling convention: escape -v var "$arg" (like in bash printf).
+escape ()
+{
+	local arg=${3//\\/\\\\}
+	eval $2='${arg//\"/\\\"}'
+}
+
+unset ALTERNATE_EDITOR
+exec_mua ()
+{
+    if "${EMACSCLIENT:=emacsclient}" --eval t >/dev/null 2>&1
+    then
+	emacs=$EMACSCLIENT
+	# Close stdout in case no --no-window-system (and no --print).
+	test -n "$W$X" || exec >/dev/null
+	# W/ emacsclient, use '-c' in case no --no-window-system.
+	[[ -n $W ]] || W=-c
+    else
+	emacs=${EMACS:-emacs}
+    fi
+    ${X:-exec} "${emacs}" $W --eval "(prog1 'done $*)"
+    exit
+}
+
+X=  # This is chaged to 'echo' when --print is used.
+W=  # This is changed to '-nw' when --no-window-system is used.
+
+SUBJECT= TO= CC= BCC= BODY= FROM=
+
+unset message_goto # Final elisp function to execute, when defined.
+cddone=false
+
+# "Short circuit" mailto handling.
+case ${1-} in mailto:*)
+	oIFS=$IFS; IFS=
+	escape -v OPTARG "$*"
+	IFS=$oIFS
+	exec_mua "(require 'notmuch) (browse-url-mail \"$OPTARG\")"
+	exit
+esac
+
+while getopts :s:c:b:i:n:h opt; do
+    # Handle errors and long options.
+    case "${opt}" in
+	:)
+	    echo "$0: short option -${OPTARG} requires an argument." >&2
+	    exit 1
+	    ;;
+	\?)
+	    opt=$1
+	    if [[ ${OPTARG} != '-' ]]; then
+		echo "$0: unknown short option -${OPTARG}." >&2
+		exit 1
+	    fi
+
+	    case "${opt}" in
+		# Long options with arguments.
+		--subject=*|--to=*|--cc=*|--bcc=*|--body=*|--from=*|--bodytext=*)
+		    OPTARG=${opt#--*=}
+		    opt=${opt%%=*}
+		    ;;
+		# Long options without arguments.
+		--help|--print|--no-window-system)
+		    ;;
+		*)
+		    echo "$0: unknown long option ${opt}, or argument mismatch." >&2
+		    exit 1
+		    ;;
+	    esac
+	    # Getopts does not do this for what it considers errors.
+	    OPTIND=$((OPTIND + 1))
+	    ;;
+    esac
+
+    escape -v OPTARG "${OPTARG}"
+
+    case "${opt}" in
+	--help|h)
+	    exec man notmuch-emacs-mua
+	    ;;
+	--from)
+	    escape -v FROM "${OPTARG}"
+	    ;;
+	--subject|s)
+	    escape -v OPTARG "${OPTARG}"
+	    SUBJECT=${SUBJECT:+$SUBJECT }${OPTARG}
+	    message_goto='(message-goto-subject)'
+	    ;;
+	--to)
+	    escape -v OPTARG "${OPTARG}"
+	    TO=${TO:+$TO, }${OPTARG}
+	    message_goto='(message-goto-to)'
+	    ;;
+	--cc|c)
+	    escape -v OPTARG "${OPTARG}"
+	    CC=${CC:+$CC, }${OPTARG}
+	    message_goto='(message-goto-cc)'
+	    ;;
+	--bcc|b)
+	    escape -v OPTARG "${OPTARG}"
+	    BCC=${BCC:+$BCC, }${OPTARG}
+	    message_goto='(message-goto-bcc)'
+	    ;;
+	--body|i)
+	    escape -v OPTARG "${OPTARG}"
+	    if [[ ! -f ${OPTARG} ]]; then
+	        echo "$0: '${OPTARG}': no such file" >&2
+		exit 1
+	    fi
+	    if [[ $cddone == 'false' ]]; then
+		BODY=${BODY}$'\n'"  (cd \"${PWD}\")"
+		cddone=true
+	    fi
+	    BODY=${BODY}$'\n'"  (insert-file \"${OPTARG}\")"
+	    BODY=${BODY}$'\n'"  (if (/= (point) (line-beginning-position)) (insert \"\\n\"))"
+	    unset message_goto
+	    ;;
+	--bodytext)
+	    escape -v OPTARG "${OPTARG}"
+	    BODY=${BODY}$'\n'"  (insert \"${OPTARG}\\n\")"
+	    unset message_goto
+	    ;;
+	--no-window-system)
+	    W=-nw
+	    ;;
+	n) # -nw !!!
+	    if [[ $OPTARG == 'w' ]]; then
+		W=-nw
+	    else
+		echo "$0: unknown option -n${OPTARG}, or argument mismatch." >&2
+		exit 1
+	    fi
+	    ;;
+	--print)
+	    X=echo
+	    ;;
+	*)
+	    # We should never end up here.
+	    echo "$0: internal error (option ${opt})." >&2
+	    exit 1
+	    ;;
+    esac
+
+    shift $((OPTIND - 1))
+    OPTIND=1
+done
+
+# Positional parameters.
+for arg; do
+    escape -v arg "${arg}"
+    TO=${TO:+$TO, }${arg}
+    message_goto='(message-goto-to)'
+done
+
+# The newlines are here for --print (only) output.
+NL=$'\n'
+ELISP="\
+${CC:+$NL  (message-goto-cc) (insert \"$CC\")}\
+${BCC:+$NL  (message-goto-bcc) (insert \"$BCC\")}\
+${BODY:+$NL  (message-goto-body)$BODY}"
+
+if [[ $TO == '' && $SUBJECT == '' && $ELISP == '' ]]
+then
+    exec_mua "(require 'notmuch) (notmuch-hello)"
+else
+    [[ $FROM != '' ]] && OH="(list (cons 'From \"$FROM\"))" || OH=nil
+
+    if [[ $SUBJECT == '' ]]; then
+	SUBJECT=nil
+	message_goto='(message-goto-subject)'
+    else
+	SUBJECT=\"$SUBJECT\"
+    fi
+    if [[ $TO == '' ]]; then
+	TO=nil
+	message_goto='(message-goto-to)'
+    else
+	TO=\"$TO\"
+    fi
+    exec_mua "(require 'notmuch)
+  (notmuch-mua-mail ${TO} ${SUBJECT}
+	${OH} nil (notmuch-mua-get-switch-function))\
+${ELISP}${NL}  (set-buffer-modified-p nil)${message_goto+ $message_goto}"
+fi
-- 
2.0.0

^ permalink raw reply related	[flat|nested] 17+ messages in thread

* Re: [DRAFT PATCH v2] modified notmuch-emacs-mua v2
  2015-01-20 17:53             ` [DRAFT PATCH v2] modified notmuch-emacs-mua v2 Tomi Ollila
@ 2015-01-20 18:58               ` David Bremner
  2015-01-21  9:38                 ` Tomi Ollila
  0 siblings, 1 reply; 17+ messages in thread
From: David Bremner @ 2015-01-20 18:58 UTC (permalink / raw)
  To: Tomi Ollila, notmuch, Jani Nikula; +Cc: tomi.ollila

Tomi Ollila <tomi.ollila@iki.fi> writes:

> This is second draft patch of (first being)
>
> id:1405026779-29966-1-git-send-email-tomi.ollila@iki.fi
>
> I saw potential problem with only supporting emacsclient(1) in
> the version David sent:
> id:1421598115-4889-1-git-send-email-david@tethera.net
>
> (no emacs server running and no tty -- new X client not started)
>

I don't understand what use case is failing for you. I think I tested
all 4 combinations of DISPLAY set and unset and emacs server running and
not running.  Do you somehow want to run the notmuch-emacs-mua script
from a process not attached to a terminal (from cron?).

> In case emacsclient(1) is used and no --no-window-system, '-c' arg is
> given to emacsclient like in the version David sent.
>
> (this means that if emacs is not running on X, user may get this message:
>  "emacsclient: could not get terminal name" -- we need to document user
>  to give -nw (--no-window-system) option then)

As I wrote above, I'm missing what the tradeoff is. The version I sent
works fine (at least for me) in the case where DISPLAY is not set and
--no-window-system is not given (i.e. it's implied if DISPLAY is not
set).

d

^ permalink raw reply	[flat|nested] 17+ messages in thread

* Re: [DRAFT PATCH v2] modified notmuch-emacs-mua v2
  2015-01-20 18:58               ` David Bremner
@ 2015-01-21  9:38                 ` Tomi Ollila
  2015-01-21 16:50                   ` David Bremner
  0 siblings, 1 reply; 17+ messages in thread
From: Tomi Ollila @ 2015-01-21  9:38 UTC (permalink / raw)
  To: David Bremner, notmuch, Jani Nikula

On Tue, Jan 20 2015, David Bremner <david@tethera.net> wrote:

> Tomi Ollila <tomi.ollila@iki.fi> writes:
>
>> This is second draft patch of (first being)
>>
>> id:1405026779-29966-1-git-send-email-tomi.ollila@iki.fi
>>
>> I saw potential problem with only supporting emacsclient(1) in
>> the version David sent:
>> id:1421598115-4889-1-git-send-email-david@tethera.net
>>
>> (no emacs server running and no tty -- new X client not started)
>>
>
> I don't understand what use case is failing for you. I think I tested
> all 4 combinations of DISPLAY set and unset and emacs server running and
> not running.  Do you somehow want to run the notmuch-emacs-mua script
> from a process not attached to a terminal (from cron?).

It seems that you have done good testing and I just failed to test using
exactly the same options you have:

emacsclient -c -a '' .zshrc

Works as one'd expect to work successfully in all cases, DISPLAY set/unset
and emacs-server running or not (now deleting 6 lines of text below that
was based on wrong assumtions...)

// 6 lines of text deleted ... :) //

So, the question goes into deciding whether the magic of starting emacs
server to the user if it is not running -- something that many users would
not anticipate/desire (I am one of those)...

Running emacs via emacsclient has subtle differences to just running emacs
the "regular" way -- while testing I just had problems exiting the
emacsclient session without exiting the whole emacs -- I exited the whole
emacs and next time paid attention to minibuffer message saying c-x 5 0
exits the session...
Now that I got the tests work as David would have expected me to do those,
the frame emacs started looked different that my emacs frames have when
starting "normally" -- there was extra toolbar in the frame (I have
inhibited all menu and toolbars in my normal setup). Just that it behaves
differently is suspicious.

Therefore, IMO it is clearer to run "regular" emacs unless user is
explicitly running emacs-server and can anticipate the behaviour
differences when running emacsclient there.


>> In case emacsclient(1) is used and no --no-window-system, '-c' arg is
>> given to emacsclient like in the version David sent.
>>
>> (this means that if emacs is not running on X, user may get this message:
>>  "emacsclient: could not get terminal name" -- we need to document user
>>  to give -nw (--no-window-system) option then)
>
> As I wrote above, I'm missing what the tradeoff is. The version I sent
> works fine (at least for me) in the case where DISPLAY is not set and
> --no-window-system is not given (i.e. it's implied if DISPLAY is not
> set).

Ok, my tests failed colossally here. Sorry. First, I forgot to have
-a '' there (for comparison) and secondly I closed stdout before
running emacsclient (bug in the script). 

That's what you get after almost 3 hours of vigorous hacking there; the
manual test coverage is probably not the best possible...

>
> d

Tomi

^ permalink raw reply	[flat|nested] 17+ messages in thread

* Re: [DRAFT PATCH v2] modified notmuch-emacs-mua v2
  2015-01-21  9:38                 ` Tomi Ollila
@ 2015-01-21 16:50                   ` David Bremner
  0 siblings, 0 replies; 17+ messages in thread
From: David Bremner @ 2015-01-21 16:50 UTC (permalink / raw)
  To: Tomi Ollila, notmuch, Jani Nikula

Tomi Ollila <tomi.ollila@iki.fi> writes:

>
> So, the question goes into deciding whether the magic of starting emacs
> server to the user if it is not running -- something that many users would
> not anticipate/desire (I am one of those)...
>

Yes, this objection I understand, and even anticipated a bit when
sending the patch. So no problem from my side to make this an option. We
could even even use "notmuch config get" to retrieve the users
preference, although maybe that is overcomplicating things.

d

^ permalink raw reply	[flat|nested] 17+ messages in thread

* [PATCH] cli: add a tool for starting new message in the emacs ui
  2015-01-18 16:21           ` David Bremner
                               ` (2 preceding siblings ...)
  2015-01-20 17:53             ` [DRAFT PATCH v2] modified notmuch-emacs-mua v2 Tomi Ollila
@ 2015-02-22 20:34             ` David Bremner
  2015-03-06  7:06               ` David Bremner
  3 siblings, 1 reply; 17+ messages in thread
From: David Bremner @ 2015-02-22 20:34 UTC (permalink / raw)
  To: David Bremner, notmuch

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.
---
 doc/conf.py                    |   4 ++
 doc/man1/notmuch-emacs-mua.rst |  63 +++++++++++++++++++
 notmuch-emacs-mua              | 136 +++++++++++++++++++++++++++++++++++++++++
 3 files changed, 203 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 fb49f6e..8fbc854 100644
--- a/doc/conf.py
+++ b/doc/conf.py
@@ -78,6 +78,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..eb47098
--- /dev/null
+++ b/doc/man1/notmuch-emacs-mua.rst
@@ -0,0 +1,63 @@
+=================
+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.
+
+Supported options for **notmuch-emacs-mua** include
+
+    ``-h, --help``
+        Display help.
+
+    ``-C, --client``
+        Use emacsclient, rather than emacs. This will start
+        an emacs daemon process if necessary.
+
+    ``-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.
+
+    ``--no-window-system``
+        Even if a window system is available, use the current terminal
+
+    ``--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.
+
+ENVIRONMENT VARIABLES
+=====================
+
+``EMACS``
+Name of emacs command to invoke
+
+``EMACSCLIENT``
+Name of emacsclient comment to invoke
+
+SEE ALSO
+========
+
+**notmuch(1)**, **emacsclient(1)**, **mutt(1)**
diff --git a/notmuch-emacs-mua b/notmuch-emacs-mua
new file mode 100755
index 0000000..b8cbc82
--- /dev/null
+++ b/notmuch-emacs-mua
@@ -0,0 +1,136 @@
+#!/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//\"/\\\"}"
+}
+
+EMACS=${EMACS-emacs}
+EMACSCLIENT=${EMACSCLIENT-emacsclient}
+
+PRINT_ONLY=
+USE_EMACSCLIENT=
+CLIENT_TYPE="-c"
+
+# The crux of it all: construct an elisp progn and eval it.
+ELISP="(prog1 'done (require 'notmuch) (notmuch-mua-new-mail)"
+ELISP="${ELISP} (setq message-exit-actions (list #'save-buffers-kill-terminal))"
+
+while getopts :s:c:b:i:hC opt; do
+    # Handle errors and long options.
+    case "${opt}" in
+	:)
+	    echo "$0: short option -${OPTARG} requires an argument." >&2
+	    exit 1
+	    ;;
+	\?)
+	    opt=$1
+	    if [ "${OPTARG}" != "-" ]; then
+		echo "$0: unknown short option -${OPTARG}." >&2
+		exit 1
+	    fi
+
+	    case "${opt}" in
+		# Long options with arguments.
+		--subject=*|--to=*|--cc=*|--bcc=*|--body=*)
+		    OPTARG=${opt#--*=}
+		    opt=${opt%%=*}
+		    ;;
+		# Long options without arguments.
+		--help|--print|--no-window-system|--client)
+		    ;;
+		*)
+		    echo "$0: unknown long option ${opt}, or argument mismatch." >&2
+		    exit 1
+		    ;;
+	    esac
+	    # getopts does not do this for what it considers errors.
+	    OPTIND=$((OPTIND + 1))
+	    ;;
+    esac
+
+
+    OPTARG="${OPTARG-none}"
+    OPTARG="$(escape "${OPTARG}")"
+
+    case "${opt}" in
+	--help|h)
+	    exec man notmuch-emacs-mua
+	    ;;
+	--client|C)
+	    USE_EMACSCLIENT="yes"
+	    ;;
+	--subject|s)
+	    ELISP="${ELISP} (message-goto-subject) (insert \"${OPTARG}\")"
+	    ;;
+	--to)
+	    ELISP="${ELISP} (message-goto-to) (insert \"${OPTARG}, \")"
+	    ;;
+	--cc|c)
+	    ELISP="${ELISP} (message-goto-cc) (insert \"${OPTARG}, \")"
+	    ;;
+	--bcc|b)
+	    ELISP="${ELISP} (message-goto-bcc) (insert \"${OPTARG}, \")"
+	    ;;
+	--body|i)
+	    ELISP="${ELISP} (message-goto-body) (cd \"${PWD}\") (insert-file \"${OPTARG}\")"
+	    ;;
+	--print)
+	    PRINT_ONLY=1
+	    ;;
+	--no-window-system)
+	    CLIENT_TYPE="-t"
+	    ;;
+	*)
+	    # We should never end up here.
+	    echo "$0: internal error (option ${opt})." >&2
+	    exit 1
+	    ;;
+    esac
+
+    shift $((OPTIND - 1))
+    OPTIND=1
+done
+
+# Positional parameters.
+for arg; do
+    arg="$(escape "${arg}")"
+    ELISP="${ELISP} (message-goto-to) (insert \"${arg}, \")"
+done
+
+# End progn.
+ELISP="${ELISP})"
+
+if [ -n "$PRINT_ONLY" ]; then
+    echo ${ELISP}
+    exit 0
+fi
+
+if [ -n "$USE_EMACSCLIENT" ]; then
+    # Evaluate the progn.
+    exec ${EMACSCLIENT} ${CLIENT_TYPE} -a '' --eval "${ELISP}"
+else
+    exec ${EMACS} --eval "${ELISP}"
+fi
-- 
2.1.4

^ permalink raw reply related	[flat|nested] 17+ messages in thread

* Re: [PATCH] cli: add a tool for starting new message in the emacs ui
  2015-02-22 20:34             ` [PATCH] cli: add a tool for starting new message in the emacs ui David Bremner
@ 2015-03-06  7:06               ` David Bremner
  0 siblings, 0 replies; 17+ messages in thread
From: David Bremner @ 2015-03-06  7:06 UTC (permalink / raw)
  To: notmuch

David Bremner <david@tethera.net> writes:

> 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.

Both Jani and Tomi expressed, if not satisfaction, at least exhaustion
with this version, so I pushed to master.

d

^ permalink raw reply	[flat|nested] 17+ messages in thread

end of thread, other threads:[~2015-03-06  7:08 UTC | newest]

Thread overview: 17+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2014-03-19 19:25 [PATCH] cli: add a tool for starting new message in the emacs ui Jani Nikula
2014-03-19 21:24 ` Tomi Ollila
2014-03-19 21:54   ` Jani Nikula
2014-03-20 10:31     ` Tomi Ollila
2014-04-06 15:43       ` [PATCH v2] " Jani Nikula
2014-04-07  3:59         ` Jameson Graef Rollins
2014-07-01 20:02         ` [PATCH] " David Bremner
2014-07-04 17:36           ` Tomi Ollila
2015-01-18 16:21           ` David Bremner
2015-01-18 21:07             ` Tomi Ollila
2015-01-19 16:32             ` Tomi Ollila
2015-01-20 17:53             ` [DRAFT PATCH v2] modified notmuch-emacs-mua v2 Tomi Ollila
2015-01-20 18:58               ` David Bremner
2015-01-21  9:38                 ` Tomi Ollila
2015-01-21 16:50                   ` David Bremner
2015-02-22 20:34             ` [PATCH] cli: add a tool for starting new message in the emacs ui David Bremner
2015-03-06  7:06               ` David Bremner

Code repositories for project(s) associated with this public inbox

	https://yhetil.org/notmuch.git/

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).