emacs-devel
[Top][All Lists]
Advanced

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

Re: Scheme Mode and Regular Expression Literals


From: Stefan Monnier
Subject: Re: Scheme Mode and Regular Expression Literals
Date: Tue, 19 Mar 2024 09:36:40 -0400
User-agent: Gnus/5.13 (Gnus v5.13)

> 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.

We usually don't bother doing that because it affects only navigation
*within* those strings/comments :-)

The code looks pretty good now.  Can you turn it into a patch against
`scheme.el`?

In the mean time, see my comments below.

> (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))
>                    "#")))

(eq ?# (char-after start-delim-pos)) would be simpler and more efficient.
Also, `within-str` and `within-comm` are mutually exclusive, so the
`(and (not within-comm)` is redundant.

>         (let ((end-found nil))
>           (while (and
>                   (not end-found)
>                   (re-search-forward "\\(/\\)" end t))

You don't need the \\( \\), you can just use (match-beginning 0)
instead, which will let Emacs use the simpler non-regexp
search algorithm.

>             (progn
>               (if
>                   (not (char-equal
>                         (char-before (match-beginning 1))
>                         ?\\ ))

This fails for #/foo\\/
In sh-script.el I used

    (eq -1 (% (save-excursion (skip-chars-backward "\\\\")) 2))

At other places we let the regexp matcher skip those by using a hideous
regexp such as

    "[^\\]\\(?:\\\\\\\\\\)*/"

(but this regexp fails to match the closing / if it's right at the
starting position, so you have to use a workaround such as doing
a (forward-char -1) before searching).

>                   (progn
>                     (put-text-property
>                      (match-beginning 1)
>                      (1+ (match-beginning 1))

Aka (match-end 1).

>                      'syntax-table (string-to-syntax "|"))
>                     (setq end-found t)
>                     )))))
>       )))

You can avoid the `end-found` thingy with

    (while (and (re-search-forward "/" end 'move)
                (eq -1 (% (save-excursion (skip-chars-backward "\\\\")) 2))))
    (when (< (point) end) ;; Double check that `re-search-forward` succeeded.
      (put-text-property ...))

> (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)

(nth 8 match-start-state) gives the same boolean answer as this `or`.
And instead of having `syntax-propertize-rules` add a | syntax and then
you replacing it with "@" you could also tell `syntax-propertize-rules`
when to do it with something like:

    ("\\(#\\)/" (1 (when (null (nth 8 (save-excursion
                                        (syntax-ppss (match-beginning 0)))))
                     (prog1 "|"
                       (scheme-syntax-propertize-regexp-end
                        (point) end)))))

tho `syntax-propertize-rules` sadly doesn't currently handle this
combination of `when` and `prog1` :-(

    ("\\(#\\)/" (1 (when (null (nth 8 (save-excursion
                                        (syntax-ppss (match-beginning 0)))))
                     (put-text-property ... "|" ..)
                     (scheme-syntax-propertize-regexp-end
                      (point) end)
                     nil)))


- Stefan




reply via email to

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