Subject: bug#79058: 30.1; involking signal using emacsclient takes very long time to complete ~2 seconds

From: Bror Winther <[email-masked]>
Date: Mon, 21 Jul 2025 15:22:06 +0200

> On 21 Jul 2025, at 13.06, Eli Zaretskii <[email-masked]> wrote:
> 
>> From: Bror Winther <[email-masked] <mailto:[email-masked]>>
>> Date: Sun, 20 Jul 2025 22:07:10 +0200
>> Cc: [email-masked] <mailto:[email-masked]>
>> 
>> 
>> 
>>> On 20 Jul 2025, at 20.54, Eli Zaretskii <[email-masked] <mailto:[email-masked]>> wrote:
>>> 
>>>> From: Bror Winther <[email-masked] <mailto:[email-masked]>>
>>>> Date: Sun, 20 Jul 2025 19:20:22 +0200
>>>> Cc: [email-masked] <mailto:[email-masked]>
>>>> 
>>>> Sure, no problem at all. I use a tiling window manager. For this I have a script
>>>> for navigating between OS windows and for consistency I use the same script to
>>>> navigate windows in Emacs. The script uses emacsclient --eval “(evil-window-up
>>>> 1)” to navigate a window up, if this fails it will call the window manager
>>>> instead because it means that there is no window in that direction. Because the
>>>> wait is now 2 seconds it takes 2 seconds to shift focus out of emacs. This might
>>>> be a minor nuisance but enough to be annoying.
>>> 
>>> Sorry, I don't understand: the wait is only when an error message is
>>> to be displayed.  Your description above doesn't involve any messages,
>>> AFAIU, so how is the recipe you've shown related to your real problem?
>> 
>> The script waits for emacsclient to finish execution, and execution is halted
>> for 2 seconds to wait for the error message to be displayed. This means that any
>> script calling an Emacs command with emacsclient that results in an error now
>> takes 2 seconds longer to complete than it did previously.
> 
> If there's no one to see the error message, why is the error message
> issued? it should be suppressed if it is not intended for human
> consumption.

I don’t think that is a fair question as I don’t think an error is only for human consumption.
The error should not be suppressed, as it is still useful.

>> In my case, the script I use for OS window management calls Emacs to change
>> windows. If there is no window in the requested direction Emacs throws an error.
>> The script then tells the OS window manager to change focus instead. This now
>> takes 2 seconds extra.
> 
> So my suggestion for this case is to use ignore-errors around the form
> which could signal an error, or some other method of suppressing the
> error.

I currently use the exit code from emacsclient. If I where to suppress the errors
with ignore-errors, the exit code would always be 0. Of course I could create 
more logic to handle this but that seems like the wrong way to go about this.
It should be possible to fire one-liners to without having to wait for the error to
be displayed imo.

>>> Thanks, but I don't see any need to make this a user option.  If some
>>> rare Lisp program needs to control the wait time after showing an
>>> error message, it can let-bind a simple variable.  Users have no
>>> reason to customize this time globally.
>> 
>> From a user perspective, calling emacsclient --eval from a shell or script, I
>> would not expect it to halt execution for 2 seconds just to display an error on
>> the server. Especially since this also affects workflows where Emacs is run
>> daemonized. 
> 
> We had exactly opposite requests, and thus introduced this feature.
> So at least some users do care about error messages in client frames.

I would think as much. As I said I completely understand the reason behind this
and not being able to set the delay or ignore it is probably just a small oversight.

> You seem to be assuming that --eval used from a script necessarily
> means that errors important for the users should never happen, but
> that is definitely not the case in general.  When errors do happen, it
> is important to let the user see them.

That was not what I was assuming. I understand the general use case and that 
my use is a bit more infrequent. And I’m not arguing to remove the delay
if that is what came across. I tried to make the case that exclusively halting both emacs
and caller program to show an error is a surprising (and somewhat archaic,
pardon my words) choice. Surely there would be a way to have the --eval caller exit
while retaining the error.

> 
>> For instance:
>> 
>> ```
>> emacs —daemon 
>> emacsclient --eval "(windmove-up)” 
>> ```
>> 
>> will now take 2 seconds longer due to the display wait.
> 
> As I said above, using
> 
>  emacsclient --eval "(ignore-errors (windmove-up))”
> 
> should solve this problem very easily.

Yes but then I won’t know if it failed or not

> 
>> Having it as a user
>> option would empower users to decide whether their scripts should incur this
>> delay or not, preserving the responsiveness of Emacs in integrated window
>> management or automation setups.  _(please note I know that these two commands
>> are a bit nonsensical given that there are no windows)_
> 
> A user option has global effect, i.e. it affects all the client
> connections and frames.  By contrast, ignoring errors only where the
> user's scripts really don't care about the errors will allow users to
> see messages that matter.

I think being able to disable the wait globally is useful. That
was the reasoning behind it at least.

> That is why I think the proper solution is to have a simple variable
> that Lisp programs could bind as part of such scripts to easily
> disable the wait, if using ignore-errors or similar technique is for
> some reason inconvenient or inappropriate.

As I understand, this would mean that I would have to bind it every time I call --eval if I don’t
want to wait for errors? I don’t think this is ideal either.

>> Maybe I'm misunderstanding the intetion. From the doc string I understand that
>> the delay is a means to fix a bug where the error might not be written to stderr
>> and thus showing the message somewhere. In daemonized mode that message is not
>> being displayed anywhere yet the client waits for it to finish displaying.
> 
> The intent is to stderr of emacsclient.  The server has no way of
> knowing whether the emacsclient's stderr is shown anywhere.

 ;; Display the error as a message and give the user time to see
 ;; it, in case the error written by emacsclient to stderr is not
 ;; visible for some reason.

My understanding was that the error might not have been written by emacsclient to stderr and thus 
we just wait and hope the user sees it. From your comment I guess we wait for the client to show
it which makes a bit more sense. This raises another question, how does that make sense with 
--eval then? Are we waiting, in the terminal, for the user to see the output? In that case I think it is
perfectly reasonable to exit early as stderr usually gets written as well. I’m not sure I fully
understand what the issue based on this doc string.

> 
>> While I understand the reasoning behind the fixed delay, I believe it would be
>> more user-friendly to make it configurable, since the current approach halts
>> execution and may not suit all use cases.
> 
> I agreed to allow this to be controllable by Lisp programs.  However,
> a user option is not the only method of providing such control, and in
> this case I believe it is sub-optimal, for the reason I mentioned: its
> effect is global.  In addition, adding another user option requires us
> to document it in user-level terms, and increases the number of user
> options in Emacs that is already huge.  So I prefer to have a simple
> variable rather than a user option, because the problem, when it
> happens, is local and ephemeral.

That is completely fair. However it sounds like you are suggesting to include this
as an undocumented user option instead (I could be wrong). A simple variable would definitely
suffice but I don’t agree completely with the argument against making it a user option. Only 
that it would be less work, which is of course true.

Apologies if I sound argumentative or combative, that is not my intent.

//bror