Subject: bug#79047: Add some multi-character pairs to some major modes.

From: Alan Mackenzie <[email-masked]>
Date: Fri, 25 Jul 2025 13:39:07 +0000

Hello, Eli.

On Fri, Jul 25, 2025 at 15:02:12 +0300, Eli Zaretskii wrote:
> > Date: Fri, 25 Jul 2025 11:42:37 +0000
> > Cc: [email-masked], [email-masked], [email-masked],
> >   [email-masked], [email-masked]
> > From: Alan Mackenzie <[email-masked]>

> > > > self-insert-command, called from Lisp, is broken.  There is no usable
> > > > definition of its functionality.

> > > What's wrong with its doc string as that definition?

> > It's inaccurate and misleading.

> > We have:

> >     Insert the character you type.
> >     Whichever character C you type to run this command is inserted.
> >     [Plus all the bits about the numeric prefix, abbreviations, etc.]

> > More accurate would be:

> >     Maybe insert the character you type (depending on
> >     post-self-insert-hook).
> >     Insert or delete further characters as specified by
> >     post-self-insert-hook.
> >     Leave point at the position determined by post-self-insert-hook or
> >     after the inserted character.

> Of course, if you truncate the doc string at some arbitrary point, you
> can claim anything about its low quality.

I abstracted the relevant bit.  I'm complaining not about the doc string,
which can't be made adequate, rather about the function, whose
functionality has become indeterminate due to the violation of the
non-convention which you deny doesn't exist.

> The full doc string is this:

>   Insert the character you type.
>   Whichever character C you type to run this command is inserted.
>   The numeric prefix argument N says how many times to repeat the insertion.
>   Before insertion, ‘expand-abbrev’ is executed if the inserted character does
>   not have word syntax and the previous character in the buffer does.
>   After insertion, ‘internal-auto-fill’ is called if
>   ‘auto-fill-function’ is non-nil and if the ‘auto-fill-chars’ table has
>   a non-nil value for the inserted character.  At the end, it runs
>   ‘post-self-insert-hook’.

> Which does mention post-self-insert-hook.  (And the ELisp manual
> expands on the possible uses of that hook.)

Yes.  But that doesn't make the function usable.  Before this mechanism
came into existence, one could depend on self-insert-command inserting
exactly one character and point being after the point of insertion.  Now
an arbitrary collection of characters is inserted and deleted, and point
ends up in an arbitrary position.  This makes self-insert-command
virtually unusable from Lisp.

> What kind of argument is it when you elide arbitrary parts of the
> documentation, just to make your point?  In what book does that
> qualify as a serious discussion?

As I said in my last paragraph, the bit I left out didn't really seem
relevant.  self-insert-command is just as unusable if one considers that
part of the doc string too.

> > ..  This makes it unusable in a Lisp program.

> That's debatable, ....

Then debate it with me, please.

> .... and is not the issue when the doc string and the definition of
> functionality are being discussed.

On the contrary, being able to use a function is the entire point of
documenting it.

> > For example, in c-electric-paren, which handles the user entering "("
> > or ")", the code needs to determine whether the "(" was entered at
> > the end of a line.  The current self-insert-command, which inserts
> > arbitrary further characters, makes this difficult.

> So we have two electric behaviors that could conflict.

That's a most superficial way of regarding the problem, and if one looks
no further, one will end up with a superficial workaround which fails to
solve the underlying problem.

> That's not anything new, and we have ways of handling these situations,
> as Stefan pointed out, and as you can see in the source code.

What Stefan suggested was no longer using self-insert-command.  That is
hardly practical in CC Mode.

> What does this have to do with the issue at hand?

I'm not sure what you see as the issue.  I see the issue as the
unusability of self-insert-command, and I've analysed the cause of this.

Forgive me for pointing out that this was another instance of a big
feature being introduced into Emacs without prior discussion
on emacs-devel, what I was complaining about last November.  I spotted
its flaw instantly on becoming aware of the new feature, but that was too
late actually to get anything done about it.

> > I am suggesting that self-insert-command should be made usable from Lisp
> > again, as it once was, and have suggested a means for achieving this.

> Your request is noted.  I find it hard to believe that we will take
> that direction, since post-self-insert-hook is used in so many useful
> features nowadays.

I can't say I'm all that surprised, sadly.

Note that my changes wouldn't remove any functionality.  They would
merely make self-insert-command work again predictably.

I've tried putting electric-pair-post-self-insert-function and its friend
onto post-command-hook instead of post-self-insert-hook.  It works, sort
of, but would naturaly need some debugging and testing.

Or we just leave the ugly workarounds in c-electric-paren and friends and
fix them whenever they break.  Or replace them with other ugly
workarounds of some nature, perhaps.

I'm not happy about the state of c-electric-paren.

-- 
Alan Mackenzie (Nuremberg, Germany).