bug-gnu-emacs
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

bug#51089: 28.0.60; Using read-symbol-shorthands (("-" . "foo-")) should


From: João Távora
Subject: bug#51089: 28.0.60; Using read-symbol-shorthands (("-" . "foo-")) shouldn't shadow the '-' symbol
Date: Thu, 07 Oct 2021 21:44:57 +0100

First reported in

    https://lists.gnu.org/archive/html/emacs-devel/2021-09/msg02297.html

Richard Stallman writes:

> It looks like "-" as a shorthand prefix should not rename `-'.  I can
> imagine various ways to fix this, some more general and some less
> general.

This is true.  We must fix this before importing Magnar Sveen's dash.el
library (which uses the very short '-' prefix) and any of its users in a
way that avoids the namespace pollution.

As Richard states, there are various ways to fix this.  I discuss
briefly 2 of them.  The first doesn't have any drawbacks in my opinion,
the second has a small one but it's overcome reasonably easy.

(1) The very simplest fix (and perhaps the most correct one) is just to
special-case the case of the '-' prefix and the '-' function.  That's
because the '-' symbol is the only one that exactly matches the
name-prefix separator that is used in Emacs.  In other words, I can't
think of any other "legitimate" use case for the shorthands feature that
would shadow a similar one-character symbol.  For example using

   (("/" . "some-longhand/"))

would shadow the '/' symbol but count as as "the user knows what she's
doing".


(2) Another natural, more generic, way would be to demand that the
shorthand in the 'car's of the elements of read-symbol-shorthands is
strictly shorter then the form about to be renamed.  In lread.c, I think
it would amount to this:

diff --git a/src/lread.c b/src/lread.c
index 07580d11d1..2950abf982 100644
--- a/src/lread.c
+++ b/src/lread.c
@@ -4666,7 +4666,7 @@ oblookup_considering_shorthand (Lisp_Object obarray, 
const char *in,
         version of the symbol name with xrealloc.  This isn't
         strictly needed, but it could later be used as a way for
         multiple transformations on a single symbol name.  */
-      if (sh_prefix_size <= size_byte
+      if (sh_prefix_size < size_byte
          && memcmp (SSDATA (sh_prefix), in, sh_prefix_size) == 0)
        {
          ptrdiff_t lh_prefix_size = SBYTES (lh_prefix);

However, this would also forbid another proposed use for shorthands,
which is to use them to rename whole collections symbols and allow them
to be used without a prefix.  An example would be the 'cl-' family of
symbols, which have "grown" a 'cl-' prefix some versions go, but which
some people would still like to use without that prefix.  Examples are

   cl-loop
   cl-first
   cl-plusp

Currently, it is possible to use shorthands to do

  (("cl-loop" . "loop")
   ("cl-first" . "first")
   ("cl-plusp" . "plusp"))

With the proposed fix above, it wouldn't be.

Therefore, I propos that for this use case, we introduce new syntax in
read-symbol-shorthands.  A trailing '$' character in the shorthand
portion would mean that it's OK to bypass that "strickly shorter"
limitation and rename the whole name.  This could be done with something
like this:

diff --git a/src/lread.c b/src/lread.c
index 07580d11d1..1bcaf5c64f 100644
--- a/src/lread.c
+++ b/src/lread.c
@@ -4658,6 +4658,13 @@ oblookup_considering_shorthand (Lisp_Object obarray, 
const char *in,
       if (!STRINGP (sh_prefix) || !STRINGP (lh_prefix))
        continue;
       ptrdiff_t sh_prefix_size = SBYTES (sh_prefix);
+      bool replace_whole = false;
+
+      if (SCHARS (sh_prefix) == (size + 1) &&
+         SSDATA (sh_prefix)[sh_prefix_size - 1] == '$') {
+       replace_whole = true;
+       sh_prefix_size--;
+      }
 
       /* Compare the prefix of the transformation pair to the symbol
         name.  If a match occurs, do the renaming and exit the loop.
@@ -4666,7 +4673,7 @@ oblookup_considering_shorthand (Lisp_Object obarray, 
const char *in,
         version of the symbol name with xrealloc.  This isn't
         strictly needed, but it could later be used as a way for
         multiple transformations on a single symbol name.  */
-      if (sh_prefix_size <= size_byte
+      if ((sh_prefix_size < size_byte || replace_whole)
          && memcmp (SSDATA (sh_prefix), in, sh_prefix_size) == 0)
        {
          ptrdiff_t lh_prefix_size = SBYTES (lh_prefix);

In addition to the C-side change, the Elisp code dealing with
read-symbol-shorthands prefixes needs to be changed to account for the
trailing "$".  Fortunately, there's not a lot of that code around it.

João





reply via email to

[Prev in Thread] Current Thread [Next in Thread]