Subject: Invert when symbol syntax class is used for ##

From: Jonas Bernoulli <[email-masked]>
Date: Wed, 12 Mar 2025 22:25:46 +0100

The `llama' package uses the `##' symbol and encourages not putting any
space in between that and the following symbol.

Since it was added three years ago, `elisp-mode-syntax-propertize'
explicitly assigns the symbol syntax class to "##", which means that
code that relies on the syntax alone (such as complete-symbol), thinks
that ##foo is one symbol, when that are actually two symbols ## and foo.

For some reason [1: 6ccc4b6bc8a] limited assigning symbol syntax for ##
to when that appears in code.  I propose we do the opposite: do NOT use
symbol syntax in code, but DO use symbol syntax in strings and comments.
Do the latter so that `##' is highlighted like other symbols would, when
quoted like that.

1: 2022-05-06 6ccc4b6bc8a14daca6b3e3250574752c90c1eb9b
   Handle elisp #-syntax better in Emacs Lisp mode

I am opening this bug-report because Stefan Monnier commented on
llama.el's advice for `elisp-mode-syntax-propertize', to ask whether
such a bug-report exists:

>> +     (syntax-propertize-rules
>> +      ;; Empty symbol.
>> +      ;; {{ Comment out to prevent the `##' from becoming part of
>> +      ;;    the following symbol when there is no space in between.
>> +      ;; ("##" (0 (unless (nth 8 (syntax-ppss))
>> +      ;;            (string-to-syntax "_"))))
>> +      ;; }}
>> +      ;; {{ As for other symbols, use `font-lock-constant-face' in
>> +      ;;    docstrings and comments.
>> +      ("##" (0 (when (nth 8 (syntax-ppss))
>> +                 (string-to-syntax "_"))))
>> +      ;; }}
>
> BTW, is there a bug-report about this?  It seems this issue is not
> really dependent on what ## is used for (except maybe for the fact that
> `llama.el` encourages the use a `##` immediately followed by another
> symbol without any intervening space).
>
>         Stefan

Coming from an override advice, the above code includes "original
vs. advice" commentary.  As a patch to Emacs, this change look like
this:

diff --git a/lisp/progmodes/elisp-mode.el b/lisp/progmodes/elisp-mode.el
@@ -269,9 +269,12 @@ elisp-mode-syntax-propertize
   (let ((case-fold-search nil))
     (funcall
      (syntax-propertize-rules
-      ;; Empty symbol.
-      ("##" (0 (unless (nth 8 (syntax-ppss))
-                 (string-to-syntax "_"))))
+      ;; Prevent ## (the empty symbol) from becoming part of a
+      ;; preceeding or following symbol by *not* explicitly assigning
+      ;; symbol syntax class here; except in comments and strings, so
+      ;; that `##' gets highlighted like other `symbols'.
+      ("##" (0 (and (nth 8 (syntax-ppss))
+                    (string-to-syntax "_"))))
       ;; Prevent the @ from becoming part of a following symbol.
       (",@" (0 (unless (nth 8 (syntax-ppss))
                  (string-to-syntax "'"))))

Jonas