From: Stefan Monnier Date: Mon, 1 Apr 2024 06:12:51 +0000 (-0400) Subject: (scheme-syntax-propertize-sexp-comment): Handle nested sexp-comments X-Git-Url: http://git.eshelyaron.com/gitweb/?a=commitdiff_plain;h=e07cb7c32a07e319e1cdbba2159b7ec307fec8d0;p=emacs.git (scheme-syntax-propertize-sexp-comment): Handle nested sexp-comments 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) --- diff --git a/etc/NEWS b/etc/NEWS index e86471a2969..35c8dea8a2e 100644 --- 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 diff --git a/lisp/progmodes/scheme.el b/lisp/progmodes/scheme.el index 8652abeb817..79d076ff145 100644 --- a/lisp/progmodes/scheme.el +++ b/lisp/progmodes/scheme.el @@ -50,6 +50,7 @@ ;;; Code: (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))