Subject: bug#78021: 30.1; Unclear sentence in (emacs)Matching

From: Stephen Berman <[email-masked]>
Date: Fri, 25 Apr 2025 15:48:54 +0200

reopen 78021
thanks

(In light of the posts related to this bug on emacs-devel, included
below for convenience, I've reopened this bug and am following up here.)

On Thu, 24 Apr 2025 18:30:37 +0300 Eli Zaretskii <[email-masked]> wrote:

>> From: Stephen Berman <[email-masked]>
>> Cc: Eli Zaretskii <[email-masked]>
>> Date: Thu, 24 Apr 2025 16:15:16 +0200
>> 
>> On Thu, 24 Apr 2025 05:08:40 -0400 (EDT) Eli Zaretskii <[email-masked]> wrote:
>> 
>> > branch: emacs-30
>> > commit a975232c0fd7bbcce39f904518bd068a879ea4f0
>> > Author: Eli Zaretskii <[email-masked]>
>> > Commit: Eli Zaretskii <[email-masked]>
>> >
>> >     ; * doc/emacs/programs.texi (Matching): Fix wording (bug#78021).
>> > ---
>> >  doc/emacs/programs.texi | 25 ++++++++++++++-----------
>> >  1 file changed, 14 insertions(+), 11 deletions(-)
>> >
>> > diff --git a/doc/emacs/programs.texi b/doc/emacs/programs.texi
>> > index e155092676b..820a772104e 100644
>> > --- a/doc/emacs/programs.texi
>> > +++ b/doc/emacs/programs.texi
>> > @@ -960,11 +960,11 @@ argument specifies the number of levels to go down.
>> >  
>> >  @node Matching
>> >  @subsection Matching Parentheses
>> > -@cindex matching parentheses
>> > +@cindex matching, parentheses and other paired delimiters
>> >  @cindex parentheses, displaying matches
>> >  
>> > -  Emacs has a number of @dfn{parenthesis matching} features, which
>> > -make it easy to see how and whether parentheses (or other delimiters)
>> > +  Emacs has a number of @dfn{parenthesis matching} features, which make
>> > +it easy to see how and whether parentheses (or other paired delimiters)
>> >  match up.
>> >  
>> >    Whenever you type a self-inserting character that is a closing
>> > @@ -1065,14 +1065,17 @@ nonblank line.
>> >  @findex electric-pair-mode
>> >    Electric Pair mode, a global minor mode, provides a way to easily
>> >  insert matching delimiters: parentheses, braces, brackets, etc.
>> > -Whenever you insert an opening delimiter, the matching closing
>> > -delimiter is automatically inserted as well, leaving point between the
>> > -two.  Conversely, when you insert a closing delimiter over an existing
>> > -one, no insertion takes places, and that position is simply skipped
>> > -over.  If the region is active (@pxref{Mark}), insertion of a
>> > -delimiter operates on the region: the characters in the region are
>> > -enclosed in a pair of matching delimiters, leaving point after the
>> > -delimiter you typed.
>> > +Whenever you insert an opening delimiter, the matching closing delimiter
>> > +is automatically inserted as well, leaving point between the two.
>> > +However, if you insert a closing delimiter where one already exists
>> > +(probably a mistake, since typing the opening delimiter inserted the
>> > +closing one for you), Emacs simply moves point to after the closing
>> > +delimiter, skipping the insertion.  If the region is active
>> > +(@pxref{Mark}), insertion of a delimiter operates on the region: the
>> > +characters in the region are enclosed in a pair of matching delimiters,
>> > +leaving point after the delimiter you typed.  If you provide a prefix
>> > +argument when inserting a delimiter, the numeric value of that prefix
>> > +argument specifies the number of pairs to insert.
>> >  
>> >  These variables control additional features of Electric Pair mode:
>>   
>> I think the documentation of Electric Pair mode (both before and after
>> the change), is incomplete or inaccurate in several respects:
>> 
>> - What counts as paired delimiters can vary with the mode (e.g.,
>>   emacs-lisp-mode includes ` and ', and latex-mode includes $).
>> 
>> - Whether typing an opening delimiter automatically inserts the matching
>>   closing delimiter depends both on the presence or absence of a
>>   following unmatched closing delimiter as well as on the value of
>>   electric-pair-preserve-balance.
>> 
>> - Unless the region is active (see below), typing a closing delimiter
>>   anywere (not just where a closing delimiter already is) does not
>>   insert the matching opening delimiter but is just like typing a
>>   non-delimiter self-inserting character.
>> 
>> - With a numeric prefix argument N, typing an opening delimiter normally
>>   (but see below) inserts N nested (not sequential) paired delimiters
>>   and leaves point directly after the innermost opening delimiter, while
>>   typing a closing delimiter inserts N nested paired delimiters only
>>   with an active region, leaving point directly after the outermost
>>   closing delimiter.  If there is an unmatched closing delimiter, then
>>   typing the opening delimiter with a numeric prefix argument inserts
>>   just N copies of the opening delimiter, not N nested paired delimiters
>>   (even if electric-pair-preserve-balance is non-nil, which might be
>>   considered a bug).
>> 
>> - The user option electric-pair-preserve-balance only affects the
>>   behavior of opening delimiters (I haven't yet tested the other
>>   Electric Pair mode user options).
>> 
>> Should the documentation be amended accordingly?
>
> I think so, but please try to be as concise as possible, and secondary
> details could be omitted entirely.  I wouldn't want to have this node
> bloated too much because of this minor feature.
>
> For example, your first point could be addressed by adding just this:
>
>   What counts as paired delimiters depends on the major mode.
>
> Thanks.

I've attached a patch for emacs-30 and have several remarks concerning
it.  First, regarding my first point above, since the parent node
already says "The major mode controls which delimiters are significant
[...]", I now think there is no need to reiterate it here.

Second, in the first paragraphs of the patch I've tried to describe the
default behavior concisely and completely; however, the sentence about
the numeric prefix argument, which evidently comes from the
documentation in master, is not suitable for emacs-30: the use of the
prefix argument was added (together with its documentation) as a result
of bug#72437 only to master.  If my doc changes for emacs-30 are
acceptable, they should be added to master as well, but not merged,
because of the prefix argument doc.  But in addition, in testing the use
of the prefix argument I've encountered what seems like buggy behavior,
one instance of which I pointed out above; I'm still investigating this
and plan to file a bug report about it.  A doc patch for master should
await the outcome of that.

Third, concerning the user options, I think it's better not to use the
phrase "when non-‘nil’", which is in all cases the default value: for
electric-pair-preserve-balance, the behavior with that value was already
described, so it's better (and more parsimonious) to focus on the
behavior with the non-default value here; and for the other three
options a user-defined function is also allowed as value, which of
course is non-nil, but I don't think documenting this value is
appropriate for the Emacs manual, so I think it's better just to say "by
default".

Finally, in the description of electric-pair-preserve-balance the
penultimate parenthetical sentence seems like a rather shamefaced
admission of a bug.  Indeed, it does strike me as a bug, and I have a
simple fix that makes setting this option to nil have the same effect
with an active region as without, according to my initial testing.  I
will file a bug report and include the patch.  If the maintainers agree
that this is a bug and that the patch fixes it, then the parenthetical
sentence can be removed.  But whether that goes only for master or also
for emacs-30 is also for the maintainers to decide.

Steve Berman
diff --git a/doc/emacs/programs.texi b/doc/emacs/programs.texi
index 820a772104e..ff8cf904915 100644
--- a/doc/emacs/programs.texi
+++ b/doc/emacs/programs.texi
@@ -1063,52 +1063,65 @@ Matching
 @cindex Electric Pair mode
 @cindex inserting matching parentheses
 @findex electric-pair-mode
-  Electric Pair mode, a global minor mode, provides a way to easily
-insert matching delimiters: parentheses, braces, brackets, etc.
-Whenever you insert an opening delimiter, the matching closing delimiter
-is automatically inserted as well, leaving point between the two.
-However, if you insert a closing delimiter where one already exists
-(probably a mistake, since typing the opening delimiter inserted the
-closing one for you), Emacs simply moves point to after the closing
-delimiter, skipping the insertion.  If the region is active
-(@pxref{Mark}), insertion of a delimiter operates on the region: the
-characters in the region are enclosed in a pair of matching delimiters,
-leaving point after the delimiter you typed.  If you provide a prefix
-argument when inserting a delimiter, the numeric value of that prefix
-argument specifies the number of pairs to insert.
-
-These variables control additional features of Electric Pair mode:
+  Electric Pair mode is a minor mode that provides a way to easily
+insert matching delimiters: parentheses, braces, brackets, quotes, etc.
+To toggle Electric Pair mode globally, type @kbd{M-x
+electric-pair-mode}.  To toggle it only in the current buffer, type
+@kbd{M-x electric-pair-local-mode}.
+
+  When this mode is enabled and you type an opening delimiter, then by
+default the matching closing delimiter is normally automatically
+inserted as well, leaving point between the two.  However, if there is
+an unmatched closing delimiter later in the buffer, then by default
+typing an opening delimiter inserts just that character, in order to
+balance opening and closing delimiters.
+
+  This makes it unnecessary to type a closing delimiter, and doing so
+normally simply inserts that character.  However, if you type a closing
+delimiter at a buffer position between matching delimiters of the same
+type with only white space between the delimiters, then by default Emacs
+simply moves point to after the closing delimiter and does not insert
+another one.
+
+  If the region is active (@pxref{Mark}), inserting either an opening or
+a closing delimiter encloses the characters in the region within the
+resulting pair of matching delimiters, leaving point after the delimiter
+you typed.
+
+  There are several user options for changing the default behavior of
+Electric Pair mode:
 
 @itemize @bullet
 @item
 @vindex electric-pair-preserve-balance
-@code{electric-pair-preserve-balance}, when non-@code{nil}, makes the
-default pairing logic balance out the number of opening and closing
-delimiters.
+@code{electric-pair-preserve-balance}, when set to @code{nil}, makes
+typing an opening delimiter insert only that character, thus overriding
+the default pairing logic of balancing the number of opening and closing
+delimiters.  (However, if the region is active, setting this option to
+@code{nil} has no effect.)  The default is non-@code{nil} (on).
 
 @item
 @vindex electric-pair-delete-adjacent-pairs
-@code{electric-pair-delete-adjacent-pairs}, when non-@code{nil}, makes
-backspacing between two adjacent delimiters also automatically delete
-the closing delimiter.
+@code{electric-pair-delete-adjacent-pairs}, by default, makes
+backspacing between two adjacent delimiters delete not only the opening
+delimiter but also the closing delimiter.
 
 @item
 @vindex electric-pair-open-newline-between-pairs
-@code{electric-pair-open-newline-between-pairs}, when non-@code{nil},
-makes inserting a newline between two adjacent pairs also
-automatically open an extra newline after point.
+@code{electric-pair-open-newline-between-pairs}, by default, makes
+inserting a newline between two adjacent pairs also automatically open
+an extra newline after point.
 
 @item
 @vindex electric-pair-skip-whitespace
-@code{electric-pair-skip-whitespace}, when non-@code{nil}, causes the minor
-mode to skip whitespace forward before deciding whether to skip over
-the closing delimiter.
+@code{electric-pair-skip-whitespace}, by default, makes typing a closing
+delimiter between matching delimiters of the same type behave as
+described above.  You can set this option to additionally delete any
+white space skipped over.  You can also set it not to skip over the
+following closing delimiter but simply insert a closing delimiter at
+point (thus making the following delimiter unbalanced).
 @end itemize
 
-To toggle Electric Pair mode, type @kbd{M-x electric-pair-mode}.  To
-toggle the mode in a single buffer, use @kbd{M-x
-electric-pair-local-mode}.
-
 @node Comments
 @section Manipulating Comments
 @cindex comments