Subject: Re: bug#5560: 23.1.92; parens matching in c-mode broken

From: Alan Mackenzie <[email-masked]>
Date: Sun, 21 Feb 2016 12:35:39 +0000

Hello again, David and Andrew.

On Sat, Feb 20, 2016 at 10:57:23PM +0000, Alan Mackenzie wrote:
> On Tue, Feb 16, 2016 at 10:56:34PM -0500, Andrew Hyatt wrote:

> > I can confirm this still doesn't work right in Emacs 25.  However, I get
> > a slightly different experience, with clicking on all 3 left parens
> > highlighting until the first right paren only.  Similarly, that right
> > paren seems to be the matching paren for all 3 left parens.

> > David Reitter <[email-masked]> writes:

> > > Parens matching in C mode is sometimes surprising. In the example
> > > below, double-clicking on either of the first two opening parentheses 
> > > will mark the text until the "     hyper_modifier : 0)", but that is correct
> > > only for the second paren, while the first one is unmatched due to a space
> > > following the backslash.

> > > #define EV_MODIFIERS(e)                               \
> > >     ((([e modifierFlags] & NSHelpKeyMask) ?           \ 
> > >            hyper_modifier : 0)                        \    
> > >     ...

> > > It would be more useful if an "unmatched parentheses" was shown, or
> > > if the region up to the end of the scan process (i.e. the
> > > space+newline) was marked.

> Giving a decent error message here would be difficult.  We're down in the
> depths of the mouse code, but the strategem of giving syntax-table text
> properties to parentheses is a pure CC Mode one.  Signaling an error if
> a paren has other than paren syntax is liable to have unforseen side
> effects somewhere, somehow, some time.

After a night's sleep, I've changed my mind about the advisability of
such a fix.  So, here is a fix.  It works as indicated last night: if a
character whose normal syntax is open/close-paren has a different syntax
due to syntax-table text properties, a 'scan-error error is signaled:
either "Containing expression ends prematurely" for an open paren, or
"Unbalanced parentheses" for a close paren.

Here's the patch.  Please try it out and let me know if there's anything
amiss about it.  Otherwise, I'll commit it.

diff --git a/lisp/mouse.el b/lisp/mouse.el
index 85ffc43..22c5b48 100644
--- a/lisp/mouse.el
+++ b/lisp/mouse.el
@@ -931,20 +931,29 @@ mouse-start-end
               (= start end)
 	      (char-after start)
               (= (char-syntax (char-after start)) ?\())
-	 (list start
-	       (save-excursion
-		 (goto-char start)
-		 (forward-sexp 1)
-		 (point))))
+         (if (/= (car (syntax-after start)) 4)
+             ;; This happens in CC Mode when unbalanced parens in CPP
+             ;; constructs are given punctuation syntax with
+             ;; syntax-table text properties.  (2016-02-21).
+             (signal 'scan-error (list "Containing expression ends prematurely"
+                                       start start))
+           (list start
+                 (save-excursion
+                   (goto-char start)
+                   (forward-sexp 1)
+                   (point)))))
         ((and (= mode 1)
               (= start end)
 	      (char-after start)
               (= (char-syntax (char-after start)) ?\)))
-	 (list (save-excursion
-		 (goto-char (1+ start))
-		 (backward-sexp 1)
-		 (point))
-	       (1+ start)))
+         (if (/= (car (syntax-after start)) 5)
+             ;; See above comment about CC Mode.
+             (signal 'scan-error (list "Unbalanced parentheses" start start))
+           (list (save-excursion
+                   (goto-char (1+ start))
+                   (backward-sexp 1)
+                   (point))
+                 (1+ start))))
 	((and (= mode 1)
               (= start end)
 	      (char-after start)

-- 
Alan Mackenzie (Nuremberg, Germany).