Subject: Re: bug#65902: 29.0.92; emacsclient-mail.desktop fails due to complicated escaping

From: Eli Zaretskii <[email-masked]>
Date: Sun, 24 Sep 2023 08:18:45 +0300

> From: [email-masked]
> Date: Sat, 23 Sep 2023 20:24:07 +0000 (UTC)
> Cc: [email-masked], [email-masked], [email-masked]
> 
> > IIUC, this kind of solution is fine by me, but the protocol of
> > accessing and using server-eval-args-left in the Lisp expressions
> > specified on the emacsclient command line should be well-documented to
> > avoid any confusion and UB.
> 
> Added a docstring and included it in NEWS.  I would have put it in the
> manual, but it seems rather niche to put in the Emacs manual and I
> didn't see a natural place to put it in the Emacs Lisp manual.

The natural place is in the Emacs user manual, in "emacsclient
Options", where --eval is described.  Where else?

> Passing arbitrary arguments to functions through emacsclient --eval
> requires complicated escaping to avoid them being parsed as Lisp (as
> seen in emacsclient-mail.desktop before this change).
> 
> This new variable server-eval-args-left allows access to the arguments
> before they are parsed as Lisp.  By removing arguments from the
> variable before they're parsed, a snippet of Lisp can consume
> arguments, as in emacsclient-mail.desktop.
> 
> org-protocol might be able to use this as well, which might allow it
> to drop its current advice on server-visit-files.

The right place to keep this information is in the manual and the doc
strings, not just in the Git commit log message.

> +(defvar server-eval-args-left nil
> +  "List of eval args not yet processed.
> +
> +When the server receives a request to eval one or more strings,
> +it stores them in this variable.  Then, until this variable is
> +nil, it `pop's a string from this variable and evaluates it with
> +`server-eval-and-print'.  Adding or removing strings from this
> +variable during this process will affect what is evaluated.

This describes the implementation rather than the intended usage.

> +This allows an expression passed to \"emacsclient --eval\" to
> +consume one or more subsequent arguments before they're parsed or
> +evaluated, with (pop server-eval-args-left).  This is useful if
> +those arguments are arbitrary strings which should not be
> +evaluated.

This describes a way of using this, but without the important part:
that any processed argument _must_ be popped, or it will be evaluated
again.  See the doc string of command-line-functions for what I have
in mind.

All in all, I think this should be rewritten in terms of how to use
this, and the result moved to the Emacs manual, leaving just the
minimum here.

> +See also `command-line-args-left' for a similar variable which
> +works for command line invocations of \"emacs\".")

This "see also" is not useful, because the doc string of
command-line-args-left is minimal and doesn't add any information
(which is okay, since that variable is basically meant for internal
Emacs handling of command-line arguments, unlike this one).

> --- a/lisp/startup.el
> +++ b/lisp/startup.el
> @@ -120,7 +120,10 @@ command-switch-alist
>      "List of command-line args not yet processed.
>  This is a convenience alias, so that one can write (pop argv)
>  inside of --eval command line arguments in order to access
> -following arguments."))
> +following arguments.
> +
> +See also `server-eval-args-left' for a similar variable which
> +works for invocations of \"emacsclient --eval\"."))

And neither is this, because the use cases of the two variables are
almost completely unrelated.