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

From: David Reitter <[email-masked]>
Date: Sun, 21 Feb 2016 16:40:09 -0500

Alan,

Your patch works as advertised for my test case.  It’s certainly better to error out than to do the wrong thing.

I think you are catching the right situations, but my confidence is low because of the readability of the code (what is 4, 5?).

I think the question is whether that fix is appropriate for the 25.1 release.  If you want to apply it there, I would probably test a whole lot of cases in modes that are derivates of c-mode.

- David

> On Feb 21, 2016, at 7:35 AM, Alan Mackenzie <[email-masked]> wrote:
> 
> 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).