]> git.eshelyaron.com Git - emacs.git/commitdiff
Add option for not highlight parens inside comments or strings
authorElías Gabriel Pérez <eg642616@gmail.com>
Mon, 12 May 2025 18:04:46 +0000 (12:04 -0600)
committerEshel Yaron <me@eshelyaron.com>
Sat, 7 Jun 2025 20:03:15 +0000 (22:03 +0200)
* lisp/paren.el (show-paren-not-in-comments-or-strings):
New user option.  (Bug#78396)
(show-paren-function): Enclose code in 'catch' function.
* etc/NEWS: Announce changes.
* doc/emacs/programs.texi (Matching): Document new option.

(cherry picked from commit 12397e3eb00c052455f03dc024e9335834f0c6ef)

doc/emacs/programs.texi
lisp/paren.el

index c62b6c252c60df47ec1ab58536ca4b385a5566cc..36c676c27184f885bd64de83f27ed05867bd5efe 100644 (file)
@@ -1022,6 +1022,13 @@ the opening delimiter is offscreen.  The context is usually the line
 that contains the opening delimiter, except if the opening delimiter
 is on its own line, in which case the context includes the previous
 nonblank line.
+
+@item
+@vindex show-paren-not-in-comments-or-strings
+If the value of @code{show-paren-not-in-comments-or-strings} is
+@code{all}, delimiters inside comments and strings will not be
+highlighted.  Otherwise if the value is set to @code{on-mismatch}, the
+mismatched delimiters inside comments will not be highlighted.
 @end itemize
 
 @cindex Electric Pair mode
index 9d7f131e043526e64bbbb9e4f44c2179f5abff16..986576a8e1d2df61ada7ad2752af5c62081ebb8a 100644 (file)
@@ -110,6 +110,19 @@ On non-graphical frames, the context is shown in the echo area."
                  (const :tag "In child-frame" child-frame))
   :version "29.1")
 
+(defcustom show-paren-not-in-comments-or-strings nil
+  "Do not highlight the paren that are inside a comment or string.
+If set to `all', do not highlight the paren that are inside comments
+or strings.
+If set to `on-mismatch', the paren mismatched inside comments will not be
+highlighted.
+If set to nil (by default), highlight the paren wherever it is."
+  :type '(choice
+          (const :tag "Never highlight" all)
+          (const :tag "Don't highlight when mismatched" on-mismatch)
+          (const :tag "Always highlight" nil))
+  :version "31.1")
+
 (defvar show-paren--idle-timer nil)
 (defvar show-paren--overlay
   (let ((ol (make-overlay (point) (point) nil t))) (delete-overlay ol) ol)
@@ -450,88 +463,97 @@ It is the default value of `show-paren-data-function'."
           (setq show-paren--last-pos (point)))
 
       ;; Found something to highlight.
-      (let* ((here-beg (nth 0 data))
-             (here-end (nth 1 data))
-             (there-beg (nth 2 data))
-             (there-end (nth 3 data))
-             (mismatch (nth 4 data))
-             (highlight-expression
-              (or (eq show-paren-style 'expression)
-                  (and there-beg
-                       (eq show-paren-style 'mixed)
-                       (let ((closest (if (< there-beg here-beg)
-                                          (1- there-end) (1+ there-beg))))
-                         (not (pos-visible-in-window-p closest))))))
-             (face
-              (cond
-               (mismatch
-                (if show-paren-ring-bell-on-mismatch
-                    (beep))
-                'show-paren-mismatch)
-               (highlight-expression 'show-paren-match-expression)
-               (t 'show-paren-match))))
-        ;;
-        ;; If matching backwards, highlight the closeparen
-        ;; before point as well as its matching open.
-        ;; If matching forward, and the openparen is unbalanced,
-        ;; highlight the paren at point to indicate misbalance.
-        ;; Otherwise, turn off any such highlighting.
-        (if (or (not here-beg)
-                (and (not show-paren-highlight-openparen)
-                     (> here-end (point))
-                     (<= here-beg (point))
-                     (integerp there-beg)))
-            (delete-overlay show-paren--overlay-1)
-          (move-overlay show-paren--overlay-1
-                        here-beg here-end (current-buffer))
-          ;; Always set the overlay face, since it varies.
-          (overlay-put show-paren--overlay-1 'priority show-paren-priority)
-          (overlay-put show-paren--overlay-1 'face face))
-        ;;
-        ;; Turn on highlighting for the matching paren, if found.
-        ;; If it's an unmatched paren, turn off any such highlighting.
-        (if (not there-beg)
-            (delete-overlay show-paren--overlay)
-          (if highlight-expression
-              (move-overlay show-paren--overlay
-                            (if (< there-beg here-beg) here-end here-beg)
-                            (if (< there-beg here-beg) there-beg there-end)
-                            (current-buffer))
-            (move-overlay show-paren--overlay
-                          there-beg there-end (current-buffer)))
-          ;; If `show-paren-context-when-offscreen' is non-nil and
-          ;; point is at a closing paren, show the context around the
-          ;; opening paren.
-          (let ((openparen (min here-beg there-beg)))
-            (when (and show-paren-context-when-offscreen
-                       (not (eql show-paren--last-pos (point)))
-                       (< there-beg here-beg)
-                       ;; Either OPENPAREN position is fully visible...
-                       (not (or (pos-visible-in-window-p openparen)
-                                (let ((dfh4 (* 0.25 (default-font-height)))
-                                      (part
-                                       (pos-visible-in-window-p openparen
-                                                                nil t)))
-                                  ;; ...or partially visible, and the
-                                  ;; invisible part is less than 1/4th
-                                  ;; of the default font height
-                                  (and (>= (length part) 4)
-                                       (< (nth 2 part) dfh4)
-                                       (< (nth 3 part) dfh4))))))
-              (let ((context (blink-paren-open-paren-line-string
-                              openparen))
-                    (message-log-max nil))
+      (catch 'sp-exit
+        (let* ((here-beg (nth 0 data))
+               (here-end (nth 1 data))
+               (there-beg (nth 2 data))
+               (there-end (nth 3 data))
+               (mismatch (nth 4 data))
+               (highlight-expression
+                (or (eq show-paren-style 'expression)
+                    (and there-beg
+                         (eq show-paren-style 'mixed)
+                         (let ((closest (if (< there-beg here-beg)
+                                            (1- there-end) (1+ there-beg))))
+                           (not (pos-visible-in-window-p closest))))))
+               (face
                 (cond
-                 ((eq show-paren-context-when-offscreen 'child-frame)
-                  (show-paren--show-context-in-child-frame context))
-                 ((eq show-paren-context-when-offscreen 'overlay)
-                  (show-paren--show-context-in-overlay context))
-                 (show-paren-context-when-offscreen
-                  (minibuffer-message "Matches %s" context))))))
-          (setq show-paren--last-pos (point))
-          ;; Always set the overlay face, since it varies.
-          (overlay-put show-paren--overlay 'priority show-paren-priority)
-          (overlay-put show-paren--overlay 'face face))))))
+                 (mismatch
+                  (if (and (eq show-paren-not-in-comments-or-strings 'on-mismatch)
+                           (save-excursion
+                             (syntax-ppss-context (syntax-ppss here-beg))))
+                      (throw 'sp-exit nil))
+                  (if show-paren-ring-bell-on-mismatch
+                      (beep))
+                  'show-paren-mismatch)
+                 (highlight-expression 'show-paren-match-expression)
+                 (t 'show-paren-match))))
+          (if (and (eq show-paren-not-in-comments-or-strings 'all)
+                   (save-excursion
+                     (syntax-ppss-context (syntax-ppss here-beg))))
+              (throw 'sp-exit nil))
+          ;;
+          ;; If matching backwards, highlight the closeparen
+          ;; before point as well as its matching open.
+          ;; If matching forward, and the openparen is unbalanced,
+          ;; highlight the paren at point to indicate misbalance.
+          ;; Otherwise, turn off any such highlighting.
+          (if (or (not here-beg)
+                  (and (not show-paren-highlight-openparen)
+                       (> here-end (point))
+                       (<= here-beg (point))
+                       (integerp there-beg)))
+              (delete-overlay show-paren--overlay-1)
+            (move-overlay show-paren--overlay-1
+                          here-beg here-end (current-buffer))
+            ;; Always set the overlay face, since it varies.
+            (overlay-put show-paren--overlay-1 'priority show-paren-priority)
+            (overlay-put show-paren--overlay-1 'face face))
+          ;;
+          ;; Turn on highlighting for the matching paren, if found.
+          ;; If it's an unmatched paren, turn off any such highlighting.
+          (if (not there-beg)
+              (delete-overlay show-paren--overlay)
+            (if highlight-expression
+                (move-overlay show-paren--overlay
+                              (if (< there-beg here-beg) here-end here-beg)
+                              (if (< there-beg here-beg) there-beg there-end)
+                              (current-buffer))
+              (move-overlay show-paren--overlay
+                            there-beg there-end (current-buffer)))
+            ;; If `show-paren-context-when-offscreen' is non-nil and
+            ;; point is at a closing paren, show the context around the
+            ;; opening paren.
+            (let ((openparen (min here-beg there-beg)))
+              (when (and show-paren-context-when-offscreen
+                         (not (eql show-paren--last-pos (point)))
+                         (< there-beg here-beg)
+                         ;; Either OPENPAREN position is fully visible...
+                         (not (or (pos-visible-in-window-p openparen)
+                                  (let ((dfh4 (* 0.25 (default-font-height)))
+                                        (part
+                                         (pos-visible-in-window-p openparen
+                                                                  nil t)))
+                                    ;; ...or partially visible, and the
+                                    ;; invisible part is less than 1/4th
+                                    ;; of the default font height
+                                    (and (>= (length part) 4)
+                                         (< (nth 2 part) dfh4)
+                                         (< (nth 3 part) dfh4))))))
+                (let ((context (blink-paren-open-paren-line-string
+                                openparen))
+                      (message-log-max nil))
+                  (cond
+                   ((eq show-paren-context-when-offscreen 'child-frame)
+                    (show-paren--show-context-in-child-frame context))
+                   ((eq show-paren-context-when-offscreen 'overlay)
+                    (show-paren--show-context-in-overlay context))
+                   (show-paren-context-when-offscreen
+                    (minibuffer-message "Matches %s" context))))))
+            (setq show-paren--last-pos (point))
+            ;; Always set the overlay face, since it varies.
+            (overlay-put show-paren--overlay 'priority show-paren-priority)
+            (overlay-put show-paren--overlay 'face face)))))))
 
 (provide 'paren)