unofficial mirror of emacs-devel@gnu.org 
 help / color / mirror / code / Atom feed
* (unknown)
@ 2023-11-18  3:13 Greg Minshall
  2023-11-18  7:05 ` (unknown) Jim Porter
                   ` (2 more replies)
  0 siblings, 3 replies; 26+ messages in thread
From: Greg Minshall @ 2023-11-18  3:13 UTC (permalink / raw)
  To: emacs-devel

hi.  i would like to be able to write Emacs scripts ("#!...") that allow
a user to enter almost any option to the script itself, *without* having
to use double dashes ("--") to avoid colliding with Emacs option
processing.

looking at "--script" and "-x", this doesn't seem possible.

as a test case, given a simple script foo.sh (*), using "-x", and
invoking it with an option "--eval" gives this error:

----
% ./foo.sh --eval
emacs: Option '--eval' requires an argument
----

(that bare "--eval" *should* be an error if it were meant for Emacs
itself; however, it is meant for the Emacs script, which may have other
ideas of the syntax/semantics of "--eval".)

the below patch to src/emacs.c (**) treats a "-x" (and its "partner"
"-scripteval") like a "--" on the command line, and *seems* to allow
arbitrary options on the command line.  for example, with this patch
installed:

----
% ./foo.sh --eval
command-line-args-left (--eval)
----


i wonder if this might be of use for Emacs?  if there are worries about
backwards compatibility with "-x", well ... "-y" anybody?  :)

(i was thinking of writing a test to go with the patch, but the ERT
framework is maybe a bit awkward for tests of essentially
shell-command-line functionality.  i may have missed it, but i didn't
see anything in ./test/Makefile.in that seemed to be aimed at testing
command-line invocation of Emacs.)

cheers, Greg


(*) foo.sh
----
#!/usr/bin/env -S emacs -x

(message "command-line-args-left %s" command-line-args-left)

1
----


(**) proposed patch
----
diff --git a/src/emacs.c b/src/emacs.c
index 6101ed4004c..6e140177086 100644
--- a/src/emacs.c
+++ b/src/emacs.c
@@ -2795,9 +2795,10 @@ sort_args (int argc, char **argv)
        {
          int match;

-         /* If we have found "--", don't consider
-            any more arguments as options.  */
-         if (argv[from][1] == '-' && argv[from][2] == 0)
+         /* If we have found "--", or a "-x", don't consider any more
+            arguments as options.  */
+         if ((((argv[from][1] == '-') || (argv[from][1] == 'x')) && argv[from][2] == 0)
+             || !strcmp(argv[from], "-scripteval"))
            {
              /* Leave the "--", and everything following it, at the end.  */
              for (; from < argc; from++)
----



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

* Re: (unknown)
  2023-11-18  3:13 (unknown) Greg Minshall
@ 2023-11-18  7:05 ` Jim Porter
  2023-11-18 14:10   ` (unknown) -x behavior change Greg Minshall
  2023-11-18  7:36 ` Emacs script options Eli Zaretskii
  2023-11-18 19:18 ` Sebastian Miele
  2 siblings, 1 reply; 26+ messages in thread
From: Jim Porter @ 2023-11-18  7:05 UTC (permalink / raw)
  To: Greg Minshall, emacs-devel

On 11/17/2023 7:13 PM, Greg Minshall wrote:
> (i was thinking of writing a test to go with the patch, but the ERT
> framework is maybe a bit awkward for tests of essentially
> shell-command-line functionality.  i may have missed it, but i didn't
> see anything in ./test/Makefile.in that seemed to be aimed at testing
> command-line invocation of Emacs.)

You could probably take some inspiration from the "Synchronous 
processes" section of the file test/lisp/eshell/esh-proc-tests.el. 
Essentially, you can just start a new Emacs instance in your ERT test 
and do whatever you like.



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

* Re: Emacs script options
  2023-11-18  3:13 (unknown) Greg Minshall
  2023-11-18  7:05 ` (unknown) Jim Porter
@ 2023-11-18  7:36 ` Eli Zaretskii
  2023-11-18 14:38   ` Greg Minshall
  2023-11-27  3:29   ` Greg Minshall
  2023-11-18 19:18 ` Sebastian Miele
  2 siblings, 2 replies; 26+ messages in thread
From: Eli Zaretskii @ 2023-11-18  7:36 UTC (permalink / raw)
  To: Greg Minshall; +Cc: emacs-devel

> From: Greg Minshall <minshall@umich.edu>
> Date: Fri, 17 Nov 2023 19:13:56 -0800
> 
> hi.  i would like to be able to write Emacs scripts ("#!...") that allow
> a user to enter almost any option to the script itself, *without* having
> to use double dashes ("--") to avoid colliding with Emacs option
> processing.
> 
> looking at "--script" and "-x", this doesn't seem possible.
> 
> as a test case, given a simple script foo.sh (*), using "-x", and
> invoking it with an option "--eval" gives this error:
> 
> ----
> % ./foo.sh --eval
> emacs: Option '--eval' requires an argument
> ----
> 
> (that bare "--eval" *should* be an error if it were meant for Emacs
> itself; however, it is meant for the Emacs script, which may have other
> ideas of the syntax/semantics of "--eval".)

But if we change that, how can we pass additional options to Emacs
when invoking it from a script?  That is also an important capability,
and replacing it with what you want seems to be an incompatible
change, which takes away a capability we have now.

If we want to be able to pass options to the script itself, we need to
do it in a compatible way, that doesn't lose what we have now.

In any case, could you please show a real-life case where this is
needed?  The -x option was intended to support the use cases where the
rest of the script is Emacs Lisp code, so what would such a script do
with an option that is not interpreted by Emacs, and why is that
needed?

Thanks.



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

* Re: (unknown) -x behavior change
  2023-11-18  7:05 ` (unknown) Jim Porter
@ 2023-11-18 14:10   ` Greg Minshall
  0 siblings, 0 replies; 26+ messages in thread
From: Greg Minshall @ 2023-11-18 14:10 UTC (permalink / raw)
  To: Jim Porter; +Cc: emacs-devel

Jim Porter <jporterbugs@gmail.com> wrote:

> You could probably take some inspiration from the "Synchronous
> processes" section of the file
> test/lisp/eshell/esh-proc-tests.el. Essentially, you can just start a
> new Emacs instance in your ERT test and do whatever you like.

thanks.  that looks likely.

cheers, Greg

ps -- sorry, all, for the lack of Subject:



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

* Re: Emacs script options
  2023-11-18  7:36 ` Emacs script options Eli Zaretskii
@ 2023-11-18 14:38   ` Greg Minshall
  2023-11-18 16:20     ` Eli Zaretskii
  2023-11-27  3:29   ` Greg Minshall
  1 sibling, 1 reply; 26+ messages in thread
From: Greg Minshall @ 2023-11-18 14:38 UTC (permalink / raw)
  To: Eli Zaretskii; +Cc: emacs-devel

Eli Zaretskii <eliz@gnu.org> wrote:

> But if we change that, how can we pass additional options to Emacs
> when invoking it from a script?  That is also an important capability,
> and replacing it with what you want seems to be an incompatible
> change, which takes away a capability we have now.
> 
> If we want to be able to pass options to the script itself, we need to
> do it in a compatible way, that doesn't lose what we have now.
> 
> In any case, could you please show a real-life case where this is
> needed?  The -x option was intended to support the use cases where the
> rest of the script is Emacs Lisp code, so what would such a script do
> with an option that is not interpreted by Emacs, and why is that
> needed?

this last point is maybe all i can answer now (your other points are
food for thought, and code-staring).  the idea is a generalized facility
that allows script-writers to do whatever they want, define whatever
options they want.

plus, trying to stay out of the way of even current, let alone future,
Emacs options is tricky; realistically, script-writers would need to
require their users to always type double-dashes, e.g.,
----
ls-emacs -- -F
----
which doesn't seem so user-friendly.

in my case, for example, i want to write an Emacs script that has some
familiar options like "-d", "-V", etc., in addition to options to
specify how the script should run (what input files to process, output
files to produce, alterations to behavior).

i could have users do that in an Emacs'y way ('--eval (setq debug 1)').
but, the idea is to provide something that, to the end user, looks like
a standard Unix'y script.  if that makes any sense.

cheers, Greg



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

* Re: Emacs script options
  2023-11-18 14:38   ` Greg Minshall
@ 2023-11-18 16:20     ` Eli Zaretskii
  2023-11-18 19:36       ` Greg Minshall
  0 siblings, 1 reply; 26+ messages in thread
From: Eli Zaretskii @ 2023-11-18 16:20 UTC (permalink / raw)
  To: Greg Minshall; +Cc: emacs-devel

> cc: emacs-devel@gnu.org
> From: Greg Minshall <minshall@umich.edu>
> Comments: In-reply-to Eli Zaretskii <eliz@gnu.org>
>    message dated "Sat, 18 Nov 2023 09:36:36 +0200."
> Date: Sat, 18 Nov 2023 06:38:24 -0800
> 
> Eli Zaretskii <eliz@gnu.org> wrote:
> 
> > In any case, could you please show a real-life case where this is
> > needed?  The -x option was intended to support the use cases where the
> > rest of the script is Emacs Lisp code, so what would such a script do
> > with an option that is not interpreted by Emacs, and why is that
> > needed?
> 
> this last point is maybe all i can answer now (your other points are
> food for thought, and code-staring).  the idea is a generalized facility
> that allows script-writers to do whatever they want, define whatever
> options they want.
> 
> plus, trying to stay out of the way of even current, let alone future,
> Emacs options is tricky; realistically, script-writers would need to
> require their users to always type double-dashes, e.g.,
> ----
> ls-emacs -- -F
> ----
> which doesn't seem so user-friendly.
> 
> in my case, for example, i want to write an Emacs script that has some
> familiar options like "-d", "-V", etc., in addition to options to
> specify how the script should run (what input files to process, output
> files to produce, alterations to behavior).

How would you pass these -F, -d, -V etc. options to Emacs, or use them
in any other way in the script, whose contents is supposed to be an
Emacs Lisp program?  There's something I'm missing here.  I asked my
question because I thought you had a real-life example of a script you
wanted to use, but in your response you don't show any such example.
Can you show it?



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

* Re: Emacs script options
  2023-11-18  3:13 (unknown) Greg Minshall
  2023-11-18  7:05 ` (unknown) Jim Porter
  2023-11-18  7:36 ` Emacs script options Eli Zaretskii
@ 2023-11-18 19:18 ` Sebastian Miele
  2023-11-18 19:49   ` Greg Minshall
  2023-11-19  5:04   ` Bob Rogers
  2 siblings, 2 replies; 26+ messages in thread
From: Sebastian Miele @ 2023-11-18 19:18 UTC (permalink / raw)
  To: Greg Minshall; +Cc: emacs-devel

> From: Greg Minshall <minshall@umich.edu>
> Date: Fri, 2023-11-17 19:13 -0800
>
> hi.  i would like to be able to write Emacs scripts ("#!...") that allow
> a user to enter almost any option to the script itself, *without* having
> to use double dashes ("--") to avoid colliding with Emacs option
> processing.
>
> looking at "--script" and "-x", this doesn't seem possible.
>
> as a test case, given a simple script foo.sh (*), using "-x", and
> invoking it with an option "--eval" gives this error:
>
> ----
> % ./foo.sh --eval
> emacs: Option '--eval' requires an argument
> ----
>
> (that bare "--eval" *should* be an error if it were meant for Emacs
> itself; however, it is meant for the Emacs script, which may have other
> ideas of the syntax/semantics of "--eval".)
>
> the below patch to src/emacs.c (**) treats a "-x" (and its "partner"
> "-scripteval") like a "--" on the command line, and *seems* to allow
> arbitrary options on the command line.  for example, with this patch
> installed:
>
> ----
> % ./foo.sh --eval
> command-line-args-left (--eval)
> ----

On Linux that can be achieved by defining a custom interpreter.  E.g.,
put the following into ‘/path/to/emacs-script’:

  #!/bin/sh
  script=$1
  shift
  exec emacs -Q --batch --load $script -- "$@"

Then, with the following in a ‘test-script’

  #!/path/to/emacs-script
  ;; -*- mode: emacs-lisp; lexical-binding: t -*-
  (message "%s" command-line-args-left)

‘test-script --eval’ prints "(-- --eval)".

On Linux, and when ‘emacs-script’ is in the PATH, the ‘/path/to/’ in the
shebang even can be omitted.

However, the workaround is not possible on at least some non-Linux
systems, because not all systems allow something interpreted as an
interpreter in a shebang, see
https://en.wikipedia.org/wiki/Shebang_(Unix)#Syntax.



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

* Re: Emacs script options
  2023-11-18 16:20     ` Eli Zaretskii
@ 2023-11-18 19:36       ` Greg Minshall
  2023-11-19  5:55         ` Eli Zaretskii
  0 siblings, 1 reply; 26+ messages in thread
From: Greg Minshall @ 2023-11-18 19:36 UTC (permalink / raw)
  To: Eli Zaretskii; +Cc: emacs-devel

Eli Zaretskii <eliz@gnu.org> wrote:

> How would you pass these -F, -d, -V etc. options to Emacs, or use them
> in any other way in the script, whose contents is supposed to be an
> Emacs Lisp program?  There's something I'm missing here.  I asked my
> question because I thought you had a real-life example of a script you
> wanted to use, but in your response you don't show any such example.
> Can you show it?

in this case, the -F, -d, -V are aimed at the elisp code running in the
script, not for Emacs itself.

think of wanting to convert some random unix utility to run as an Emacs
script (rather than as a shell script, say), and trying to make the
command line options (and invocation) the same as the original shell
script.  does that help clarify?

in my case, i have the beginnings of a shell script that is to set up
some state and then invoke Emacs to do some work (org mode stuff).  its
projected getopt(1) strings look like
----
getopt -o "B:C:dhP:V" -l "base-dir:,config-file:,debug,help,publish-dir:,version"
----

presumably most of those options (especially the long ones) don't
conflict with any Emacs command line options.  but, some might ("-d"
does, as it turns out).

i'd like the users (hah!) to be able to type
----
./random-script -d --base-dir ${PWD}/foo
----
rather than
----
./random-script -- -d --base-dir ${PWD}/foo
----

cheers, Greg

(truth in advertising: in addition to this *application*, i also -- for
this application, really -- wrote some emacs-getopt package that would
probably benefit from such a facility.)




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

* Re: Emacs script options
  2023-11-18 19:18 ` Sebastian Miele
@ 2023-11-18 19:49   ` Greg Minshall
  2023-11-19 21:39     ` Jens Schmidt
  2023-11-19  5:04   ` Bob Rogers
  1 sibling, 1 reply; 26+ messages in thread
From: Greg Minshall @ 2023-11-18 19:49 UTC (permalink / raw)
  To: Sebastian Miele; +Cc: emacs-devel

Sebastian Miele <iota@whxvd.name> wrote:

> On Linux that can be achieved by defining a custom interpreter.  E.g.,
> put the following into ‘/path/to/emacs-script’:

yes, thanks.  R has similar (Rscript in R itself; r in littler).  for a
script writer, it's somewhat of a barrier, wondering how many potential
users' machines will have such a script installed; for users, it's one
more hurdle between them and making use of a provided script.

one could also *imagine* (i.e., i think this could work) a packaging
step that would turn one's elisp script into a string and embed it
inside a "#!/bin/sh" script that would unquote the string and feed it
(along with the command line arguments) to Emacs.  if that worked, it at
least would remove the minor hurdle of needing the custom interpreter
you suggest (since everything -- in my fantaxy -- would be in one file).
it seems very messy, though.

cheers, Greg



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

* Re: Emacs script options
  2023-11-18 19:18 ` Sebastian Miele
  2023-11-18 19:49   ` Greg Minshall
@ 2023-11-19  5:04   ` Bob Rogers
  2023-11-19  6:21     ` Eli Zaretskii
  1 sibling, 1 reply; 26+ messages in thread
From: Bob Rogers @ 2023-11-19  5:04 UTC (permalink / raw)
  To: Sebastian Miele, Greg Minshall; +Cc: emacs-devel, Eli Zaretskii

   From: Sebastian Miele <iota@whxvd.name>
   Date: Sat, 18 Nov 2023 20:18:00 +0100

   > From: Greg Minshall <minshall@umich.edu>
   > Date: Fri, 2023-11-17 19:13 -0800

   . . .

   > the below patch to src/emacs.c (**) treats a "-x" (and its "partner"
   > "-scripteval") like a "--" on the command line, and *seems* to allow
   > arbitrary options on the command line.  for example, with this patch
   > installed:
   >
   > ----
   > % ./foo.sh --eval
   > command-line-args-left (--eval)
   > ----

   On Linux that can be achieved by defining a custom interpreter . . .

   However, the workaround is not possible on at least some non-Linux
   systems, because not all systems allow something interpreted as an
   interpreter in a shebang, see
   https://en.wikipedia.org/wiki/Shebang_(Unix)#Syntax.

A more portable option might be for emacs itself to change its startup
behavior if invoked under a special name.  For example, if you used an
"emacscript" alias, emacs would assume "--batch --load" and defer the
rest of its argument processing to the script.  That would make life
easy on Unix-like systems.  And you could just do

	emacscript script-name.el ...

on non-Unix systems.

   ================
   From: Greg Minshall <minshall@umich.edu>
   Date: Sat, 18 Nov 2023 11:36:52 -0800

   . . .

   i'd like the users (hah!) to be able to type
   ----
   ./random-script -d --base-dir ${PWD}/foo
   ----
   rather than
   ----
   ./random-script -- -d --base-dir ${PWD}/foo
   ----

   cheers, Greg

   (truth in advertising: in addition to this *application*, i also -- for
   this application, really -- wrote some emacs-getopt package that would
   probably benefit from such a facility.)

I am reminded of the emacs-lisp email server I wrote 30 years ago
. . . it ran for about 8 years.  "emacs --batch" on steroids.  ;-}

					-- Bob



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

* Re: Emacs script options
  2023-11-18 19:36       ` Greg Minshall
@ 2023-11-19  5:55         ` Eli Zaretskii
  0 siblings, 0 replies; 26+ messages in thread
From: Eli Zaretskii @ 2023-11-19  5:55 UTC (permalink / raw)
  To: Greg Minshall; +Cc: emacs-devel

> cc: emacs-devel@gnu.org
> From: Greg Minshall <minshall@umich.edu>
> Comments: In-reply-to Eli Zaretskii <eliz@gnu.org>
>    message dated "Sat, 18 Nov 2023 18:20:56 +0200."
> Date: Sat, 18 Nov 2023 11:36:52 -0800
> 
> Eli Zaretskii <eliz@gnu.org> wrote:
> 
> > How would you pass these -F, -d, -V etc. options to Emacs, or use them
> > in any other way in the script, whose contents is supposed to be an
> > Emacs Lisp program?  There's something I'm missing here.  I asked my
> > question because I thought you had a real-life example of a script you
> > wanted to use, but in your response you don't show any such example.
> > Can you show it?
> 
> in this case, the -F, -d, -V are aimed at the elisp code running in the
> script, not for Emacs itself.

So this is about avoiding the need to type "--" before those options
which you want to be passed to the Lisp code?  Can't you arrange for
another script or shell alias that would inject the "--" part before
invoking the main script?



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

* Re: Emacs script options
  2023-11-19  5:04   ` Bob Rogers
@ 2023-11-19  6:21     ` Eli Zaretskii
  0 siblings, 0 replies; 26+ messages in thread
From: Eli Zaretskii @ 2023-11-19  6:21 UTC (permalink / raw)
  To: Bob Rogers; +Cc: iota, minshall, emacs-devel

> Date: Sat, 18 Nov 2023 21:04:11 -0800
> From: Bob Rogers <rogers@rgrjr.com>
> CC: emacs-devel@gnu.org,
>     Eli Zaretskii <eliz@gnu.org>
> 
> A more portable option might be for emacs itself to change its startup
> behavior if invoked under a special name.

The GNU Coding Standards frown on such practices:

  Please don't make the behavior of a utility depend on the name used to
  invoke it.  It is useful sometimes to make a link to a utility with a
  different name, and that should not change what it does.  Thus, if you
  make 'foo' a link to 'ls', the program should behave the same regardless
  of which of those names is used to invoke it.



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

* Re: Emacs script options
  2023-11-18 19:49   ` Greg Minshall
@ 2023-11-19 21:39     ` Jens Schmidt
  2023-11-19 21:47       ` Jens Schmidt
  0 siblings, 1 reply; 26+ messages in thread
From: Jens Schmidt @ 2023-11-19 21:39 UTC (permalink / raw)
  To: Greg Minshall, Sebastian Miele; +Cc: emacs-devel



On 2023-11-18  20:49, Greg Minshall wrote:

> one could also *imagine* (i.e., i think this could work) a packaging
> step that would turn one's elisp script into a string and embed it
> inside a "#!/bin/sh" script that would unquote the string and feed it
> (along with the command line arguments) to Emacs.  if that worked, it at
> least would remove the minor hurdle of needing the custom interpreter
> you suggest (since everything -- in my fantaxy -- would be in one file).
> it seems very messy, though.

What about this one, which nicely plays with the meaning of ";" in
Emacs and the Bourne shell:

------------------------- test -------------------------
#!/bin/sh
: ; exec emacs --script "$0" -- "$@"
(message "%S" command-line-args-left)
------------------------- test -------------------------

Might not be very portable.  And I couldn't cram the lexical-bindings
line in, yet.



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

* Re: Emacs script options
  2023-11-19 21:39     ` Jens Schmidt
@ 2023-11-19 21:47       ` Jens Schmidt
  2023-11-20  1:19         ` Greg Minshall
  2023-11-20  6:10         ` Sebastian Miele
  0 siblings, 2 replies; 26+ messages in thread
From: Jens Schmidt @ 2023-11-19 21:47 UTC (permalink / raw)
  To: Greg Minshall, Sebastian Miele; +Cc: emacs-devel

On 2023-11-19  22:39, Jens Schmidt wrote:

> And I couldn't cram the lexical-bindings
> line in, yet.

But of course like this:

------------------------- test -------------------------
#!/bin/sh
: ; exec emacs --script "$0" -- "$@" #; -*- lexical-binding: t -*-
(message "%S" command-line-args-left)
------------------------- test -------------------------




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

* Re: Emacs script options
  2023-11-19 21:47       ` Jens Schmidt
@ 2023-11-20  1:19         ` Greg Minshall
  2023-11-21 21:13           ` Jens Schmidt
  2023-11-20  6:10         ` Sebastian Miele
  1 sibling, 1 reply; 26+ messages in thread
From: Greg Minshall @ 2023-11-20  1:19 UTC (permalink / raw)
  To: Jens Schmidt; +Cc: Sebastian Miele, emacs-devel

Jens,

> ------------------------- test -------------------------
> #!/bin/sh
> : ; exec emacs --script "$0" -- "$@" #; -*- lexical-binding: t -*-
> (message "%S" command-line-args-left)
> ------------------------- test -------------------------

no way, NO way near hack'y enough.  :)

that is, in fact, truly, truly impressive!

(i'd still vote for something like my mod for "-x", but i can run with
this!)

thank you very much!

cheers, Greg



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

* Re: Emacs script options
  2023-11-19 21:47       ` Jens Schmidt
  2023-11-20  1:19         ` Greg Minshall
@ 2023-11-20  6:10         ` Sebastian Miele
  2023-11-20 20:10           ` Jens Schmidt
  1 sibling, 1 reply; 26+ messages in thread
From: Sebastian Miele @ 2023-11-20  6:10 UTC (permalink / raw)
  To: Jens Schmidt; +Cc: Greg Minshall, emacs-devel

> From: Jens Schmidt <jschmidt4gnu@vodafonemail.de>
> Date: Sun, 2023-11-19 22:47 +0100
>
> ------------------------- test -------------------------
> #!/bin/sh
> : ; exec emacs --script "$0" -- "$@" #; -*- lexical-binding: t -*-
> (message "%S" command-line-args-left)
> ------------------------- test -------------------------

This is the trick that Doom Emacs employs, see
https://github.com/doomemacs/doomemacs/blob/master/bin/doom.

But it has a problem with lexical binding.  Consider:

  #!/bin/sh
  : ; exec emacs --script "$0" -- "$@" #; -*- lexical-binding: t; mode: emacs-lisp -*-

  (defmacro lexical-binding-p ()
    '(let* ((x t)
            (f (lambda () x))
            (x nil))
       (funcall f)))

  (message "%s %s" lexical-binding (lexical-binding-p))

When I run it as a script, the output is "nil nil", i.e., the script
definitely does not run with lexical binding enabled.  When I evaluate
it in a buffer, the output is "t t".

When I discovered the problem some while ago, I wanted to report it as
an issue to Doom Emacs, but the bars for reporting issues to that
specific project were set to high for me to actually go through the
process.

But maybe it should be reported as an Emacs bug?



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

* Re: Emacs script options
  2023-11-20  6:10         ` Sebastian Miele
@ 2023-11-20 20:10           ` Jens Schmidt
  2023-11-21  8:51             ` Sebastian Miele
  0 siblings, 1 reply; 26+ messages in thread
From: Jens Schmidt @ 2023-11-20 20:10 UTC (permalink / raw)
  To: Sebastian Miele; +Cc: Greg Minshall, emacs-devel

On 2023-11-20  07:10, Sebastian Miele wrote:

> This is the trick that Doom Emacs employs, see
> https://github.com/doomemacs/doomemacs/blob/master/bin/doom.

Aw, I was afraid that somebody might have code-golfed that already.

> But it has a problem with lexical binding.  Consider:
> 
>   #!/bin/sh
>   : ; exec emacs --script "$0" -- "$@" #; -*- lexical-binding: t; mode: emacs-lisp -*-
> 
>   (defmacro lexical-binding-p ()
>     '(let* ((x t)
>             (f (lambda () x))
>             (x nil))
>        (funcall f)))
> 
>   (message "%s %s" lexical-binding (lexical-binding-p))
> 
> When I run it as a script, the output is "nil nil", i.e., the script
> definitely does not run with lexical binding enabled.  When I evaluate
> it in a buffer, the output is "t t".

I tried byte-compiling something similar yesterday, which also
indicated that the byte-compiler compiles with lexical bindings.  Only
the scripting machinery sees dynamical bindings.

> When I discovered the problem some while ago, I wanted to report it as
> an issue to Doom Emacs, but the bars for reporting issues to that
> specific project were set to high for me to actually go through the
> process.
> 
> But maybe it should be reported as an Emacs bug?

I think chances are good that this gets accepted.  It seems that the
scripting machinery expects a semicolon in the very first column,
without that the lexical-binding line is not recognized.  Even a 
space before the semicolon breaks the recognition.

The problem is in function `lisp_file_lexically_bound_p' from lread.c,
which is indeed much more strict in its recognition of the -*- ... -*-
stanza than the functions `set-auto-mode-1' and
`hack-local-variables-prop-line' from files.el.  The Emacs manual
((emacs) Specifying File Variables) only mentions that the stanza
has to be in the first line (or the second one if the first is taken
by a she-bang), without any restriction where the comment has to start.

Would you or Greg report that as a bug?




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

* Re: Emacs script options
  2023-11-20 20:10           ` Jens Schmidt
@ 2023-11-21  8:51             ` Sebastian Miele
  0 siblings, 0 replies; 26+ messages in thread
From: Sebastian Miele @ 2023-11-21  8:51 UTC (permalink / raw)
  To: Jens Schmidt; +Cc: Greg Minshall, emacs-devel

> From: Jens Schmidt <jschmidt4gnu@vodafonemail.de>
> Date: Mon, 2023-11-20 21:10 +0100
>
> On 2023-11-20  07:10, Sebastian Miele wrote:
>
>> But it has a problem with lexical binding.  Consider:
>>
>>   #!/bin/sh
>>   : ; exec emacs --script "$0" -- "$@" #; -*- lexical-binding: t; mode: emacs-lisp -*-
>>
>>   (defmacro lexical-binding-p ()
>>     '(let* ((x t)
>>             (f (lambda () x))
>>             (x nil))
>>        (funcall f)))
>>
>>   (message "%s %s" lexical-binding (lexical-binding-p))
>>
>> When I run it as a script, the output is "nil nil", i.e., the script
>> definitely does not run with lexical binding enabled.  When I evaluate
>> it in a buffer, the output is "t t".
>
> I tried byte-compiling something similar yesterday, which also
> indicated that the byte-compiler compiles with lexical bindings.  Only
> the scripting machinery sees dynamical bindings.
>
> […]  It seems that the scripting machinery expects a semicolon in the
> very first column, without that the lexical-binding line is not
> recognized.  Even a space before the semicolon breaks the recognition.
>
> The problem is in function `lisp_file_lexically_bound_p' from lread.c,
> which is indeed much more strict in its recognition of the -*- ... -*-
> stanza than the functions `set-auto-mode-1' and
> `hack-local-variables-prop-line' from files.el.  The Emacs manual
> ((emacs) Specifying File Variables) only mentions that the stanza
> has to be in the first line (or the second one if the first is taken
> by a she-bang), without any restriction where the comment has to
> start.

Thank you for the additional investigation into and information about
the issue.

> Would you or Greg report that as a bug?

Done, https://debbugs.gnu.org/cgi/bugreport.cgi?bug=67321.



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

* Re: Emacs script options
  2023-11-20  1:19         ` Greg Minshall
@ 2023-11-21 21:13           ` Jens Schmidt
  2023-11-22 18:17             ` Sebastian Miele
  2023-11-24  4:22             ` Greg Minshall
  0 siblings, 2 replies; 26+ messages in thread
From: Jens Schmidt @ 2023-11-21 21:13 UTC (permalink / raw)
  To: Greg Minshall; +Cc: Sebastian Miele, emacs-devel

On 2023-11-20  02:19, Greg Minshall wrote:

> no way, NO way near hack'y enough.  :)

I couldn't stand the fact that my hack was taken already plus
that it is flawed, so I set off to extend it with a work-around
for the lexical-binding issue.

While there are surely other methods to achieve what below code
does, supposedly also more stable ones, I wanted to go for
brevity to keep the non-script overhead small:

------------------------- escript -------------------------
#!/bin/sh
: ; exec emacs --script "$0" -- "$@" #; -*- lexical-binding: t -*-

;; Work around `eval-buffer' not recognizing the lexical-binding
;; stanza when the comment containing it does not start at first
;; column (bug#67321).
(unless (ignore-errors (funcall (let ((v t)) (lambda () v))))
  (with-current-buffer (car eval-buffer-list)
    (goto-char (point-min)) (search-forward "; -*-")
    (delete-region (point-min) (match-beginning 0))
    (eval-buffer)))

;; Script payload.
(message "%S:%S" lexical-binding command-line-args-left)

;; Explicitly exit Emacs to not return from the second-level
;; `eval-buffer'.
(kill-emacs 0)

;;; Local Variables:
;;; mode: emacs-lisp
;;; End:
------------------------- escript -------------------------

(Thanks to Sebastian for opening the bug, BTW.  When looking at
the previous, now merged bug, it seems that this won't be
something easy to get through.)




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

* Re: Emacs script options
  2023-11-21 21:13           ` Jens Schmidt
@ 2023-11-22 18:17             ` Sebastian Miele
  2023-11-22 20:18               ` Jens Schmidt
  2023-11-24  4:22             ` Greg Minshall
  1 sibling, 1 reply; 26+ messages in thread
From: Sebastian Miele @ 2023-11-22 18:17 UTC (permalink / raw)
  To: Jens Schmidt; +Cc: Greg Minshall, emacs-devel

> From: Jens Schmidt <jschmidt4gnu@vodafonemail.de>
> Date: Tue, 2023-11-21 22:13 +0100
>
> On 2023-11-20  02:19, Greg Minshall wrote:
>
>> no way, NO way near hack'y enough.  :)
>
> I couldn't stand the fact that my hack was taken already plus
> that it is flawed, so I set off to extend it with a work-around
> for the lexical-binding issue.
>
> While there are surely other methods to achieve what below code
> does, supposedly also more stable ones, I wanted to go for
> brevity to keep the non-script overhead small:
>
> ------------------------- escript -------------------------
> #!/bin/sh
> : ; exec emacs --script "$0" -- "$@" #; -*- lexical-binding: t -*-
>
> ;; Work around `eval-buffer' not recognizing the lexical-binding
> ;; stanza when the comment containing it does not start at first
> ;; column (bug#67321).
> (unless (ignore-errors (funcall (let ((v t)) (lambda () v))))
>   (with-current-buffer (car eval-buffer-list)
>     (goto-char (point-min)) (search-forward "; -*-")
>     (delete-region (point-min) (match-beginning 0))
>     (eval-buffer)))
>
> ;; Script payload.
> (message "%S:%S" lexical-binding command-line-args-left)
>
> ;; Explicitly exit Emacs to not return from the second-level
> ;; `eval-buffer'.
> (kill-emacs 0)
>
> ;;; Local Variables:
> ;;; mode: emacs-lisp
> ;;; End:
> ------------------------- escript -------------------------

Thank you, I noted this trick for the future.

For the record, Gerd Möllemann mentioned yet another trick on
https://debbugs.gnu.org/67321:

> From: Gerd Möllmann <gerd.moellmann@gmail.com>
> Date: Wed, 2023-11-22 15:59 +0100
>
> cat >somefile <<EOF
> ; -*- lexical-binding: t -*-
> (message "%s" lexical-binding)
> EOF
> emacs --script somefile



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

* Re: Emacs script options
  2023-11-22 18:17             ` Sebastian Miele
@ 2023-11-22 20:18               ` Jens Schmidt
  0 siblings, 0 replies; 26+ messages in thread
From: Jens Schmidt @ 2023-11-22 20:18 UTC (permalink / raw)
  To: Sebastian Miele; +Cc: Greg Minshall, emacs-devel

On 2023-11-22  19:17, Sebastian Miele wrote:

> For the record, Gerd Möllemann mentioned yet another trick on
> https://debbugs.gnu.org/67321:
> 
>> From: Gerd Möllmann <gerd.moellmann@gmail.com>
>> Date: Wed, 2023-11-22 15:59 +0100
>>
>> cat >somefile <<EOF
>> ; -*- lexical-binding: t -*-
>> (message "%s" lexical-binding)
>> EOF
>> emacs --script somefile

Hmja, only this leaves somefile behind, which I intentionally wanted
to avoid.  (At least in Bash one could get more or less safely rid of
that with a "trap 'rm -f somefile' EXIT", but anyway.)




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

* Re: Emacs script options
  2023-11-21 21:13           ` Jens Schmidt
  2023-11-22 18:17             ` Sebastian Miele
@ 2023-11-24  4:22             ` Greg Minshall
  2023-11-26 18:07               ` Jens Schmidt
  1 sibling, 1 reply; 26+ messages in thread
From: Greg Minshall @ 2023-11-24  4:22 UTC (permalink / raw)
  To: Jens Schmidt; +Cc: Sebastian Miele, emacs-devel

Jens,

> While there are surely other methods to achieve what below code
> does, supposedly also more stable ones, I wanted to go for
> brevity to keep the non-script overhead small:

yes, i would say the below code *is* sufficiently hacky!

but, i would go back to my suggestion for "-x".  i think it would be a
real benefit to those wanting to write general purpose scripts using
Emacs as the "engine" (or whatever).

cheers, Greg

> ------------------------- escript -------------------------
> #!/bin/sh
> : ; exec emacs --script "$0" -- "$@" #; -*- lexical-binding: t -*-
> 
> ;; Work around `eval-buffer' not recognizing the lexical-binding
> ;; stanza when the comment containing it does not start at first
> ;; column (bug#67321).
> (unless (ignore-errors (funcall (let ((v t)) (lambda () v))))
>   (with-current-buffer (car eval-buffer-list)
>     (goto-char (point-min)) (search-forward "; -*-")
>     (delete-region (point-min) (match-beginning 0))
>     (eval-buffer)))
> 
> ;; Script payload.
> (message "%S:%S" lexical-binding command-line-args-left)
> 
> ;; Explicitly exit Emacs to not return from the second-level
> ;; `eval-buffer'.
> (kill-emacs 0)
> 
> ;;; Local Variables:
> ;;; mode: emacs-lisp
> ;;; End:
> ------------------------- escript -------------------------



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

* Re: Emacs script options
  2023-11-24  4:22             ` Greg Minshall
@ 2023-11-26 18:07               ` Jens Schmidt
  0 siblings, 0 replies; 26+ messages in thread
From: Jens Schmidt @ 2023-11-26 18:07 UTC (permalink / raw)
  To: Greg Minshall; +Cc: emacs-devel

Hi Greg,

On 2023-11-24  05:22, Greg Minshall wrote:

> but, i would go back to my suggestion for "-x".  i think it would be a
> real benefit to those wanting to write general purpose scripts using
> Emacs as the "engine" (or whatever).

only I have the gut feeling that this branch of your thread drifted
off too far from your initial request, so that you keeping up to your
suggestion won't be noticed here.

So probably you'd like to bump an earlier branch, and/or include Eli
in the Cc.

								Jens





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

* Re: Emacs script options
  2023-11-18  7:36 ` Emacs script options Eli Zaretskii
  2023-11-18 14:38   ` Greg Minshall
@ 2023-11-27  3:29   ` Greg Minshall
  2023-11-27 12:59     ` Eli Zaretskii
  1 sibling, 1 reply; 26+ messages in thread
From: Greg Minshall @ 2023-11-27  3:29 UTC (permalink / raw)
  To: Eli Zaretskii; +Cc: emacs-devel

Eli, et al.,

there was an interesting discussion on how to use a two-line shell
script as a spring board into Emacs.  but, possibly not everyone
followed the discussion that far.

but, i would jump back to my suggestion for "-x".  i think it would be a
real benefit to those wanting to write general purpose scripts using
Emacs as the "engine" (or whatever you want to call it).

cheers, Greg



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

* Re: Emacs script options
  2023-11-27  3:29   ` Greg Minshall
@ 2023-11-27 12:59     ` Eli Zaretskii
  2023-11-27 19:32       ` Greg Minshall
  0 siblings, 1 reply; 26+ messages in thread
From: Eli Zaretskii @ 2023-11-27 12:59 UTC (permalink / raw)
  To: Greg Minshall; +Cc: emacs-devel

> cc: emacs-devel@gnu.org
> From: Greg Minshall <minshall@umich.edu>
> Comments: In-reply-to Eli Zaretskii <eliz@gnu.org>
>    message dated "Sat, 18 Nov 2023 09:36:36 +0200."
> Date: Sun, 26 Nov 2023 19:29:25 -0800
> 
> there was an interesting discussion on how to use a two-line shell
> script as a spring board into Emacs.  but, possibly not everyone
> followed the discussion that far.
> 
> but, i would jump back to my suggestion for "-x".  i think it would be a
> real benefit to those wanting to write general purpose scripts using
> Emacs as the "engine" (or whatever you want to call it).

My understanding of this is that one can easily avoid the annoyance of
having to use "--" by at least two different techniques.

As mentioned in

  https://lists.gnu.org/archive/html/emacs-devel/2023-11/msg00864.html

the proposed feature will change the Emacs behavior in incompatible
ways, so there's also a significant disadvantage to this proposal.

So on balance, I think that we should not add this feature.



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

* Re: Emacs script options
  2023-11-27 12:59     ` Eli Zaretskii
@ 2023-11-27 19:32       ` Greg Minshall
  0 siblings, 0 replies; 26+ messages in thread
From: Greg Minshall @ 2023-11-27 19:32 UTC (permalink / raw)
  To: Eli Zaretskii; +Cc: emacs-devel

hi, Eli,

> My understanding of this is that one can easily avoid the annoyance of
> having to use "--" by at least two different techniques.
> 
> As mentioned in
> 
>   https://lists.gnu.org/archive/html/emacs-devel/2023-11/msg00864.html

there are ways.  they have the random problem here or there.  but, even
if they didn't, i think it would be cleaner, and maybe more robust, to
have something in the "#!/usr/bin/emacs" line that would stop parsing
any Emacs options at the end of that line (rather than looking at any
command line options the end-user gave when invoking the script).

> the proposed feature will change the Emacs behavior in incompatible
> ways, so there's also a significant disadvantage to this proposal.

it's definitely a good idea to not introduce incompatibilities.  (though
i'd be curious to see how people are using "-x" with other Emacs
options, whether on the "#!/usr/bin/emacs" line, or on the command
line.)

how about "-y"? :)

cheers, Greg



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

end of thread, other threads:[~2023-11-27 19:32 UTC | newest]

Thread overview: 26+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2023-11-18  3:13 (unknown) Greg Minshall
2023-11-18  7:05 ` (unknown) Jim Porter
2023-11-18 14:10   ` (unknown) -x behavior change Greg Minshall
2023-11-18  7:36 ` Emacs script options Eli Zaretskii
2023-11-18 14:38   ` Greg Minshall
2023-11-18 16:20     ` Eli Zaretskii
2023-11-18 19:36       ` Greg Minshall
2023-11-19  5:55         ` Eli Zaretskii
2023-11-27  3:29   ` Greg Minshall
2023-11-27 12:59     ` Eli Zaretskii
2023-11-27 19:32       ` Greg Minshall
2023-11-18 19:18 ` Sebastian Miele
2023-11-18 19:49   ` Greg Minshall
2023-11-19 21:39     ` Jens Schmidt
2023-11-19 21:47       ` Jens Schmidt
2023-11-20  1:19         ` Greg Minshall
2023-11-21 21:13           ` Jens Schmidt
2023-11-22 18:17             ` Sebastian Miele
2023-11-22 20:18               ` Jens Schmidt
2023-11-24  4:22             ` Greg Minshall
2023-11-26 18:07               ` Jens Schmidt
2023-11-20  6:10         ` Sebastian Miele
2023-11-20 20:10           ` Jens Schmidt
2023-11-21  8:51             ` Sebastian Miele
2023-11-19  5:04   ` Bob Rogers
2023-11-19  6:21     ` Eli Zaretskii

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

	https://git.savannah.gnu.org/cgit/emacs.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).