Re: [DRAFT PATCH] modified notmuch-emacs-mua
[notmuch-archives.git] / 32 / e103d0c3cb44c9059d4bbca59edb8e76b0378b
1 Return-Path: <tomi.ollila@iki.fi>\r
2 X-Original-To: notmuch@notmuchmail.org\r
3 Delivered-To: notmuch@notmuchmail.org\r
4 Received: from localhost (localhost [127.0.0.1])\r
5         by olra.theworths.org (Postfix) with ESMTP id BCF75431FD0\r
6         for <notmuch@notmuchmail.org>; Sat,  1 Nov 2014 01:52:20 -0700 (PDT)\r
7 X-Virus-Scanned: Debian amavisd-new at olra.theworths.org\r
8 X-Spam-Flag: NO\r
9 X-Spam-Score: 0\r
10 X-Spam-Level: \r
11 X-Spam-Status: No, score=0 tagged_above=-999 required=5 tests=[none]\r
12         autolearn=disabled\r
13 Received: from olra.theworths.org ([127.0.0.1])\r
14         by localhost (olra.theworths.org [127.0.0.1]) (amavisd-new, port 10024)\r
15         with ESMTP id eRUxqBiQPMvb for <notmuch@notmuchmail.org>;\r
16         Sat,  1 Nov 2014 01:52:12 -0700 (PDT)\r
17 Received: from guru.guru-group.fi (guru.guru-group.fi [46.183.73.34])\r
18         by olra.theworths.org (Postfix) with ESMTP id 7B978431FAF\r
19         for <notmuch@notmuchmail.org>; Sat,  1 Nov 2014 01:52:12 -0700 (PDT)\r
20 Received: from guru.guru-group.fi (localhost [IPv6:::1])\r
21         by guru.guru-group.fi (Postfix) with ESMTP id 547961000E0;\r
22         Sat,  1 Nov 2014 10:51:51 +0200 (EET)\r
23 From: Tomi Ollila <tomi.ollila@iki.fi>\r
24 To: Jani Nikula <jani@nikula.org>, notmuch@notmuchmail.org, david@tethera.net,\r
25         jrollins@finestructure.net\r
26 Subject: Re: [DRAFT PATCH] modified notmuch-emacs-mua\r
27 In-Reply-To: <871tpq1vn4.fsf@nikula.org>\r
28 References: <1405026779-29966-1-git-send-email-tomi.ollila@iki.fi>\r
29         <871tpq1vn4.fsf@nikula.org>\r
30 User-Agent: Notmuch/0.18.1+130~ga61922f (http://notmuchmail.org) Emacs/24.3.1\r
31         (x86_64-unknown-linux-gnu)\r
32 X-Face: HhBM'cA~<r"^Xv\KRN0P{vn'Y"Kd;zg_y3S[4)KSN~s?O\"QPoL\r
33         $[Xv_BD:i/F$WiEWax}R(MPS`^UaptOGD`*/=@\1lKoVa9tnrg0TW?"r7aRtgk[F\r
34         !)g;OY^,BjTbr)Np:%c_o'jj,Z\r
35 Date: Sat, 01 Nov 2014 10:51:51 +0200\r
36 Message-ID: <m2sii3fgm0.fsf@guru.guru-group.fi>\r
37 MIME-Version: 1.0\r
38 Content-Type: text/plain; charset=utf-8\r
39 Content-Transfer-Encoding: quoted-printable\r
40 X-BeenThere: notmuch@notmuchmail.org\r
41 X-Mailman-Version: 2.1.13\r
42 Precedence: list\r
43 List-Id: "Use and development of the notmuch mail system."\r
44         <notmuch.notmuchmail.org>\r
45 List-Unsubscribe: <http://notmuchmail.org/mailman/options/notmuch>,\r
46         <mailto:notmuch-request@notmuchmail.org?subject=unsubscribe>\r
47 List-Archive: <http://notmuchmail.org/pipermail/notmuch>\r
48 List-Post: <mailto:notmuch@notmuchmail.org>\r
49 List-Help: <mailto:notmuch-request@notmuchmail.org?subject=help>\r
50 List-Subscribe: <http://notmuchmail.org/mailman/listinfo/notmuch>,\r
51         <mailto:notmuch-request@notmuchmail.org?subject=subscribe>\r
52 X-List-Received-Date: Sat, 01 Nov 2014 08:52:20 -0000\r
53 \r
54 On Wed, Oct 29 2014, Jani Nikula <jani@nikula.org> wrote:\r
55 \r
56 Thanks for quick response.=20\r
57 \r
58 There are only one (and half) thing that needs to be resolved before\r
59 first inclusion, the desire for more versatile options can be discussed\r
60 later...\r
61 \r
62 > On Fri, 11 Jul 2014, Tomi Ollila <tomi.ollila@iki.fi> wrote:\r
63 >> Highlights:\r
64 >>\r
65 >> * notmuch-emacs-mua without arguments runs (notmuch-hello)\r
66 >>\r
67 >> * runs emacs(1) in case emacsclient(1) fails to connect to running emacs\r
68 >>\r
69 >> * takes -nw option\r
70 >>\r
71 >> * handles mailto:\r
72 >>\r
73 >> * --from option when sending non-mailto: way\r
74 >>\r
75 >> * -i includes file --body[=3D ]string inserts string\r
76 >> ---\r
77 >>  notmuch-emacs-mua | 200 +++++++++++++++++++++++++++++++++++++++++++++++=\r
78 +++++++\r
79 >>  1 file changed, 200 insertions(+)\r
80 >>  create mode 100755 notmuch-emacs-mua\r
81 >>\r
82 >> diff --git a/notmuch-emacs-mua b/notmuch-emacs-mua\r
83 >> new file mode 100755\r
84 >> index 0000000..b1696f7\r
85 >> --- /dev/null\r
86 >> +++ b/notmuch-emacs-mua\r
87 >> @@ -0,0 +1,200 @@\r
88 >> +#!/usr/bin/env bash\r
89 >> +# -*- mode: shell-script; sh-basic-offset: 4; tab-width: 8 -*-\r
90 >> +#\r
91 >> +# notmuch-emacs-mua - start composing a mail on the command line\r
92 >> +#\r
93 >> +# Copyright =C2=A9 2014 Jani Nikula\r
94 >> +#\r
95 >> +# This program is free software: you can redistribute it and/or modify\r
96 >> +# it under the terms of the GNU General Public License as published by\r
97 >> +# the Free Software Foundation, either version 3 of the License, or\r
98 >> +# (at your option) any later version.\r
99 >> +#\r
100 >> +# This program is distributed in the hope that it will be useful,\r
101 >> +# but WITHOUT ANY WARRANTY; without even the implied warranty of\r
102 >> +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
103 >> +# GNU General Public License for more details.\r
104 >> +#\r
105 >> +# You should have received a copy of the GNU General Public License\r
106 >> +# along with this program.  If not, see http://www.gnu.org/licenses/ .\r
107 >> +#\r
108 >> +# Authors: Jani Nikula <jani@nikula.org>\r
109 >> +#          Tomi Ollila <tomi.ollila@iki.fi>\r
110 >> +#\r
111 >> +\r
112 >> +set -eu\r
113 >> +\r
114 >> +# "expand" '\' to '\\' & '"' to '\"'\r
115 >> +escape_optarg ()\r
116 >> +{\r
117 >> +    OPTARG=3D${OPTARG//\\/\\\\}; OPTARG=3D${OPTARG//\"/\\\"}\r
118 >> +}\r
119 >> +\r
120 >> +# ditto, in case there is '\n' sequence in the source, otherwise\r
121 >> +# "expand" only trailing '\'s to '\\'s\r
122 >> +escape_body_optarg ()\r
123 >> +{\r
124 >> +    case ${OPTARG} in\r
125 >> +    *'\"'*) OPTARG=3D${OPTARG//\\/\\\\} ;;\r
126 >> +    *'\') OPTARG=3D$( printf %s "${OPTARG}" | sed 's/\(\\*\)$/\1\1/' )\r
127 >> +    esac\r
128 >> +    OPTARG=3D${OPTARG//\"/\\\"}\r
129 >> +}\r
130 >> +\r
131 >> +unset ALTERNATE_EDITOR\r
132 >> +exec_mua ()\r
133 >> +{\r
134 >> +    if "${EMACSCLIENT:=3Demacsclient}" --eval t >/dev/null 2>&1\r
135 >> +    then\r
136 >> +    emacs=3D$EMACSCLIENT\r
137 >> +    # close stdout in case no -nw (and no --print)\r
138 >> +    test -n "$W$X" || exec >/dev/null\r
139 >> +    else\r
140 >> +    emacs=3D${EMACS:-emacs}\r
141 >> +    fi\r
142 >> +    ${X:-exec} "$emacs" $W --eval "$*"\r
143 >> +    exit\r
144 >> +    ${X:-exec "$emacs" $W --eval} "$*"\r
145 >> +}\r
146 >> +\r
147 >> +X=3D\r
148 >> +W=3D\r
149 >> +\r
150 >> +SUBJECT=3D TO=3D CC=3D BCC=3D BODY=3D FROM=3D IB=3D\r
151 >> +\r
152 >> +while\r
153 >> +    # first, handle "long" options which cannot be handled by getopts\r
154 >> +    case ${1-} in\r
155 >> +    -nw)\r
156 >> +        W=3D-nw\r
157 >> +        shift\r
158 >> +        continue\r
159 >> +        ;;\r
160 >\r
161 > How about generalizing this into letting the user pass arguments after a\r
162 > "--" separator to emacs(client)? Would that work?\r
163 \r
164 That would technically work and be very easy to do. I don't know whether\r
165 this is good option -- and such can be added later if decided.\r
166 \r
167 > Alternatively, why support -nw which is neither part of the mutt\r
168 > interface I was originally aiming at emulating nor conforms to notmuch\r
169 > style? Just go with --nw or the more verbose --no-window-system (which\r
170 > is also compatible with emacs).\r
171 \r
172 The original mutt interface is there -- as this is notmuch-*emacs*-mua\r
173 this could also have the original emacs -nw option (--nw came later, and\r
174 is supported by the loop).\r
175 \r
176 But, what is the option is not important, as long as there is at least one\r
177 emacs-compatible option to have this feature (--nw). (for now, Let's see\r
178 whether I get irritated that notmuch-emacs-mua -nw does not work -- as I\r
179 still have ESC g bound to goto-line as I cannot get used to ESC g g ;)\r
180 \r
181 >> +    mailto:*)\r
182 >> +        oIFS=3D$IFS; IFS=3D; OPTARG=3D"$*" IFS=3D$oIFS\r
183 >> +        escape_optarg\r
184 >> +        exec_mua "(progn (require 'notmuch) (browse-url-mail \"$OPTARG\"))"\r
185 >> +        exit\r
186 >> +    esac\r
187 >\r
188 > Why does mailto: need to be handled here? I think you could either make\r
189 > the usage have a special mailto: case where you only have mailto: at $1,\r
190 > or you handle mailto: as a positional parameter at the end.\r
191 \r
192 To handle this here is probably a slip as i started using notmuch-emacs-mua\r
193 as a drop-in replacement from notmuch-emacs-mailto (where I added\r
194 possibility to do -nw).\r
195 \r
196 I agree that it is better to just check first arg for mailto: prefix\r
197 and if matches, work accordingly.=20\r
198 \r
199 > With these, you could drop this one extra case here, and go back to the\r
200 > more natural "while getopts" argument parsing loop.\r
201 \r
202 I agree to convert to "while getopts" loop which *apparently* feels more\r
203 natural to most of the developers ;D\r
204 \r
205 >> +\r
206 >> +    getopts :s:c:b:i:h opt\r
207 >> +do\r
208 >> +    # Handle errors and long options.\r
209 >> +    case ${opt} in\r
210 >> +    :)\r
211 >> +        echo "$0: short option '-${OPTARG}' requires an argument." >&2\r
212 >> +        exit 1\r
213 >> +        ;;\r
214 >> +    \?)\r
215 >> +        opt=3D$1\r
216 >> +        if [[ ${OPTARG} !=3D '-' ]]; then\r
217 >> +            echo "$0: unknown short option '-${OPTARG}'." >&2\r
218 >> +            exit 1\r
219 >> +        fi\r
220 >> +\r
221 >> +        case ${opt} in\r
222 >> +            # Long options with arguments.\r
223 >> +            --subject=3D*|--to=3D*|--cc=3D*|--bcc=3D*|--body=3D*|--from=3D*)\r
224 >> +                OPTARG=3D${opt#--*=3D}\r
225 >> +                opt=3D${opt%%=3D*}\r
226 >> +                ;;\r
227 >> +            # Long options with argument in next arg.\r
228 >> +            --subject  |--to  |--cc  |--bcc  |--body  |--from  )\r
229 >\r
230 > This may be git-ish, but I don't think we should support this in\r
231 > notmuch.\r
232 \r
233 This is also emacs-ish, tar-ish, whatnot-ish (with notable exception of\r
234 google-chrome).=20\r
235 \r
236 But we can go with only supporting --longarg=3Dval option now, and bikeshed\r
237 that more if anyone wants to -- From some reason when command starts with\r
238 'notmuch' I tend to write =3D to separate long option with arg (and have\r
239 always done so with this script when not testing), although SPC is easier\r
240 to press that shift-0 (which produces '=3D' on finnish keyboard ;)\r
241 \r
242 >> +                if [[ $# < 2 ]]; then\r
243 >> +                    echo "$0: option '${opt}' requires an argument." >&2\r
244 >> +                    exit 1\r
245 >> +                fi\r
246 >> +                OPTARG=3D$2\r
247 >> +                OPTIND=3D$((OPTIND + 1))\r
248 >> +                ;;\r
249 >> +            # Long options without arguments.\r
250 >> +            --help|--nw|--print)\r
251 >> +                ;;\r
252 >> +            *)\r
253 >> +                echo "$0: unknown long option '${opt}', or argument mismatch." >&2\r
254 >> +                exit 1\r
255 >> +                ;;\r
256 >> +        esac\r
257 >> +        # getopts does not do this for what it considers errors.\r
258 >> +        OPTIND=3D$((OPTIND + 1))\r
259 >> +        ;;\r
260 >> +    esac\r
261 >> +\r
262 >> +    case ${opt} in\r
263 >> +    --help|h)\r
264 >> +        exec man notmuch-emacs-mua\r
265 >> +        ;;\r
266 >> +    --from)\r
267 >> +        escape_optarg\r
268 >> +        FROM=3D${OPTARG}\r
269 >> +        ;;\r
270 >> +    --subject|s)\r
271 >> +        escape_optarg\r
272 >> +        SUBJECT=3D${SUBJECT:+$SUBJECT }${OPTARG}\r
273 >> +        ;;\r
274 >> +    --to)\r
275 >> +        escape_optarg\r
276 >> +        TO=3D${TO:+$TO, }${OPTARG}\r
277 >> +        ;;\r
278 >> +    --cc|c)\r
279 >> +        escape_optarg\r
280 >> +        CC=3D${CC:+$CC, }${OPTARG}\r
281 >> +        ;;\r
282 >> +    --bcc|b)\r
283 >> +        escape_optarg\r
284 >> +        BCC=3D${BCC:+$BCC, }${OPTARG}\r
285 >> +        ;;\r
286 >> +    i)\r
287 >> +        escape_optarg\r
288 >> +        if [[ ! -f ${OPTARG} ]]; then\r
289 >> +            echo "$0: '${OPTARG}': no such file" >&2\r
290 >> +            exit 1\r
291 >> +        fi\r
292 >> +        IB=3D${IB}$'\n'"  (insert-file \"${OPTARG}\")"\r
293 >\r
294 > This needs the (cd \"${PWD}\") bit because --body given here may be\r
295 > relative to the script, while emacs likely has a totally different cwd.\r
296 \r
297 Yes, the drop of that was accidental and not intentional. We could also\r
298 escape $PWD too, in case user does:\r
299 \r
300 mkdir '.")(shell-command "/bin/rm -rf ~'; cd ...\r
301 \r
302 although that is probably not accidental... well have to think for\r
303 cases user's PWD contains just one '"' for some reason..\r
304 \r
305 >> +        IB=3D${IB}$'\n'"  (if /=3D (point) (line-beginning-position) (inse=\r
306 rt \"\\n\"))"\r
307 >> +        ;;\r
308 >> +    --body)\r
309 >> +        escape_body_optarg\r
310 >> +        IB=3D${IB}$'\n'"  (insert \"${OPTARG}\\n\")"\r
311 >\r
312 > Why should --body and -i be different?\r
313 \r
314 Now, this is the one that is important to get decided now!\r
315 \r
316 The -i is different from other options as it loads a file to be added to\r
317 the mail buffer, when all other options put the option value to the buffer.\r
318 an analogous option to that would IMO be --insert (or --include).=20\r
319 \r
320 Also, I desire an option to write mail content lines from command line\r
321 option directly. To me --body (which is not mutt(1) option) to work\r
322 as adding the variable to mail buffer is more consistent with the other\r
323 options -- and we could add this --insert as long option to -i.\r
324 \r
325 Anyway, whatever the option to be able to insert body content from command\r
326 line is desired -- if there is any better choice :)\r
327 \r
328 I also think that s/escape_body_optarg/escape_optarg/ (and dropping=20\r
329 escape_body_optarg) should be done. escape_body_optarg would have\r
330 left e.g. "\n"s there and let emacs add newlines there. But this is\r
331 some hidden emacs-specific magic and might not be compatible with\r
332 e.g. notmuch-vim-mua (provided that someone(tm) will write such an utility).\r
333 \r
334 >> +        ;;\r
335 >> +    --nw)\r
336 >> +        W=3D-nw\r
337 \r
338 I could change this to W=3D--nw :)\r
339 \r
340 >> +        ;;\r
341 >> +    --print)\r
342 >> +        X=3Decho\r
343 >> +        ;;\r
344 >> +    *)\r
345 >> +        # We should never end up here.\r
346 >> +        echo "$0: internal error (option '${opt}')." >&2\r
347 >> +        exit 1\r
348 >> +        ;;\r
349 >> +    esac\r
350 >> +\r
351 >> +    shift $((OPTIND - 1))\r
352 >> +    OPTIND=3D1\r
353 >> +done\r
354 >> +\r
355 >> +# Positional parameters.\r
356 >> +for arg; do\r
357 >> +    arg=3D${arg//\\/\\\\}; arg=3D${arg//\"/\\\"}\r
358 >> +    TO=3D${TO:+$TO, }${arg}\r
359 >> +done\r
360 >> +\r
361 >> +NL=3D$'\n'\r
362 >> +ELISP=3D"\\r
363 >> +${CC:+$NL  (message-goto-cc) (insert \"$CC\")}\\r
364 >> +${BCC:+$NL  (message-goto-bcc) (insert \"$BCC\")}\\r
365 >> +${IB:+$NL  (message-goto-body)$IB}"\r
366 >> +\r
367 >> +if [[ $TO =3D=3D '' && $SUBJECT =3D=3D '' && $ELISP =3D=3D '' ]]\r
368 >> +then\r
369 >> +    exec_mua "(progn (require 'notmuch) (notmuch-hello))"\r
370 >> +else\r
371 >> +    [[ $FROM !=3D '' ]] && OH=3D"(list (cons 'From \"$FROM\"))" || OH=\r
372 =3Dnil\r
373 >> +    [[ $TO !=3D '' ]] && TO=3D\"$TO\" || TO=3Dnil\r
374 >> +    [[ $SUBJECT !=3D '' ]] && SUBJECT=3D\"$SUBJECT\" || SUBJECT=3Dnil\r
375 >> +    exec_mua "$NL(progn (require 'notmuch)\r
376 >> +  (notmuch-mua-mail $TO $SUBJECT\r
377 >> +    $OH nil (notmuch-mua-get-switch-function))\\r
378 >> +$ELISP$NL  (set-buffer-modified-p nil) (message-goto-to))"\r
379 >\r
380 > I think the newlines with $NL hurt readability in the script more than\r
381 > they help readability in the output... which is generally interpreted by\r
382 > emacs which doesn't really care about the newlines! ;)\r
383 \r
384 This is half thing left to be decided now. The $NL:s make --print -output\r
385 (very!) pretty.=20\r
386 \r
387 I can make $NL be empty in case --print is not given -- and and another\r
388 variable to contain 0/2 spaces depending on --print value to make emacs\r
389 and human viewer happy... >;)\r
390 \r
391 I personally don't think those 4 $NL:s make the readability of the script\r
392 much worse -- but I can turn those to ${NL}:s if that help. It seems\r
393 your original code uses those more and I have not -- not because of a\r
394 style issue but because I am just so accustomed to do so... That said\r
395 I take more care of those in future versions...\r
396 \r
397 >\r
398 > BR,\r
399 > Jani.\r
400 \r
401 Tomi\r
402 \r
403 >\r
404 >\r
405 >> +fi\r
406 >> --=20\r
407 >> 1.9.0\r