]> git.eshelyaron.com Git - emacs.git/commitdiff
(scheme-syntax-propertize-sexp-comment): Handle nested sexp-comments
authorStefan Monnier <monnier@iro.umontreal.ca>
Mon, 1 Apr 2024 06:12:51 +0000 (02:12 -0400)
committerEshel Yaron <me@eshelyaron.com>
Tue, 2 Apr 2024 13:23:00 +0000 (15:23 +0200)
Well, I'm not completely sure this will work right in all cases,
because I've been confused about this in the past.
It works in my test case, at least.

* lisp/progmodes/scheme.el (scheme-syntax-propertize-sexp-comment):
Look for nested `#;` and mark them appropriately.

(cherry picked from commit 0f504dde3388687d1214182fa519354146947635)

etc/NEWS
lisp/progmodes/scheme.el

index e86471a2969c2df9b0c57efcb680d93b6d039135..35c8dea8a2e607f8af56455be9c483834df96005 100644 (file)
--- a/etc/NEWS
+++ b/etc/NEWS
@@ -1320,6 +1320,7 @@ interactive Python interpreter specified by 'python-interpreter'.
 
 Scheme mode now handles regular expression literal #/regexp/ that is
 available in some Scheme implementations.
+Also, it should now handle nested sexp-comments.
 
 ** use-package
 
index 8652abeb8174c93174f34066ae23f76a2de4cd0d..79d076ff1452c879d0cf71a2aa9c154e6824e096 100644 (file)
@@ -50,6 +50,7 @@
 ;;; Code:
 \f
 (require 'lisp-mode)
+(eval-when-compile 'subr-x)             ;For `named-let'.
 
 (defvar scheme-mode-syntax-table
   (let ((st (make-syntax-table))
@@ -426,18 +427,40 @@ See `run-hooks'."
    (point) end))
 
 (defun scheme-syntax-propertize-sexp-comment (end)
-  (let ((state (syntax-ppss)))
+  (let ((state (syntax-ppss))
+        (checked (point)))
     (when (eq 2 (nth 7 state))
       ;; It's a sexp-comment.  Tell parse-partial-sexp where it ends.
-      (condition-case nil
-          (progn
-            (goto-char (+ 2 (nth 8 state)))
-            ;; FIXME: this doesn't handle the case where the sexp
-            ;; itself contains a #; comment.
-            (forward-sexp 1)
-            (put-text-property (1- (point)) (point)
-                               'syntax-table (string-to-syntax "> cn")))
-        (scan-error (goto-char end))))))
+      (named-let loop ((startpos (+ 2 (nth 8 state))))
+        (let ((found nil))
+          (while
+              (progn
+                (setq found nil)
+                (condition-case nil
+                    (progn
+                      (goto-char startpos)
+                      (forward-sexp 1)
+                      (setq found (point)))
+                  (scan-error (goto-char end)))
+                ;; If there's a nested `#;', the syntax-tables will normally
+                ;; consider the `;' to start a normal comment, so the
+                ;; (forward-sexp 1) above may have landed at the wrong place.
+                ;; So look for `#;' in the text over which we jumped, and
+                ;; mark those we found as nested sexp-comments.
+                (let ((limit (or found end)))
+                  (when (< checked limit)
+                    (goto-char checked)
+                    (when (re-search-forward "\\(#\\);" limit 'move)
+                      (setq checked (point))
+                      (put-text-property (match-beginning 1) (match-end 1)
+                                         'syntax-table
+                                         (string-to-syntax "< cn"))
+                      (loop (point)))
+                    (< (point) limit)))))
+          (when found
+            (goto-char found)
+            (put-text-property (1- found) found
+                               'syntax-table (string-to-syntax "> cn"))))))))
 
 (defun scheme-syntax-propertize-regexp (end)
   (let* ((state (syntax-ppss))