all messages for Emacs-related lists mirrored at yhetil.org
 help / color / mirror / code / Atom feed
From: Toshi Umehara <toshi@niceume.com>
To: monnier@iro.umontreal.ca
Cc: Eli Zaretskii <eliz@gnu.org>, jcubic@onet.pl, emacs-devel@gnu.org
Subject: Re: Scheme Mode and Regular Expression Literals
Date: Tue, 19 Mar 2024 12:06:24 +0900	[thread overview]
Message-ID: <87edc6kjin.fsf@niceume.com> (raw)
In-Reply-To: jwv1q89fwmx.fsf-monnier+emacs@gnu.org

[-- Attachment #1: Type: text/plain, Size: 4375 bytes --]


Thank you very much for your comments, Stefan. As you point out, the
previous code is found to fail when regular expressions and sexp
comments exist in the same line.

Now I put the logic to scan the beginning of sexp comments and regular
expressions in syntax-propertize-rules macro. I use different functions
to be invoked by them, because the beginning of regular expressions
need to be canceled when they are already in normal strings or
comments. (This kind of logic might be required also for sexp comment,
but the current implementation does not do that and does not seem to
cause any harms.)

Therefore, if I use the same function, it requires an extra conditional
code only for regular expressions, which is a repetition of what is done
in syntax-propertize-rules level. (At syntax-propertize-rules leve, we
already know it's a beginning of a sexp comment or a possible beginning
of regular expression).

The following explains the functions implemented.

- scheme-syntax-propertize-sexp-comment

  No change from the current built-in implementation

- scheme-syntax-propertize-regexp-end

  If the posistion is already in regular expressions and not in
  comments, it searches regular expression end (/) ignoring backslash
  slash (\/).


- scheme-syntax-propertize-regexp

  This is invoked in syntax-propertize-rules. It cancels syntax class
  assignment to # of #/ if the # part is already in strings or
  comments. (Precisely, it assigns @ syntax class to # .) Otherwise it
  continues to scan the end of regular expression by calling
  scheme-syntax-propertize-regexp-end.


Thanks.


#+BEGIN_SRC
(add-hook
 'scheme-mode-hook
 (lambda ()
   (setq-local
    syntax-propertize-function
    (lambda (beg end)
      (goto-char beg)
      (scheme-syntax-propertize-sexp-comment (point) end)
      (scheme-syntax-propertize-regexp-end (point) end)
      (funcall
       (syntax-propertize-rules
        ("\\(#\\);" (1 (prog1 "< cn"
                         (scheme-syntax-propertize-sexp-comment
                          (point) end))))
        ("\\(#\\)/" (1 (prog1 "|"
                         (scheme-syntax-propertize-regexp
                          (point) end))))
         )
       (point) end)
      ))))

(defun scheme-syntax-propertize-sexp-comment (_ end)
  (let ((state (syntax-ppss)))
    (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))))))

(defun scheme-syntax-propertize-regexp-end (_ end)
  (let* ((state (syntax-ppss))
         (within-str (nth 3 state))
         (within-comm (nth 4 state))
         (start-delim-pos (nth 8 state)))
    (if (and (not within-comm)
             (and within-str
                  (string=
                   (buffer-substring-no-properties
                    start-delim-pos
                    (1+ start-delim-pos))
                   "#")))
        (let ((end-found nil))
          (while (and
                  (not end-found)
                  (re-search-forward "\\(/\\)" end t))
            (progn
              (if
                  (not (char-equal
                        (char-before (match-beginning 1))
                        ?\\ ))
                  (progn
                    (put-text-property
                     (match-beginning 1)
                     (1+ (match-beginning 1))
                     'syntax-table (string-to-syntax "|"))
                    (setq end-found t)
                    )))))
      )))

(defun scheme-syntax-propertize-regexp (_ end)
  (let* ((match-start-state (save-excursion
                              (syntax-ppss (match-beginning 1))))
         (within-str (nth 3 match-start-state))
         (within-comm (nth 4 match-start-state)))
    (if (or within-str within-comm)
          (put-text-property ;; Cancel regular expression start
           (match-beginning 1)
           (1+ (match-beginning 1))
           'syntax-table (string-to-syntax "@"))
      (scheme-syntax-propertize-regexp-end _ end)
      )))

#+END_SRC


[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #2: deals with scheme regular expression syntax --]
[-- Type: text/x-patch, Size: 2791 bytes --]

diff --git a/lisp/progmodes/scheme.el b/lisp/progmodes/scheme.el
index 67abab6913d..98405513099 100644
--- a/lisp/progmodes/scheme.el
+++ b/lisp/progmodes/scheme.el
@@ -410,11 +410,18 @@ scheme-sexp-comment-syntax-table
 (defun scheme-syntax-propertize (beg end)
   (goto-char beg)
   (scheme-syntax-propertize-sexp-comment (point) end)
+  (scheme-syntax-propertize-regexp-end (point) end)
   (funcall
    (syntax-propertize-rules
     ("\\(#\\);" (1 (prog1 "< cn"
-                     (scheme-syntax-propertize-sexp-comment (point) end)))))
-   (point) end))
+                     (scheme-syntax-propertize-sexp-comment
+                      (point) end))))
+    ("\\(#\\)/" (1 (prog1 "|"
+                     (scheme-syntax-propertize-regexp
+                      (point) end))))
+    )
+   (point) end)
+  )
 
 (defun scheme-syntax-propertize-sexp-comment (_ end)
   (let ((state (syntax-ppss)))
@@ -430,6 +437,49 @@ scheme-syntax-propertize-sexp-comment
                                'syntax-table (string-to-syntax "> cn")))
         (scan-error (goto-char end))))))
 
+(defun scheme-syntax-propertize-regexp-end (_ end)
+  (let* ((state (syntax-ppss))
+         (within-str (nth 3 state))
+         (within-comm (nth 4 state))
+         (start-delim-pos (nth 8 state)))
+    (if (and (not within-comm)
+             (and within-str
+                  (string=
+                   (buffer-substring-no-properties
+                    start-delim-pos
+                    (1+ start-delim-pos))
+                   "#")))
+        (let ((end-found nil))
+          (while (and
+                  (not end-found)
+                  (re-search-forward "\\(/\\)" end t))
+            (progn
+              (if
+                  (not (char-equal
+                        (char-before (match-beginning 1))
+                        ?\\ ))
+                  (progn
+                    (put-text-property
+                     (match-beginning 1)
+                     (1+ (match-beginning 1))
+                     'syntax-table (string-to-syntax "|"))
+                    (setq end-found t)
+                    )))))
+      )))
+
+(defun scheme-syntax-propertize-regexp (_ end)
+  (let* ((match-start-state (save-excursion
+                              (syntax-ppss (match-beginning 1))))
+         (within-str (nth 3 match-start-state))
+         (within-comm (nth 4 match-start-state)))
+    (if (or within-str within-comm)
+          (put-text-property ;; Cancel regular expression start
+           (match-beginning 1)
+           (1+ (match-beginning 1))
+           'syntax-table (string-to-syntax "@"))
+      (scheme-syntax-propertize-regexp-end _ end)
+      )))
+
 ;;;###autoload
 (define-derived-mode dsssl-mode scheme-mode "DSSSL"
   "Major mode for editing DSSSL code.

[-- Attachment #3: Type: text/plain, Size: 32 bytes --]



-- 
Toshi (Toshihiro Umehara)

             reply	other threads:[~2024-03-19  3:06 UTC|newest]

Thread overview: 12+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2024-03-19  3:06 Toshi Umehara [this message]
2024-03-19 13:36 ` Scheme Mode and Regular Expression Literals Stefan Monnier
2024-03-23  2:45   ` Toshi Umehara
  -- strict thread matches above, loose matches on Subject: below --
2024-03-17  0:28 Toshi Umehara
2024-03-17  2:02 ` Stefan Monnier
2024-03-09  2:59 Toshi Umehara
2024-03-09 13:37 ` Jakub T. Jankiewicz
2024-03-14  8:40 ` Eli Zaretskii
2024-03-14 11:38   ` Mattias Engdegård
2024-03-14 13:34     ` Stefan Monnier
2024-03-14 15:09       ` Jakub T. Jankiewicz
2024-02-27 14:46 Jakub T. Jankiewicz

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=87edc6kjin.fsf@niceume.com \
    --to=toshi@niceume.com \
    --cc=eliz@gnu.org \
    --cc=emacs-devel@gnu.org \
    --cc=jcubic@onet.pl \
    --cc=monnier@iro.umontreal.ca \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
Code repositories for project(s) associated with this external index

	https://git.savannah.gnu.org/cgit/emacs.git
	https://git.savannah.gnu.org/cgit/emacs/org-mode.git

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.