GNU bug report logs - #50538
[PATCH] 28.0.50; electric-pair-mode fails to pair double quotes in some cases in CC mode

Previous Next

Package: emacs;

Reported by: Jim Porter <jporterbugs <at> gmail.com>

Date: Sun, 12 Sep 2021 03:59:02 UTC

Severity: normal

Tags: patch

Fixed in version 29.1

Done: Lars Ingebrigtsen <larsi <at> gnus.org>

Bug is archived. No further changes may be made.

To add a comment to this bug, you must first unarchive it, by sending
a message to control AT debbugs.gnu.org, with unarchive 50538 in the body.
You can then email your comments to 50538 AT debbugs.gnu.org in the normal way.

Toggle the display of automated, internal messages from the tracker.

View this report as an mbox folder, status mbox, maintainer mbox


Report forwarded to bug-gnu-emacs <at> gnu.org:
bug#50538; Package emacs. (Sun, 12 Sep 2021 03:59:02 GMT) Full text and rfc822 format available.

Acknowledgement sent to Jim Porter <jporterbugs <at> gmail.com>:
New bug report received and forwarded. Copy sent to bug-gnu-emacs <at> gnu.org. (Sun, 12 Sep 2021 03:59:02 GMT) Full text and rfc822 format available.

Message #5 received at submit <at> debbugs.gnu.org (full text, mbox):

From: Jim Porter <jporterbugs <at> gmail.com>
To: bug-gnu-emacs <at> gnu.org
Subject: [PATCH] 28.0.50; electric-pair-mode fails to pair double quotes in
 some cases in CC mode
Date: Sat, 11 Sep 2021 20:58:47 -0700
[Message part 1 (text/plain, inline)]
(Note: I've just updated my copyright assignment information, but 
haven't received confirmation that everything is in order, so this might 
need to wait until that's done for it to merge.)

There are a few related issues with pairing double quotes in CC mode 
while using `electric-pair-mode'. Hopefully the steps to reproduce below 
will explain the issues. In all the cases, I'd expect 
`electric-pair-mode' to insert a closing quote, but it doesn't. You can 
try similar steps in a `ruby-mode' buffer to see how it should work.

----------------------------------------

Common setup
------------

  $ cat foo.c
  "foobar"

  $ emacs -Q foo.c
  M-x electric-pair-mode

Note that | represents the point below.

1. Quote pairing in comments
----------------------------

  C-o   ;; to make a blank line
  // "  ;; type this

Expected: line 1 is // "|"
Actual:   line 1 is // "|

2. Inserting quote pairs before existing string
-----------------------------------------------

  "  ;; type this (point is at beginning of buffer, before "foobar")

Expected: line 1 is "|""foobar"
Actual:   line 1 is "|"foobar"

3. Splitting strings into two
-----------------------------

  "foo|bar"  ;; move point here
  "          ;; type this

Expected: line 1 is "foo"|"bar"
Actual:   line 1 is "foo"|bar"

----------------------------------------

This is because the logic in the patch for bug#36474 isn't quite right. 
Currently, `c-electric-pair-inhibit-predicate' checks if the 
newly-inserted quotation mark has "a string fence syntax-table text 
property" (i.e. if it's the start of a string literal not terminated on 
that line[1]). However, this fails in all three cases above: in (1) 
because we're in a comment, not a string literal; and in (2) and (3) 
because it's the *last* quotation mark on the line that's unterminated, 
not the one before point.

The attached patch fixes this by taking those cases into account. I also 
added `c-mode' to the list of modes to check in 
`test/lisp/electric-tests.el'. This required setting single-line 
comments as the default in those tests, since the tests expect 
single-line comments (I tried testing under `c++-mode', but the tests 
failed, I think due to <> being paren-like in C++).

[1] I think this is what it means, at least (or close to it).
[0001-Improve-behavior-of-electric-pair-mode-in-cc-mode.patch (text/plain, attachment)]

Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#50538; Package emacs. (Sun, 12 Sep 2021 06:27:02 GMT) Full text and rfc822 format available.

Message #8 received at 50538 <at> debbugs.gnu.org (full text, mbox):

From: Eli Zaretskii <eliz <at> gnu.org>
To: Jim Porter <jporterbugs <at> gmail.com>
Cc: 50538 <at> debbugs.gnu.org
Subject: Re: bug#50538: [PATCH] 28.0.50;
 electric-pair-mode fails to pair double quotes in some cases in CC
 mode
Date: Sun, 12 Sep 2021 09:26:05 +0300
> From: Jim Porter <jporterbugs <at> gmail.com>
> Date: Sat, 11 Sep 2021 20:58:47 -0700
> 
> There are a few related issues with pairing double quotes in CC mode 
> while using `electric-pair-mode'. Hopefully the steps to reproduce below 
> will explain the issues. In all the cases, I'd expect 
> `electric-pair-mode' to insert a closing quote, but it doesn't.

Your expected results seem to expect Emacs to assume that a new string
will be inserted, but is that an assumption that is always true?  It
could be that the user wants to modify the existing string instead, in
which case your suggested patches will require the user to delete more
quotes than previously.




Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#50538; Package emacs. (Sun, 12 Sep 2021 18:06:01 GMT) Full text and rfc822 format available.

Message #11 received at 50538 <at> debbugs.gnu.org (full text, mbox):

From: Jim Porter <jporterbugs <at> gmail.com>
To: Eli Zaretskii <eliz <at> gnu.org>
Cc: 50538 <at> debbugs.gnu.org
Subject: Re: bug#50538: [PATCH] 28.0.50; electric-pair-mode fails to pair
 double quotes in some cases in CC mode
Date: Sun, 12 Sep 2021 11:05:17 -0700
[Message part 1 (text/plain, inline)]
On 9/11/2021 11:26 PM, Eli Zaretskii wrote:
>> From: Jim Porter <jporterbugs <at> gmail.com>
>> Date: Sat, 11 Sep 2021 20:58:47 -0700
>>
>> There are a few related issues with pairing double quotes in CC mode
>> while using `electric-pair-mode'. Hopefully the steps to reproduce below
>> will explain the issues. In all the cases, I'd expect
>> `electric-pair-mode' to insert a closing quote, but it doesn't.
> 
> Your expected results seem to expect Emacs to assume that a new string
> will be inserted, but is that an assumption that is always true?

In these cases, I believe that's true (with the default 
`electric-pair-mode' settings, that is). More broadly, the goal of the 
patch is to ensure that pairing of double quotes works the same in CC 
mode as it does in other modes (`ruby-mode', `python-mode', `js-mode', 
`emacs-lisp-mode', etc), which is why I added `c-mode' to the list of 
modes to test in `test/lisp/electric-tests.el'.

That said, there's one potential case I didn't account for (mostly 
because it wasn't accounted for in the patch for bug#36474): if a user 
customizes `electric-pair-inhibit-predicate' to inhibit cases like (2) 
or (3) in my original message, that won't work right in CC modes, since 
the default value of `electric-pair-inhibit-predicate' (set by the user) 
won't be called.

Attached is an updated patch that changes the logic of 
`c-electric-pair-inhibit-predicate' to either a) inhibit insertion of 
the closing quote, or b) call the default-value of 
`electric-pair-inhibit-predicate' to determine what to do. This should 
give users more consistent behavior when customizing 
`electric-pair-inhibit-predicate'.

The tests still pass, although I wasn't able to figure out a good way to 
add a test for setting `electric-pair-inhibit-predicate' that works with 
how CC mode overrides it (using `:bindings' in 
`define-electric-pair-test' didn't work, since the binding is set too 
late). Hopefully that's ok; if not, I can try and see about making some 
more extensive changes to the tests to account for this.

Note however that this solution isn't perfect: it means a user's custom 
`electric-pair-inhibit-predicate' can only inhibit *more* than CC mode's 
default behavior, not less. I think that's a reasonable compromise 
though, and users who want more direct control can set 
`electric-pair-inhibit-predicate' inside `c-mode-common-hook'. A 
"perfect" solution here would probably require adding new customization 
points to `electric-pair-mode' (e.g. a way for major modes to override 
how the syntax is analyzed), and I'm not sure the added complexity would 
be worth it, especially since this code is already a bit tricky.
[0001-Improve-behavior-of-electric-pair-mode-in-cc-mode.patch (text/plain, attachment)]

Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#50538; Package emacs. (Wed, 15 Sep 2021 22:18:01 GMT) Full text and rfc822 format available.

Message #14 received at 50538 <at> debbugs.gnu.org (full text, mbox):

From: Jim Porter <jporterbugs <at> gmail.com>
To: Eli Zaretskii <eliz <at> gnu.org>
Cc: 50538 <at> debbugs.gnu.org
Subject: Re: bug#50538: [PATCH] 28.0.50; electric-pair-mode fails to pair
 double quotes in some cases in CC mode
Date: Wed, 15 Sep 2021 15:17:23 -0700
On 9/11/2021 8:58 PM, Jim Porter wrote:
> (Note: I've just updated my copyright assignment information, but
> haven't received confirmation that everything is in order, so this might
> need to wait until that's done for it to merge.)

I've gotten confirmation that my copyright assignment info is all 
up-to-date, so once this patch passes muster, it should be ok to merge it.

On 9/12/2021 11:05 AM, Jim Porter wrote:
> Note however that this solution isn't perfect: it means a user's custom 
> `electric-pair-inhibit-predicate' can only inhibit *more* than CC mode's 
> default behavior, not less. I think that's a reasonable compromise 
> though, and users who want more direct control can set 
> `electric-pair-inhibit-predicate' inside `c-mode-common-hook'. A 
> "perfect" solution here would probably require adding new customization 
> points to `electric-pair-mode' (e.g. a way for major modes to override 
> how the syntax is analyzed), and I'm not sure the added complexity would 
> be worth it, especially since this code is already a bit tricky.

I'm not sure if someone has a better idea for how to do things, but for 
my config[1], the patch works well and makes CC modes behave the same as 
other programming modes. In my opinion, the worst thing 
`electric-pair-mode' can do is to behave inconsistently, since that 
forces the user to pay close attention to something that should be 
almost invisible/automatic.

[1] I customize `electric-pair-inhibit-predicate' to disable 
electric-pairing in strings/comments, and this patch interacts correctly 
with that customization.




Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#50538; Package emacs. (Thu, 16 Sep 2021 05:26:01 GMT) Full text and rfc822 format available.

Message #17 received at 50538 <at> debbugs.gnu.org (full text, mbox):

From: Eli Zaretskii <eliz <at> gnu.org>
To: Jim Porter <jporterbugs <at> gmail.com>,
 Lars Ingebrigtsen <larsi <at> gnus.org>, Alan Mackenzie <acm <at> muc.de>
Cc: 50538 <at> debbugs.gnu.org
Subject: Re: bug#50538: [PATCH] 28.0.50; electric-pair-mode fails to pair
 double quotes in some cases in CC mode
Date: Thu, 16 Sep 2021 08:25:33 +0300
> From: Jim Porter <jporterbugs <at> gmail.com>
> Cc: 50538 <at> debbugs.gnu.org
> Date: Wed, 15 Sep 2021 15:17:23 -0700
> 
> On 9/11/2021 8:58 PM, Jim Porter wrote:
>  > (Note: I've just updated my copyright assignment information, but
>  > haven't received confirmation that everything is in order, so this might
>  > need to wait until that's done for it to merge.)
> 
> I've gotten confirmation that my copyright assignment info is all 
> up-to-date, so once this patch passes muster, it should be ok to merge it.

Your copyright assignment is on file, so we are good in that
department.

> On 9/12/2021 11:05 AM, Jim Porter wrote:
> > Note however that this solution isn't perfect: it means a user's custom 
> > `electric-pair-inhibit-predicate' can only inhibit *more* than CC mode's 
> > default behavior, not less. I think that's a reasonable compromise 
> > though, and users who want more direct control can set 
> > `electric-pair-inhibit-predicate' inside `c-mode-common-hook'. A 
> > "perfect" solution here would probably require adding new customization 
> > points to `electric-pair-mode' (e.g. a way for major modes to override 
> > how the syntax is analyzed), and I'm not sure the added complexity would 
> > be worth it, especially since this code is already a bit tricky.
> 
> I'm not sure if someone has a better idea for how to do things, but for 
> my config[1], the patch works well and makes CC modes behave the same as 
> other programming modes. In my opinion, the worst thing 
> `electric-pair-mode' can do is to behave inconsistently, since that 
> forces the user to pay close attention to something that should be 
> almost invisible/automatic.

I don't use this minor mode, so I don't think my opinion on this
matters much.  I will defer to Lars and Alan here.




Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#50538; Package emacs. (Thu, 16 Sep 2021 12:41:02 GMT) Full text and rfc822 format available.

Message #20 received at 50538 <at> debbugs.gnu.org (full text, mbox):

From: Lars Ingebrigtsen <larsi <at> gnus.org>
To: Eli Zaretskii <eliz <at> gnu.org>
Cc: Jim Porter <jporterbugs <at> gmail.com>, 50538 <at> debbugs.gnu.org,
 Alan Mackenzie <acm <at> muc.de>
Subject: Re: bug#50538: [PATCH] 28.0.50; electric-pair-mode fails to pair
 double quotes in some cases in CC mode
Date: Thu, 16 Sep 2021 14:40:40 +0200
Eli Zaretskii <eliz <at> gnu.org> writes:

> I don't use this minor mode, so I don't think my opinion on this
> matters much.  I will defer to Lars and Alan here.

I seldom use electric-pair-mode, and since this touches cc-mode, I'll
defer to Alan.  :-)

Alan?

-- 
(domestic pets only, the antidote for overdose, milk.)
   bloggy blog: http://lars.ingebrigtsen.no




Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#50538; Package emacs. (Thu, 16 Sep 2021 13:00:02 GMT) Full text and rfc822 format available.

Message #23 received at 50538 <at> debbugs.gnu.org (full text, mbox):

From: Dmitry Gutov <dgutov <at> yandex.ru>
To: Lars Ingebrigtsen <larsi <at> gnus.org>, Eli Zaretskii <eliz <at> gnu.org>
Cc: Jim Porter <jporterbugs <at> gmail.com>, 50538 <at> debbugs.gnu.org,
 Alan Mackenzie <acm <at> muc.de>
Subject: Re: bug#50538: [PATCH] 28.0.50; electric-pair-mode fails to pair
 double quotes in some cases in CC mode
Date: Thu, 16 Sep 2021 15:59:11 +0300
On 16.09.2021 15:40, Lars Ingebrigtsen wrote:
> Eli Zaretskii<eliz <at> gnu.org>  writes:
> 
>> I don't use this minor mode, so I don't think my opinion on this
>> matters much.  I will defer to Lars and Alan here.
> I seldom use electric-pair-mode, and since this touches cc-mode, I'll
> defer to Alan.:-)
> 
> Alan?

At risk of reigniting an old disagreement, perhaps we should ask Joao?

IIUC, Alan doesn't really use electric-pair-mode.




Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#50538; Package emacs. (Thu, 16 Sep 2021 13:18:01 GMT) Full text and rfc822 format available.

Message #26 received at 50538 <at> debbugs.gnu.org (full text, mbox):

From: Lars Ingebrigtsen <larsi <at> gnus.org>
To: Dmitry Gutov <dgutov <at> yandex.ru>
Cc: Jim Porter <jporterbugs <at> gmail.com>, Eli Zaretskii <eliz <at> gnu.org>,
 João Távora <joaotavora <at> gmail.com>,
 50538 <at> debbugs.gnu.org, Alan Mackenzie <acm <at> muc.de>
Subject: Re: bug#50538: [PATCH] 28.0.50; electric-pair-mode fails to pair
 double quotes in some cases in CC mode
Date: Thu, 16 Sep 2021 15:17:28 +0200
Dmitry Gutov <dgutov <at> yandex.ru> writes:

>>> I don't use this minor mode, so I don't think my opinion on this
>>> matters much.  I will defer to Lars and Alan here.
>> I seldom use electric-pair-mode, and since this touches cc-mode, I'll
>> defer to Alan.:-)
>> Alan?
>
> At risk of reigniting an old disagreement, perhaps we should ask Joao?

Sure; added to the CCs.  João, do you have an opinion here?

-- 
(domestic pets only, the antidote for overdose, milk.)
   bloggy blog: http://lars.ingebrigtsen.no




Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#50538; Package emacs. (Thu, 16 Sep 2021 17:06:02 GMT) Full text and rfc822 format available.

Message #29 received at 50538 <at> debbugs.gnu.org (full text, mbox):

From: João Távora <joaotavora <at> gmail.com>
To: Lars Ingebrigtsen <larsi <at> gnus.org>
Cc: Jim Porter <jporterbugs <at> gmail.com>, Eli Zaretskii <eliz <at> gnu.org>,
 Alan Mackenzie <acm <at> muc.de>, 50538 <at> debbugs.gnu.org,
 Dmitry Gutov <dgutov <at> yandex.ru>
Subject: Re: bug#50538: [PATCH] 28.0.50; electric-pair-mode fails to pair
 double quotes in some cases in CC mode
Date: Thu, 16 Sep 2021 18:04:53 +0100
Lars Ingebrigtsen <larsi <at> gnus.org> writes:

> Dmitry Gutov <dgutov <at> yandex.ru> writes:
>
>>>> I don't use this minor mode, so I don't think my opinion on this
>>>> matters much.  I will defer to Lars and Alan here.
>>> I seldom use electric-pair-mode, and since this touches cc-mode, I'll
>>> defer to Alan.:-)
>>> Alan?
>>
>> At risk of reigniting an old disagreement, perhaps we should ask Joao?
>
> Sure; added to the CCs.  João, do you have an opinion here?

I couldn't understand the initial issue fully, but I can only confirm
that the relationship between cc-mode and electric-pair-mode has been
rocky.  I think the situation is similar with electric-layout-mode and
with electric-indent-mode, to a certain degree (though I am not sure for
this last one).

I don't think there are any easy technical solutions for it. I certainly
cannot invest the effort in any of them right now.

It wasn't like this from the beginning: when I first created
electric-pair-mode it worked mostly if not fully fine with cc-mode, like
one expects e-p-m to work in other modes (ruby, python, js, elisp, rust,
perl, even non-programming modes).

At times, compatibility deteriorated as cc-mode added mechanisms for
solving electricity problems or related problems in an idiosyncratic
way.  Sometimes these changes broke e-p-m's tests and the solution was
-- incorrectly in my view --to disable the tests "temporarily".  I see
that for one of them at least, the test has been re-instated.  A good
sign, maybe.  

Regardless of history and current state of affairs, my personal solution
to C in Emacs is to use a hand-rolled mode, a so-called plainer-cc-mode.
The goal is to make it behave like most other modes w.r.t
electric-pair-mode and keep the basic c syntax and indentation.  I've
used it reasonably successfully with C and C++.  Here it is in its
entirety.  I think I use something similar for c++-mode.

   (define-derived-mode plainer-c-mode c-mode "pC"
     "A plainer C-mode with no internal electric machinery."
     (c-toggle-electric-state -1)
     (setq-local electric-indent-local-mode-hook nil)
     (setq-local electric-indent-mode-hook nil)
     (electric-indent-local-mode 1)
     (dolist (key '(?\" ?\' ?\{ ?\} ?\( ?\) ?\[ ?\]))
       (local-set-key (vector key) 'self-insert-command)))

Among other simpler things, this makes the major mode not bind special
keys to special commands.  They are all bound to `self-insert-command`
like most major modes.  This simplifies electric-pair-mode, as far as I
remember.

The above is a hack, but not very dirty one.  The one below much more so.
It's a brute-force hack for solving electricity problems.  It simply
disables some cc internal functions.  May be out of date by now, YMMV, 
warranty void, etc, as they say.

   (defun joaot/disable-some-cc-things ()
     (interactive)
     (dolist (name '(c-restore-string-fences
                     c-remove-string-fences
                     c-before-change-check-unbalanced-strings
                     c-after-change-mark-abnormal-strings
                     c-after-change-escape-NL-in-string))
       (advice-add name :override #'ignore '((name . joaot/remove-disable-some-cc-things)))
       (add-hook 'c-mode-common-hook
                 (lambda ()
                   (kill-local-variable 'electric-pair-inhibit-predicate)))))

On the C++/C editing-front, I am eagerly waiting for Treesitter to
arrive so that is it becomes possible to write a new major mode for c++
and c from scratch.  Reusing solid and efficient parsing logic based on
language grammars.  Another more closely available option, is to simply
use LSP for indentation and fontification.  Though that is almost
certainly slower and less confortable/portable/etc... Anyway, whatever
the solution, I'm quite confident that such a mode won't have these
characteristics that cc-mode has when used with `electric-pair-mode`.

If you're writing C, and not C++, my also try Stefan Monnier's aptly
named sm-c-mode, installable via M-x package-install RET sm-c-mode.
Works fine with electric-pair-mode, but seems to indent very oddly for
some reason.

Hope this helps.  I'm sorry I can't offer any better solutions.

João




Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#50538; Package emacs. (Thu, 16 Sep 2021 17:12:02 GMT) Full text and rfc822 format available.

Message #32 received at 50538 <at> debbugs.gnu.org (full text, mbox):

From: Eli Zaretskii <eliz <at> gnu.org>
To: João Távora <joaotavora <at> gmail.com>
Cc: jporterbugs <at> gmail.com, larsi <at> gnus.org, acm <at> muc.de, 50538 <at> debbugs.gnu.org,
 dgutov <at> yandex.ru
Subject: Re: bug#50538: [PATCH] 28.0.50; electric-pair-mode fails to pair
 double quotes in some cases in CC mode
Date: Thu, 16 Sep 2021 20:11:41 +0300
> From: João Távora <joaotavora <at> gmail.com>
> Cc: Dmitry Gutov <dgutov <at> yandex.ru>,  Eli Zaretskii <eliz <at> gnu.org>,  Jim
>  Porter <jporterbugs <at> gmail.com>,  50538 <at> debbugs.gnu.org,  Alan Mackenzie
>  <acm <at> muc.de>
> Date: Thu, 16 Sep 2021 18:04:53 +0100
> 
> Hope this helps.  I'm sorry I can't offer any better solutions.

Thanks, but I'm not sure I understand what is your opinion about the
proposed patch.  Are you saying we shouldn't install it?




Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#50538; Package emacs. (Thu, 16 Sep 2021 17:31:02 GMT) Full text and rfc822 format available.

Message #35 received at 50538 <at> debbugs.gnu.org (full text, mbox):

From: Jim Porter <jporterbugs <at> gmail.com>
To: João Távora <joaotavora <at> gmail.com>,
 Lars Ingebrigtsen <larsi <at> gnus.org>
Cc: Alan Mackenzie <acm <at> muc.de>, 50538 <at> debbugs.gnu.org,
 Dmitry Gutov <dgutov <at> yandex.ru>
Subject: Re: bug#50538: [PATCH] 28.0.50; electric-pair-mode fails to pair
 double quotes in some cases in CC mode
Date: Thu, 16 Sep 2021 10:29:47 -0700
On 9/16/2021 10:04 AM, João Távora wrote:
> 
> I couldn't understand the initial issue fully, but I can only confirm
> that the relationship between cc-mode and electric-pair-mode has been
> rocky.  I think the situation is similar with electric-layout-mode and
> with electric-indent-mode, to a certain degree (though I am not sure for
> this last one).

Hopefully the following summary will help. My patch is essentially an 
enhancement of the patch from bug#36474. In that bug, Alan Mackenzie 
describes the problem:

> Diagnosis: electric-pair--unbalanced-strings-p works after the (single)
> newly typed " has been stripped from the buffer.  It attempts to
> determine whether there are any open strings after the point of
> insertion.  It does this by using parse-partial-sexp, and checks (nth 3
> <result>) as evidence of an open string.
> 
> This does not work in CC Mode, since although there is an open string
> marker (with a string fence syntax-table property on it) this is
> "closed" (from parse-partial-sexp's point of view) by the string fence
> property on the newline at the end of the line.
> electric-pair--unbalanced-strings-p thus returns the wrong result.

The fix in that bug was to check if the just-inserted double-quote "is 
marked with a string fence syntax-table text property". That fixes the 
issue described in bug#36474, but it's not quite the right logic. CC 
Mode gives the *last* double-quote on a line the string fence property 
if a line has unbalanced quotes. Thus, the patch changes the behavior to 
check the last double-quote on the line, rather than the just-inserted 
double-quote.

The patch makes one other improvement as well: it doesn't check for the 
string fence property on a double-quote inside a comment. CC Mode 
doesn't apply string fence properties there, since it's not necessary. 
Therefore, inside a comment, `c-electric-pair-inhibit-predicate' just 
defers to the default value of `electric-pair-inhibit-predicate'.

As I mentioned earlier in the thread, this isn't quite perfect behavior, 
but it significantly improves the common case (`electric-pair-mode' with 
default or "default-like" settings). CC Mode's practice of closing 
strings at the end of a line - even without a closing quote - just 
doesn't play nicely with `electric-pair-mode', so barring some major 
changes to either CC Mode or `electric-pair-mode', I can't think of a 
way to improve this patch beyond where it's at now.




Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#50538; Package emacs. (Thu, 16 Sep 2021 17:34:02 GMT) Full text and rfc822 format available.

Message #38 received at 50538 <at> debbugs.gnu.org (full text, mbox):

From: João Távora <joaotavora <at> gmail.com>
To: Eli Zaretskii <eliz <at> gnu.org>
Cc: Jim Porter <jporterbugs <at> gmail.com>, Lars Ingebrigtsen <larsi <at> gnus.org>,
 Alan Mackenzie <acm <at> muc.de>, 50538 <at> debbugs.gnu.org,
 Dmitry Gutov <dgutov <at> yandex.ru>
Subject: Re: bug#50538: [PATCH] 28.0.50; electric-pair-mode fails to pair
 double quotes in some cases in CC mode
Date: Thu, 16 Sep 2021 18:33:12 +0100
On Thu, Sep 16, 2021 at 6:11 PM Eli Zaretskii <eliz <at> gnu.org> wrote:
>
> > From: João Távora <joaotavora <at> gmail.com>
> > Cc: Dmitry Gutov <dgutov <at> yandex.ru>,  Eli Zaretskii <eliz <at> gnu.org>,  Jim
> >  Porter <jporterbugs <at> gmail.com>,  50538 <at> debbugs.gnu.org,  Alan Mackenzie
> >  <acm <at> muc.de>
> > Date: Thu, 16 Sep 2021 18:04:53 +0100
> >
> > Hope this helps.  I'm sorry I can't offer any better solutions.
>
> Thanks, but I'm not sure I understand what is your opinion about the
> proposed patch.  Are you saying we shouldn't install it?

That patch targets mainly cc-mode.el.  To have an opinion would
require me to understand it, interpret its meaning. That has many
implications...  I can't do that right now.  I can confirm that the small
change to electric-tests.el (which activates many tests for c-mode) is
indeed the way I wrote those tests originally.  Maybe Jim has
found a silver bullet?

João




Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#50538; Package emacs. (Thu, 16 Sep 2021 18:27:01 GMT) Full text and rfc822 format available.

Message #41 received at 50538 <at> debbugs.gnu.org (full text, mbox):

From: Alan Mackenzie <acm <at> muc.de>
To: Eli Zaretskii <eliz <at> gnu.org>
Cc: Jim Porter <jporterbugs <at> gmail.com>, Lars Ingebrigtsen <larsi <at> gnus.org>,
 50538 <at> debbugs.gnu.org
Subject: Re: bug#50538: [PATCH] 28.0.50; electric-pair-mode fails to pair
 double quotes in some cases in CC mode
Date: Thu, 16 Sep 2021 18:26:36 +0000
Hello, Eli.

On Thu, Sep 16, 2021 at 08:25:33 +0300, Eli Zaretskii wrote:
> > From: Jim Porter <jporterbugs <at> gmail.com>
> > Cc: 50538 <at> debbugs.gnu.org
> > Date: Wed, 15 Sep 2021 15:17:23 -0700

> > On 9/11/2021 8:58 PM, Jim Porter wrote:
> >  > (Note: I've just updated my copyright assignment information, but
> >  > haven't received confirmation that everything is in order, so this might
> >  > need to wait until that's done for it to merge.)

> > I've gotten confirmation that my copyright assignment info is all 
> > up-to-date, so once this patch passes muster, it should be ok to merge it.

> Your copyright assignment is on file, so we are good in that
> department.

> > On 9/12/2021 11:05 AM, Jim Porter wrote:
> > > Note however that this solution isn't perfect: it means a user's custom 
> > > `electric-pair-inhibit-predicate' can only inhibit *more* than CC mode's 
> > > default behavior, not less. I think that's a reasonable compromise 
> > > though, and users who want more direct control can set 
> > > `electric-pair-inhibit-predicate' inside `c-mode-common-hook'. A 
> > > "perfect" solution here would probably require adding new customization 
> > > points to `electric-pair-mode' (e.g. a way for major modes to override 
> > > how the syntax is analyzed), and I'm not sure the added complexity would 
> > > be worth it, especially since this code is already a bit tricky.

> > I'm not sure if someone has a better idea for how to do things, but for 
> > my config[1], the patch works well and makes CC modes behave the same as 
> > other programming modes. In my opinion, the worst thing 
> > `electric-pair-mode' can do is to behave inconsistently, since that 
> > forces the user to pay close attention to something that should be 
> > almost invisible/automatic.

> I don't use this minor mode, so I don't think my opinion on this
> matters much.  I will defer to Lars and Alan here.

Thanks, I've downloaded the bug thread from debbugs, and I'll look at
it.  I don't actually use the minor mode either, but the patch is to do
with C++ Mode.

-- 
Alan Mackenzie (Nuremberg, Germany).




Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#50538; Package emacs. (Thu, 16 Sep 2021 19:07:02 GMT) Full text and rfc822 format available.

Message #44 received at 50538 <at> debbugs.gnu.org (full text, mbox):

From: Alan Mackenzie <acm <at> muc.de>
To: João Távora <joaotavora <at> gmail.com>
Cc: Jim Porter <jporterbugs <at> gmail.com>, Lars Ingebrigtsen <larsi <at> gnus.org>,
 Eli Zaretskii <eliz <at> gnu.org>, 50538 <at> debbugs.gnu.org,
 Dmitry Gutov <dgutov <at> yandex.ru>
Subject: Re: bug#50538: [PATCH] 28.0.50; electric-pair-mode fails to pair
 double quotes in some cases in CC mode
Date: Thu, 16 Sep 2021 19:05:56 +0000
Hello, João.

On Thu, Sep 16, 2021 at 18:04:53 +0100, João Távora wrote:
> Lars Ingebrigtsen <larsi <at> gnus.org> writes:

> > Dmitry Gutov <dgutov <at> yandex.ru> writes:

> >>>> I don't use this minor mode, so I don't think my opinion on this
> >>>> matters much.  I will defer to Lars and Alan here.
> >>> I seldom use electric-pair-mode, and since this touches cc-mode, I'll
> >>> defer to Alan.:-)
> >>> Alan?

> >> At risk of reigniting an old disagreement, perhaps we should ask Joao?

> > Sure; added to the CCs.  João, do you have an opinion here?

> I couldn't understand the initial issue fully, but I can only confirm
> that the relationship between cc-mode and electric-pair-mode has been
> rocky.  I think the situation is similar with electric-layout-mode and
> with electric-indent-mode, to a certain degree (though I am not sure for
> this last one).

I think it is up to both of us to make this relationship less rocky.

> I don't think there are any easy technical solutions for it. I certainly
> cannot invest the effort in any of them right now.

> It wasn't like this from the beginning: when I first created
> electric-pair-mode it worked mostly if not fully fine with cc-mode, like
> one expects e-p-m to work in other modes (ruby, python, js, elisp, rust,
> perl, even non-programming modes).

> At times, compatibility deteriorated as cc-mode added mechanisms for
> solving electricity problems or related problems in an idiosyncratic
> way.  Sometimes these changes broke e-p-m's tests and the solution was
> -- incorrectly in my view --to disable the tests "temporarily".  I see
> that for one of them at least, the test has been re-instated.  A good
> sign, maybe.  

> Regardless of history and current state of affairs, my personal solution
> to C in Emacs is to use a hand-rolled mode, a so-called plainer-cc-mode.
> The goal is to make it behave like most other modes w.r.t
> electric-pair-mode and keep the basic c syntax and indentation.  I've
> used it reasonably successfully with C and C++.  Here it is in its
> entirety.  I think I use something similar for c++-mode.

>    (define-derived-mode plainer-c-mode c-mode "pC"
>      "A plainer C-mode with no internal electric machinery."
>      (c-toggle-electric-state -1)
>      (setq-local electric-indent-local-mode-hook nil)
>      (setq-local electric-indent-mode-hook nil)
>      (electric-indent-local-mode 1)
>      (dolist (key '(?\" ?\' ?\{ ?\} ?\( ?\) ?\[ ?\]))
>        (local-set-key (vector key) 'self-insert-command)))

> Among other simpler things, this makes the major mode not bind special
> keys to special commands.  They are all bound to `self-insert-command`
> like most major modes.  This simplifies electric-pair-mode, as far as I
> remember.

> The above is a hack, but not very dirty one.  The one below much more so.
> It's a brute-force hack for solving electricity problems.  It simply
> disables some cc internal functions.  May be out of date by now, YMMV, 
> warranty void, etc, as they say.

>    (defun joaot/disable-some-cc-things ()
>      (interactive)
>      (dolist (name '(c-restore-string-fences
>                      c-remove-string-fences
>                      c-before-change-check-unbalanced-strings
>                      c-after-change-mark-abnormal-strings
>                      c-after-change-escape-NL-in-string))
>        (advice-add name :override #'ignore '((name . joaot/remove-disable-some-cc-things)))
>        (add-hook 'c-mode-common-hook
>                  (lambda ()
>                    (kill-local-variable 'electric-pair-inhibit-predicate)))))

Needless to say, my point of view with respect to the above is somewhat
different.  Succinctly put, the minor modes electric-.... are MINOR
modes, and are quite new.  They were implemented in a way which
interfered with major modes, and I can't see there was any need for
this.  In particular, they interfered with CC Mode features which had
existed for 20 years at the time.

> On the C++/C editing-front, I am eagerly waiting for Treesitter to
> arrive so that is it becomes possible to write a new major mode for c++
> and c from scratch.

I am also looking forward to Treesitter, though I think starting a new
C++ Mode from scratch would not be a good use of time, and would be
needlessly disruptive for current CC Mode users.

> Reusing solid and efficient parsing logic based on language grammars.
> Another more closely available option, is to simply use LSP for
> indentation and fontification.  Though that is almost certainly slower
> and less confortable/portable/etc... Anyway, whatever the solution,
> I'm quite confident that such a mode won't have these characteristics
> that cc-mode has when used with `electric-pair-mode`.

> If you're writing C, and not C++, my also try Stefan Monnier's aptly
> named sm-c-mode, installable via M-x package-install RET sm-c-mode.
> Works fine with electric-pair-mode, but seems to indent very oddly for
> some reason.

I would rather suggest using straight C Mode, which works and works
well.  If there are incompatibilities between CC Mode and
electric-pair-mode, and it seems there are, let's get these fixed.

> Hope this helps.  I'm sorry I can't offer any better solutions.

Could you please express your expert view?  In Jim's opening post he
implies that:
(i) electric-pair-mode should be active inside comments.
(ii) In some circumstances at least, typing a " immediately in front
  of another " causes two "s to be inserted.  Are these circumstances
  spelt out anywhere?
(iii) Typing a " inside a string causes two "s to be inserted, leaving
  point between the two new adjacent strings formed.  This feature is
  not intended to work in C++ raw strings, or other similar multi-line
  strings in other CC Mode modes.

Are these three features all intended in electric-pair-mode?

Thanks!

> João

-- 
Alan Mackenzie (Nuremberg, Germany).




Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#50538; Package emacs. (Thu, 16 Sep 2021 20:50:01 GMT) Full text and rfc822 format available.

Message #47 received at 50538 <at> debbugs.gnu.org (full text, mbox):

From: Alan Mackenzie <acm <at> muc.de>
To: Jim Porter <jporterbugs <at> gmail.com>
Cc: acm <at> muc.de, Eli Zaretskii <eliz <at> gnu.org>, 50538 <at> debbugs.gnu.org
Subject: Re: bug#50538: [PATCH] 28.0.50; electric-pair-mode fails to pair
 double quotes in some cases in CC mode
Date: Thu, 16 Sep 2021 20:49:20 +0000
Hello, Jim.

On Sun, Sep 12, 2021 at 11:05:17 -0700, Jim Porter wrote:
> On 9/11/2021 11:26 PM, Eli Zaretskii wrote:
> >> From: Jim Porter <jporterbugs <at> gmail.com>
> >> Date: Sat, 11 Sep 2021 20:58:47 -0700

> >> There are a few related issues with pairing double quotes in CC mode
> >> while using `electric-pair-mode'. Hopefully the steps to reproduce below
> >> will explain the issues. In all the cases, I'd expect
> >> `electric-pair-mode' to insert a closing quote, but it doesn't.

OK.  Just for context, I'm the maintainer of CC Mode, but I don't use
electric-pair-mode in my day-to-day editing.

> > Your expected results seem to expect Emacs to assume that a new string
> > will be inserted, but is that an assumption that is always true?

> In these cases, I believe that's true (with the default 
> `electric-pair-mode' settings, that is). More broadly, the goal of the 
> patch is to ensure that pairing of double quotes works the same in CC 
> mode as it does in other modes (`ruby-mode', `python-mode', `js-mode', 
> `emacs-lisp-mode', etc), which is why I added `c-mode' to the list of 
> modes to test in `test/lisp/electric-tests.el'.

The goal should be to make all these modes work correctly with respect
to e-p-m, for whatever value of correctly we decide upon.

> That said, there's one potential case I didn't account for (mostly 
> because it wasn't accounted for in the patch for bug#36474): if a user 
> customizes `electric-pair-inhibit-predicate' to inhibit cases like (2) 
> or (3) in my original message, that won't work right in CC modes, since 
> the default value of `electric-pair-inhibit-predicate' (set by the user) 
> won't be called.

> Attached is an updated patch that changes the logic of 
> `c-electric-pair-inhibit-predicate' to either a) inhibit insertion of 
> the closing quote, or b) call the default-value of 
> `electric-pair-inhibit-predicate' to determine what to do. This should 
> give users more consistent behavior when customizing 
> `electric-pair-inhibit-predicate'.

There were two or three minor problems with the patch:

1-/.  CC Mode doesn't use syntax-ppss at all.  This was because way back
when, syntax-ppss was buggy, and even now doesn't do the right thing for
CC Mode in some edge cases (e.g. with the buffer narrowed and point-min
inside a string or comment).  Instead it uses its own internal syntactic
cacheing, largely centred around the function c-semi-pp-to-literal.

2/-  Rather than using get-text-property and friends directly, CC Mode
uses the macros c-get-char-property, etc.  This is (?was) to maintain
compatibility with XEmacs.

3/- (A bit more serious) The patch looks for the last " in the current
line without taking account of any escaped new lines.  There is already
a CC Mode macro which does all the work here, c-point, which can be given
the argument 'eoll for "end of logical line".

Incorporating all these points into the macro (which I admit I haven't
tested) the function would look something like this:

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; Connection with Emacs's electric-pair-mode
(defun c-electric-pair-inhibit-predicate (char)
  "Return t to inhibit the insertion of a second copy of CHAR.

At the time of call, point is just after the newly inserted CHAR.

When CHAR is \" and not within a comment, t will be returned if
the quotes on the current line are already balanced (i.e. if the
last \" is not marked with a string fence syntax-table text
property).  For other cases, the default value of
`electric-pair-inhibit-predicate' is called and its value
returned.

This function is the appropriate value of
`electric-pair-inhibit-predicate' for CC Mode modes, which mark
invalid strings with such a syntax table text property on the
opening \" and the next unescaped end of line."
  (or (and (eq char ?\")
           (not (memq (cadr (c-semi-pp-to-literal (1- (point)))) '(c c++)))
           (not (equal (c-get-char-property (c-point 'eoll) 'c-fl-syn-tab)
                       '(15))))
      (funcall (default-value 'electric-pair-inhibit-predicate) char)))
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

> The tests still pass, although I wasn't able to figure out a good way to 
> add a test for setting `electric-pair-inhibit-predicate' that works with 
> how CC mode overrides it (using `:bindings' in 
> `define-electric-pair-test' didn't work, since the binding is set too 
> late). Hopefully that's ok; if not, I can try and see about making some 
> more extensive changes to the tests to account for this.

> Note however that this solution isn't perfect: it means a user's custom 
> `electric-pair-inhibit-predicate' can only inhibit *more* than CC mode's 
> default behavior, not less. I think that's a reasonable compromise 
> though, and users who want more direct control can set 
> `electric-pair-inhibit-predicate' inside `c-mode-common-hook'. A 
> "perfect" solution here would probably require adding new customization 
> points to `electric-pair-mode' (e.g. a way for major modes to override 
> how the syntax is analyzed), and I'm not sure the added complexity would 
> be worth it, especially since this code is already a bit tricky.

Indeed so.  ;-)

-- 
Alan Mackenzie (Nuremberg, Germany).




Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#50538; Package emacs. (Thu, 16 Sep 2021 20:52:02 GMT) Full text and rfc822 format available.

Message #50 received at 50538 <at> debbugs.gnu.org (full text, mbox):

From: João Távora <joaotavora <at> gmail.com>
To: Alan Mackenzie <acm <at> muc.de>
Cc: Jim Porter <jporterbugs <at> gmail.com>, Lars Ingebrigtsen <larsi <at> gnus.org>,
 Eli Zaretskii <eliz <at> gnu.org>, 50538 <at> debbugs.gnu.org,
 Dmitry Gutov <dgutov <at> yandex.ru>
Subject: Re: bug#50538: [PATCH] 28.0.50; electric-pair-mode fails to pair
 double quotes in some cases in CC mode
Date: Thu, 16 Sep 2021 21:51:13 +0100
Hello Alan,

[I apologize in advance for any spelling mistakes, my spell checker has
taken a vacation in this new operating system.]

Alan Mackenzie <acm <at> muc.de> writes:

> I think it is up to both of us to make this relationship less rocky.

Agreed.  But I'm afraid I don't have much to add the discussion.  I've
made all my points.  And so have you.  I understand, though I
respectfully disagree with your standpoint.  And so do you, I hope.  I
have, in a way, given up on this integration.  electric-pair-mode
doesn't support cc-mode or any more directly derived from it
"officially".  That harmony ended in Emacs 25.x, I believe (might have
been 26.x).  After that, you may have some success with it, or you may
not.

>>        (add-hook 'c-mode-common-hook
>>                  (lambda ()
>>                    (kill-local-variable 'electric-pair-inhibit-predicate)))))
>
> Needless to say, my point of view with respect to the above is somewhat
> different.  Succinctly put, the minor modes electric-.... are MINOR
> modes, and are quite new.
> In particular, they interfered with CC Mode features which had existed
> for 20 years at the time.

My belief is that the term "minor" (which you so emphasize) in the name
"minor-mode" doesn't mean "less important" in any way.  In my view, it
means merely "transversal".  You've often pitched e-p-m and cc-mode
against each other in terms of their relative ages, implying a hierarchy
of importance, deference or prestige.  My belief is that this is
unproductive.  Emacs minor modes, old or new, are not less or more
important.  All other things being equal, they don't deserve less or
more care and attention than Major or "old" modes.  The only criteria to
motivate a change is technical.

> modes, and are quite new.  They were implemented in a way which
> interfered with major modes,

You mention "major modes" in the plural form, but it is fair for me to
point out that only sub-modes of the cc-mode which you command entirely
are in that set.  If I'm forgetting any others, you're welcome to
refresh my memory.

> and I can't see there was any need for this.

I hope you will first notice I didn't adjectify or make any value
judgement on the motivation, necessity or pertinence of your work in CC
mode.  Therefore, I would appreciate if you could return the courtesy.
If you can't personally "see" the need for my work or how it was
performed, that's fine.  I don't demand that you do, though I have gone
to some lengths in the past to inform you of the motivation.  But that
isn't the same as there not being a such a need, or that I worked
spuriously, gratutiously or recklessly or with the intent to interfere
with anything.  In fact, the Git log and users memory records clearly
that when e-p-m was first introduced in Emacs, it worked harmoniously
with cc-mode for a number of years until cc-mode was modified by you to
change that harmony.

Moreover, as far as I gather, electric-pair-mode is a fairly popular
minor mode, so at least some significant group of people adhere to the
same need that I saw.  Even e-p-m's now abandoned predecessor,
"autopair"[1], is still fairly popular today.  Before archiving it some
time ago, I was still seeing healthy download counts.  See also [2] for
some Emacswiki user's (not me) account of the history and relationship
between autopair, e-p-m and other autopairing solutions for Emacs.

Now, to practical matters:

* If CC-mode users agree with you about the absence of a need for such a
  thing as e-p-m, they may simply not turn it on (same goes for
  electric-layout-mode and electric-foo-mode I suppose).  I believe you
  yourself and Eli are in this group.

* If CC-mode users disagree with you, they must find some alternative to
  CC-mode that lets them confortably turn on those modes there.  My two
  self-described hacks are such alternatives.  Not ideal ones, but
  reasonably workable.

As a user, I chose the latter option.  I look forward to a different
Major mode for editing C/CC code.  That is my personal ambition as a
user.

As a developer, changing electric-pair-mode's core principles that work
harmoniously (if not downright flawlessly) for any other major mode not
based on cc-mode is not on the table.

>> On the C++/C editing-front, I am eagerly waiting for Treesitter to
>> arrive so that is it becomes possible to write a new major mode for c++
>> and c from scratch.
>
> I am also looking forward to Treesitter, though I think starting a new
> C++ Mode from scratch would not be a good use of time, and would be
> needlessly disruptive for current CC Mode users.

I certainly didn't want to imply it would be _your_ time.  I believe
what other people do with the time they generously offer us is their
business.  Certainly, I wouldn't dream of implying that the features
you're adding to cc-mode's ever-growing code base are not a good use of
your time.  Furthermore, I think Emacs is fertile in alternative ways to
solve similar problems.  I know others disagree, but I think this is a
quality.

> Could you please express your expert view?  In Jim's opening post he
> implies that:
> (i) electric-pair-mode should be active inside comments.
> (ii) In some circumstances at least, typing a " immediately in front
>   of another " causes two "s to be inserted.  Are these circumstances
>   spelt out anywhere?
> (iii) Typing a " inside a string causes two "s to be inserted, leaving
>   point between the two new adjacent strings formed.  This feature is
>   not intended to work in C++ raw strings, or other similar multi-line
>   strings in other CC Mode modes.
> Are these three features all intended in electric-pair-mode?

(i) Yes.  Much as syntax tables and C-M-f , C-M-b, C-M-u,
    etc. navigation work is comments, so does e-p-m.

(ii) As you well note, it depends on the circumstances.

     The circumstances are well spelt out in the tests.  I can name one
     here.

     If you have the buffer with contents

       "hello"

     And you type a double quote at buffer ends, you get

       "hello"""

     This example was taken from one of the tests of the group
     'pair-some-quotes-skip-others', found in electric-tests.el, as I
     think you know.

     As I think you also know, the principle of
     'electric-pair-preserve-balance' stipulates that
     'electric-pair-mode' will only make 'self-insert-command' do
     "suprising electric behaviour" -- insert two delimiters or skip one
     -- if that action helps keep or improve the balance of said
     delimiter in the buffer.

     Therefore, if you find a circumstance where e-p-m inserts two
     quotes and that happens to _worsen_ the balancing of the buffer
     (i.e. creates an unterminated string somewhere where previously
     there wasn't), then you have found a bug in e-p-m.  In that case,
     please describe it clearly as a bug report.

     However, and very importantly, you must find this circumstance in
     any major mode _other_ than cc-mode.  Because -- as I've tried to
     make clear -- "all bets are off in cc-mode", so to speak.  So if
     you are finding this misbehaviour in e-p-m _in conjunction with
     cc-mode_, I wouldn't bother reporting it.  We've established that
     the solution that I would propose to you is very likely not going
     to appeal to you.

(iii) Yes.  That is the way that e-p-m always worked.  By behaving so,
      the balancing state of the buffer is preseved.

      Some packages, (like smartparens [3], I believe) will insert a
      single quote preceded by an escape character.  That action also
      keeps the balance.

      Perhaps e-p-m could accomodate this behaviour from smartparens.
      If some users would like it, I think it can be easily done.

Best regards,
João

[1]: https://github.com/joaotavora/autopair/
[2]: https://www.emacswiki.org/emacs/AutoPairs
[3]: https://github.com/Fuco1/smartparens




Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#50538; Package emacs. (Thu, 16 Sep 2021 21:37:01 GMT) Full text and rfc822 format available.

Message #53 received at 50538 <at> debbugs.gnu.org (full text, mbox):

From: Jim Porter <jporterbugs <at> gmail.com>
To: Alan Mackenzie <acm <at> muc.de>
Cc: 50538 <at> debbugs.gnu.org
Subject: Re: bug#50538: [PATCH] 28.0.50; electric-pair-mode fails to pair
 double quotes in some cases in CC mode
Date: Thu, 16 Sep 2021 14:36:06 -0700
[Message part 1 (text/plain, inline)]
On 9/16/2021 1:49 PM, Alan Mackenzie wrote:
> There were two or three minor problems with the patch:
> 
> 1-/.  CC Mode doesn't use syntax-ppss at all.  This was because way back
> when, syntax-ppss was buggy, and even now doesn't do the right thing for
> CC Mode in some edge cases (e.g. with the buffer narrowed and point-min
> inside a string or comment).  Instead it uses its own internal syntactic
> cacheing, largely centred around the function c-semi-pp-to-literal.
> 
> 2/-  Rather than using get-text-property and friends directly, CC Mode
> uses the macros c-get-char-property, etc.  This is (?was) to maintain
> compatibility with XEmacs.
> 
> 3/- (A bit more serious) The patch looks for the last " in the current
> line without taking account of any escaped new lines.  There is already
> a CC Mode macro which does all the work here, c-point, which can be given
> the argument 'eoll for "end of logical line".

Thanks, I've incorporated all these changes into the attached patch. The 
only difference between my patch and the version you provided was to 
keep the `(search-backward "\"")' portion from my patch, since the code 
needs to find the last double-quote, not the end of line.

As an aside, it's probably worth explaining why my patch searches for 
the last double-quote in the first place. As far as I understand CC 
Mode, when there's an unterminated double-quote on a line, both the 
quote and the newline have a string fence property applied to them. This 
means we could check the newline for that property, *but* there's no 
guarantee a newline actually exists: `(c-point 'eoll)' could actually 
point to the end of the buffer. To get around that, we search backwards 
for the last double-quote of the (logical) line, since that's guaranteed 
to exist.

If we wanted to, we could avoid searching backwards for the last 
double-quote when a newline exists, but I'm not sure the gain in 
performance (likely very small) is worth the extra code complexity.
[0001-Improve-behavior-of-electric-pair-mode-in-cc-mode.patch (text/plain, attachment)]

Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#50538; Package emacs. (Fri, 17 Sep 2021 17:09:02 GMT) Full text and rfc822 format available.

Message #56 received at 50538 <at> debbugs.gnu.org (full text, mbox):

From: Alan Mackenzie <acm <at> muc.de>
To: Jim Porter <jporterbugs <at> gmail.com>
Cc: 50538 <at> debbugs.gnu.org
Subject: Re: bug#50538: [PATCH] 28.0.50; electric-pair-mode fails to pair
 double quotes in some cases in CC mode
Date: Fri, 17 Sep 2021 17:08:33 +0000
Hello, Jim.

On Thu, Sep 16, 2021 at 14:36:06 -0700, Jim Porter wrote:
> On 9/16/2021 1:49 PM, Alan Mackenzie wrote:
> > There were two or three minor problems with the patch:

> > 1-/.  CC Mode doesn't use syntax-ppss at all.  This was because way back
> > when, syntax-ppss was buggy, and even now doesn't do the right thing for
> > CC Mode in some edge cases (e.g. with the buffer narrowed and point-min
> > inside a string or comment).  Instead it uses its own internal syntactic
> > cacheing, largely centred around the function c-semi-pp-to-literal.

> > 2/-  Rather than using get-text-property and friends directly, CC Mode
> > uses the macros c-get-char-property, etc.  This is (?was) to maintain
> > compatibility with XEmacs.

> > 3/- (A bit more serious) The patch looks for the last " in the current
> > line without taking account of any escaped new lines.  There is already
> > a CC Mode macro which does all the work here, c-point, which can be given
> > the argument 'eoll for "end of logical line".

> Thanks, I've incorporated all these changes into the attached patch. The 
> only difference between my patch and the version you provided was to 
> keep the `(search-backward "\"")' portion from my patch, since the code 
> needs to find the last double-quote, not the end of line.

Duh!  Sorry about that, I clean forgot about it.  I did say that I
hadn't tested it, though. ;-)

> As an aside, it's probably worth explaining why my patch searches for 
> the last double-quote in the first place. As far as I understand CC 
> Mode, when there's an unterminated double-quote on a line, both the 
> quote and the newline have a string fence property applied to them.

Yes.

> This means we could check the newline for that property, *but* there's
> no guarantee a newline actually exists: `(c-point 'eoll)' could
> actually point to the end of the buffer. To get around that, we search
> backwards for the last double-quote of the (logical) line, since
> that's guaranteed to exist.

Yes.  This is a very important case, the one that occurs when somebody's
typing a new file, or at the end of an existing one.

> If we wanted to, we could avoid searching backwards for the last 
> double-quote when a newline exists, but I'm not sure the gain in 
> performance (likely very small) is worth the extra code complexity.

I'm fairly sure it wouldn't be.

[ Patch snipped but read. ]

-- 
Alan Mackenzie (Nuremberg, Germany).




Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#50538; Package emacs. (Fri, 17 Sep 2021 18:14:01 GMT) Full text and rfc822 format available.

Message #59 received at 50538 <at> debbugs.gnu.org (full text, mbox):

From: Alan Mackenzie <acm <at> muc.de>
To: João Távora <joaotavora <at> gmail.com>
Cc: Jim Porter <jporterbugs <at> gmail.com>, 50538 <at> debbugs.gnu.org,
 Dmitry Gutov <dgutov <at> yandex.ru>, acm <at> muc.de,
 Lars Ingebrigtsen <larsi <at> gnus.org>, Eli Zaretskii <eliz <at> gnu.org>
Subject: Re: bug#50538: [PATCH] 28.0.50; electric-pair-mode fails to pair
 double quotes in some cases in CC mode
Date: Fri, 17 Sep 2021 18:12:57 +0000
Hello, João.

On Thu, Sep 16, 2021 at 21:51:13 +0100, João Távora wrote:
> Hello Alan,

> [I apologize in advance for any spelling mistakes, my spell checker has
> taken a vacation in this new operating system.]

> Alan Mackenzie <acm <at> muc.de> writes:

> > I think it is up to both of us to make this relationship less rocky.

> Agreed.  But I'm afraid I don't have much to add the discussion.  I've
> made all my points.  And so have you.

I was thinking more along the lines of coding, not discussion.

> I understand, though I respectfully disagree with your standpoint.
> And so do you, I hope.  I have, in a way, given up on this
> integration.  electric-pair-mode doesn't support cc-mode or any more
> directly derived from it "officially".  That harmony ended in Emacs
> 25.x, I believe (might have been 26.x).  After that, you may have some
> success with it, or you may not.

Why such a negative attitude?  CC Mode is an important package, and so
is electric-pair-mode.  There doesn't seem to be any intrinsic reason
why they shouldn't work together better.

> >>        (add-hook 'c-mode-common-hook
> >>                  (lambda ()
> >>                    (kill-local-variable 'electric-pair-inhibit-predicate)))))

> > Needless to say, my point of view with respect to the above is somewhat
> > different.  Succinctly put, the minor modes electric-.... are MINOR
> > modes, and are quite new.
> > In particular, they interfered with CC Mode features which had existed
> > for 20 years at the time.

> My belief is that the term "minor" (which you so emphasize) in the name
> "minor-mode" doesn't mean "less important" in any way.

No, that's not how I meant it.  It's more that the layout of the text on
the screen, and the process of changing it ARE the major mode.  Any
interference with the major mode in its primary role is a buggy
situation needing fixing.

> In my view, it means merely "transversal".  You've often pitched e-p-m
> and cc-mode against each other in terms of their relative ages,
> implying a hierarchy of importance, deference or prestige.

More a regret that when the electric-... modes were developed, they paid
no attention to CC Mode, even when the feature originated there.  This
was bound to lead to conflict sooner or later, and that is where we are
at now.

> My belief is that this is unproductive.  Emacs minor modes, old or
> new, are not less or more important.  All other things being equal,
> they don't deserve less or more care and attention than Major or "old"
> modes.  The only criteria to motivate a change is technical.

Right now, CC Mode binds post-self-insert-hook to nil when calling
self-insert-function, so as to get it functioning predictably, then
attempts to compensate later by calling e.g.
electric-pair-post-self-insert-function directly.  I think you'll agree
with me this is suboptimal.  I can't see any way of getting around it
without amendments to electric-pair-mode.

> > modes, and are quite new.  They were implemented in a way which
> > interfered with major modes,

[ .... ]

> > and I can't see there was any need for this.

> I hope you will first notice I didn't adjectify or make any value
> judgement on the motivation, necessity or pertinence of your work in CC
> mode.

You seem to me to be doing exactly this by declining to work to improve
the interface between CC Mode and e-p-m.

> Therefore, I would appreciate if you could return the courtesy.  If
> you can't personally "see" the need for my work or how it was
> performed, that's fine.

I can.  I can also see problems with it, and regret your very negative
attitude towards fixing problems in your own area of speciality.

CC Mode has existed in one form or another for around 40 years.  I think
it would be reasonable for a new minor mode to take due account of it
when being developed.  As far as I can see, this didn't happen with
electric-pair-mode to a sufficient degree.

> I don't demand that you do, though I have gone to some lengths in the
> past to inform you of the motivation.  But that isn't the same as
> there not being a such a need, or that I worked spuriously,
> gratutiously or recklessly or with the intent to interfere with
> anything.

I am not implying such, and don't believe I ever have done.

> In fact, the Git log and users memory records clearly that when e-p-m
> was first introduced in Emacs, it worked harmoniously with cc-mode for
> a number of years until cc-mode was modified by you to change that
> harmony.

The use of post-self-insert-hook to make buffer changes has never worked
well with CC Mode.  It cannot work in any major mode which uses
self-insert-command as part of a mode command.

You seem to be implying that my motivation in developing CC Mode was to
damage the workings of e-p-m.  I think that's somewhat uncalled for.  CC
Mode is under continual development, and has traditionally been at the
forefront of new techniques.  Electric indentation, subword mode, and
the correct fontification of unterminated strings are just three
examples of this.

When you drew attention to problems, I put considerable effort into
fixing and ameliorating these in CC Mode.

> Moreover, as far as I gather, electric-pair-mode is a fairly popular
> minor mode, so at least some significant group of people adhere to the
> same need that I saw.  Even e-p-m's now abandoned predecessor,
> "autopair"[1], is still fairly popular today.  Before archiving it some
> time ago, I was still seeing healthy download counts.  See also [2] for
> some Emacswiki user's (not me) account of the history and relationship
> between autopair, e-p-m and other autopairing solutions for Emacs.

Yes, CC Mode and e-p-m are both popular and important.  They don't work
well enough together.

> Now, to practical matters:

> * If CC-mode users agree with you about the absence of a need for such a
>   thing as e-p-m, they may simply not turn it on (same goes for
>   electric-layout-mode and electric-foo-mode I suppose).  I believe you
>   yourself and Eli are in this group.

I'm not in such a group.  I accept the need for e-p-m.  I just don't
want to use it myself.

> * If CC-mode users disagree with you, they must find some alternative to
>   CC-mode that lets them confortably turn on those modes there.  My two
>   self-described hacks are such alternatives.  Not ideal ones, but
>   reasonably workable.

Why don't you put some work in to make e-p-m work better with CC Mode?
Maybe I'm misremembering here, but when the problems raised themselves I
don't recall you making, or being prepared to make any amendments to
electric-pair-mode.  Why not?

> As a user, I chose the latter option.  I look forward to a different
> Major mode for editing C/CC code.  That is my personal ambition as a
> user.

You might have a long wait.  And people who run from things because they
don't like them often don't like what they find instead, either.

Are you saying that your aim is to _prevent_ e-p-m working well with CC
Mode?

> As a developer, changing electric-pair-mode's core principles that work
> harmoniously (if not downright flawlessly) for any other major mode not
> based on cc-mode is not on the table.

That's a bit callous, isn't it?  CC Mode is a highly important part of
Emacs, and you're deliberately not catering to it?  Why?

Why not amend e-p-m so that it will work harmoniously with _any_ major
mode, not just the simple ones?  Where's the difficulty?

[ .... ]

[ Details of particulars of electric-pair-mode operation read with
thanks. ]

> Best regards,
> João

-- 
Alan Mackenzie (Nuremberg, Germany).




Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#50538; Package emacs. (Thu, 23 Sep 2021 02:02:01 GMT) Full text and rfc822 format available.

Message #62 received at 50538 <at> debbugs.gnu.org (full text, mbox):

From: Jim Porter <jporterbugs <at> gmail.com>
To: Alan Mackenzie <acm <at> muc.de>
Cc: 50538 <at> debbugs.gnu.org
Subject: Re: bug#50538: [PATCH v3] 28.0.50; electric-pair-mode fails to pair
 double quotes in some cases in CC mode
Date: Wed, 22 Sep 2021 19:01:11 -0700
[Message part 1 (text/plain, inline)]
Ok, I've attached an updated patch that should apply cleanly on top of 
the patches for bug#49518. The tests still pass locally for me. If 
there's anything else that needs fixed/adjusted, just let me know.
[0001-Improve-behavior-of-electric-pair-mode-in-cc-mode.patch (text/plain, attachment)]

Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#50538; Package emacs. (Sun, 26 Sep 2021 20:59:01 GMT) Full text and rfc822 format available.

Message #65 received at 50538 <at> debbugs.gnu.org (full text, mbox):

From: Alan Mackenzie <acm <at> muc.de>
To: Jim Porter <jporterbugs <at> gmail.com>
Cc: 50538 <at> debbugs.gnu.org
Subject: Re: bug#50538: [PATCH v3] 28.0.50; electric-pair-mode fails to pair
 double quotes in some cases in CC mode
Date: Sun, 26 Sep 2021 20:58:36 +0000
Hello, Jim.

There's one thing I'm a bit uncertain about in the patch for cc-mode.el.

On Wed, Sep 22, 2021 at 19:01:11 -0700, Jim Porter wrote:
> Ok, I've attached an updated patch that should apply cleanly on top of 
> the patches for bug#49518. The tests still pass locally for me. If 
> there's anything else that needs fixed/adjusted, just let me know.

[ .... ]

> diff --git a/lisp/progmodes/cc-mode.el b/lisp/progmodes/cc-mode.el
> index 8b30241449..80137590c7 100644
> --- a/lisp/progmodes/cc-mode.el
> +++ b/lisp/progmodes/cc-mode.el
> @@ -2549,18 +2549,26 @@ c-electric-pair-inhibit-predicate
 
>  At the time of call, point is just after the newly inserted CHAR.
 
> -When CHAR is \", t will be returned unless the \" is marked with
> -a string fence syntax-table text property.  For other characters,
> -the default value of `electric-pair-inhibit-predicate' is called
> -and its value returned.
> +When CHAR is \" and not within a comment, t will be returned if
> +the quotes on the current line are already balanced (i.e. if the
> +last \" is not marked with a string fence syntax-table text
> +property).  For other cases, the default value of
> +`electric-pair-inhibit-predicate' is called and its value
> +returned.
 
>  This function is the appropriate value of
>  `electric-pair-inhibit-predicate' for CC Mode modes, which mark
>  invalid strings with such a syntax table text property on the
>  opening \" and the next unescaped end of line."
> -  (if (eq char ?\")
> -      (not (equal (get-text-property (1- (point)) 'c-fl-syn-tab) '(15)))
> -    (funcall (default-value 'electric-pair-inhibit-predicate) char)))
> +  (or (and (eq char ?\")
> +	   (not (memq (cadr (c-semi-pp-to-literal (1- (point)))) '(c c++)))
> +	   (let ((last-quote (save-match-data
> +			       (save-excursion
> +				 (goto-char (c-point 'eoll))
> +				 (search-backward "\"")))))
> +	     (not (equal (c-get-char-property last-quote 'c-fl-syn-tab)
> +			 '(15)))))
> +      (funcall (default-value 'electric-pair-inhibit-predicate) char)))
 
In the line starting (or (and (eq char ?\"), don't we still need an `if'
form?  I think that otherwise, if any of the sub-forms of the `and'
return nil, we will call (default-value
'electric-pair-inhibit-predicate), which surely isn't what we want.  If
we have a ", we want the CC Mode function to do all the work, only
delegating to the standard function when we don't have a ".

Or have I missed something?

[ .... ]

-- 
Alan Mackenzie (Nuremberg, Germany).




Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#50538; Package emacs. (Tue, 28 Sep 2021 04:58:01 GMT) Full text and rfc822 format available.

Message #68 received at 50538 <at> debbugs.gnu.org (full text, mbox):

From: Jim Porter <jporterbugs <at> gmail.com>
To: Alan Mackenzie <acm <at> muc.de>
Cc: 50538 <at> debbugs.gnu.org
Subject: Re: bug#50538: [PATCH v4] 28.0.50; electric-pair-mode fails to pair
 double quotes in some cases in CC mode
Date: Mon, 27 Sep 2021 21:57:07 -0700
[Message part 1 (text/plain, inline)]
On 9/26/2021 1:58 PM, Alan Mackenzie wrote:
> 
> There's one thing I'm a bit uncertain about in the patch for cc-mode.el.
> 
> On Wed, Sep 22, 2021 at 19:01:11 -0700, Jim Porter wrote:
[snip]
>> -  (if (eq char ?\")
>> -      (not (equal (get-text-property (1- (point)) 'c-fl-syn-tab) '(15)))
>> -    (funcall (default-value 'electric-pair-inhibit-predicate) char)))
>> +  (or (and (eq char ?\")
>> +	   (not (memq (cadr (c-semi-pp-to-literal (1- (point)))) '(c c++)))
>> +	   (let ((last-quote (save-match-data
>> +			       (save-excursion
>> +				 (goto-char (c-point 'eoll))
>> +				 (search-backward "\"")))))
>> +	     (not (equal (c-get-char-property last-quote 'c-fl-syn-tab)
>> +			 '(15)))))
>> +      (funcall (default-value 'electric-pair-inhibit-predicate) char)))
>   
> In the line starting (or (and (eq char ?\"), don't we still need an `if'
> form?  I think that otherwise, if any of the sub-forms of the `and'
> return nil, we will call (default-value
> 'electric-pair-inhibit-predicate), which surely isn't what we want.  If
> we have a ", we want the CC Mode function to do all the work, only
> delegating to the standard function when we don't have a ".
> 
> Or have I missed something?

I don't have a strong opinion on this either way, so here's a patch that 
uses an `if' form as you suggest. However, I introduced the `or' form 
in response to Eli's concern[1]:

On 9/11/2021 11:26 PM, Eli Zaretskii wrote:
> Your expected results seem to expect Emacs to assume that a new
> string will be inserted, but is that an assumption that is always
> true?  It could be that the user wants to modify the existing string
> instead, in which case your suggested patches will require the user
> to delete more quotes than previously.

I discussed the pros and cons in my followup[2]:

> Note however that this solution isn't perfect: it means a user's
> custom `electric-pair-inhibit-predicate' can only inhibit *more*
> than CC mode's default behavior, not less. I think that's a
> reasonable compromise though, and users who want more direct control
> can [override `c-electric-pair-inhibit-predicate'].[3]

Personally, I'm fine with letting CC Mode do all the work here, and 
requiring users to advise this function if they want a different 
behavior. It's probably easier to be sure that things don't break by 
using the `if' form patch, though I think the previous `or' form patch 
should be pretty robust too.

[1] https://lists.gnu.org/archive/html/bug-gnu-emacs/2021-09/msg00976.html
[2] https://lists.gnu.org/archive/html/bug-gnu-emacs/2021-09/msg01014.html
[3] My explanation in the original message was incorrect, so I've fixed 
it here.
[0001-Improve-behavior-of-electric-pair-mode-in-cc-mode.patch (text/plain, attachment)]

Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#50538; Package emacs. (Sun, 03 Oct 2021 17:59:02 GMT) Full text and rfc822 format available.

Message #71 received at 50538 <at> debbugs.gnu.org (full text, mbox):

From: Jim Porter <jporterbugs <at> gmail.com>
To: Alan Mackenzie <acm <at> muc.de>
Cc: 50538 <at> debbugs.gnu.org
Subject: Re: bug#50538: [PATCH v5] 28.0.50; electric-pair-mode fails to pair
 double quotes in some cases in CC mode
Date: Sun, 3 Oct 2021 10:58:15 -0700
[Message part 1 (text/plain, inline)]
On 9/27/2021 9:57 PM, Jim Porter wrote:
> I don't have a strong opinion on this either way, so here's a patch that 
> uses an `if' form as you suggest.

Oops, I was looking over this patch again and realized that I simply 
re-attached the old patch. Sorry about that. Here's the version that 
*really* uses the `if' form. Like I said in my previous message, I don't 
have a strong opinion on whether to use the `if' form or the `or' form; 
either works fine for me.
[0001-Improve-behavior-of-electric-pair-mode-in-cc-mode.patch (text/plain, attachment)]

Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#50538; Package emacs. (Sat, 06 Nov 2021 00:23:01 GMT) Full text and rfc822 format available.

Message #74 received at 50538 <at> debbugs.gnu.org (full text, mbox):

From: Lars Ingebrigtsen <larsi <at> gnus.org>
To: Jim Porter <jporterbugs <at> gmail.com>
Cc: Alan Mackenzie <acm <at> muc.de>, 50538 <at> debbugs.gnu.org
Subject: Re: bug#50538: [PATCH] 28.0.50; electric-pair-mode fails to pair
 double quotes in some cases in CC mode
Date: Sat, 06 Nov 2021 01:22:26 +0100
Jim Porter <jporterbugs <at> gmail.com> writes:

> Oops, I was looking over this patch again and realized that I simply
> re-attached the old patch. Sorry about that. Here's the version that
> *really* uses the `if' form. Like I said in my previous message, I
> don't have a strong opinion on whether to use the `if' form or the
> `or' form; either works fine for me.

Skimming this thread, it seems that everybody was OK with this patch,
but it wasn't applied.  So I've now done so (but in Emacs 29).

-- 
(domestic pets only, the antidote for overdose, milk.)
   bloggy blog: http://lars.ingebrigtsen.no




bug marked as fixed in version 29.1, send any further explanations to 50538 <at> debbugs.gnu.org and Jim Porter <jporterbugs <at> gmail.com> Request was from Lars Ingebrigtsen <larsi <at> gnus.org> to control <at> debbugs.gnu.org. (Sat, 06 Nov 2021 00:23:02 GMT) Full text and rfc822 format available.

bug archived. Request was from Debbugs Internal Request <help-debbugs <at> gnu.org> to internal_control <at> debbugs.gnu.org. (Sat, 04 Dec 2021 12:24:07 GMT) Full text and rfc822 format available.

This bug report was last modified 2 years and 144 days ago.

Previous Next


GNU bug tracking system
Copyright (C) 1999 Darren O. Benham, 1997,2003 nCipher Corporation Ltd, 1994-97 Ian Jackson.