When the remote endpoint is handling a local request 'LR' it can
sometimes make a remote sync request 'RR' as part of its handling. Some
endpoints (like Go's gopls) wait for Emacs's reply to 'RR' before
responding to 'LR'. Others (like Julia's JETLS) respond to 'LR'
immediately, and only then wait for Emacs's reply to 'RR'. Both
approaches are valid. However, in the latter case, the handling of 'RR'
(which could well be waiting for user input from the minibuffer to
complete) is vulnerable to 'throw' from process filters handling (which
is just what happens when the endpoints replies to 'LR'), so if that
happens it will unexpectedly be aborted when the reply to 'LR' comes in,
suprising the user and causing a spurious -32603 reply to be sent.
To solve this problem, this commit first refactors the sync
request/anxious queue handling and replace plain integer keys of the
rebaptized "scontrol" alist with structured (:local ID) / (:remote ID)
pairs, using `equal' for comparisons. This is to introduce some
clarity/sanity into this somewhat hairy code.
Then, the 'RR' situation is fixed: we push a (:remote ID) entry onto the
top of the 'jsonrpc-connection--control' stack and only then call
rdispatcher. Any 'LR' reply arriving during dispatch is deferred as an
"anxious" continuation rather than firing its `throw' immediately. When
rdispatcher is done, we call jsonrpc--continue at a safe point, this
will run any "anxious" continuations.
* lisp/jsonrpc.el (jsonrpc-connection): Rename -sync-request-alist to
-scontrol; accessor from jsonrpc--sync-request-alist to
jsonrpc--scontrol; update docstring for new key structure.
(jsonrpc-connection-receive): Update with-slots binding to scontrol.
Tighten anxious check to match (:local ID) keys with `equal'. In
remote-request branch, push (:remote ID) entry before rdispatcher and
call jsonrpc--continue after jsonrpc--reply.
(jsonrpc-request): Pass (:local ID) to jsonrpc--continue.
(jsonrpc--continue): Use jsonrpc--scontrol; change `=' to `equal' in
sanity check.
p
(jsonrpc--async-request-1): Push (:local ID) entry.
(jsonrpc--log-event): Use jsonrpc--scontrol.
* src/xdisp.c (clear_garbaged_frames): Re-add the call to
clear_under_internal_border, reverting that part of commit
a6a3b32208 as not essential to the fix (bug#80662).
* lisp/emacs-lisp/package.el (package-isolate): Use
'package--archive-contents' instead of the actual variable, to
ensure that we load the archive contents if missing. This is
likely the case if 'package-isolate' is the first package
function invoked during a session.
* lisp/textmodes/sgml-mode.el (sgml-whitespace-sensitive-tags):
Add new variable.
(sgml-calculate-indent): Check if in the context of a tag
specified by 'sgml-whitespace-sensitive-tags'.
(html-mode): Set 'sgml-whitespace-sensitive-tags' to not adjust
the indentation within <pre> and <textarea> tags.
* lisp/textmodes/sgml-mode.el (sgml-validate-command): If no
known program is installed, fall back to nil as the default
value instead of a warning message.
* lisp/textmodes/sgml-mode.el (sgml-quick-keys): Replace with
user option, that adjusts 'sgml-mode-map'.
(sgml-mode-map): Don't insert quick keys.
(html-quick-keys): Replace with user option, that adjusts
'html-mode-map'.
(html-mode-map): Don't insert quick keys.
* lisp/gnus/gnus-srvr.el (gnus-server-mode): Initialize needed
format specifications and call 'gnus-set-mode-line' for the
server buffer.
* lisp/gnus/gnus-sum.el (gnus-set-mode-line): Handle when WHERE
is set to 'server.
* lisp/gnus/gnus.el (gnus-updated-mode-lines): Add server.
We decided to leave it out for now, see discussion at
https://yhetil.org/emacs/jwvqzntzvvg.fsf-monnier+emacs@gnu.org/
This brings completion-preview.el back to how it were before
commit a24ff52a79.
* lisp/completion-preview.el (completion-preview--is-calling):
Delete.
(completion-preview--capf-wrapper): Adapt.
* lisp/vc/vc-dir.el (vc-dir-resynch-file): Apply 'file-truename'
instead of 'expand-file-name' to FNAME argument to prevent
spurious display of symlinked files in *vc-dir* buffer.
* lisp/progmodes/eglot.el (eglot-code-action-indicator): No lighbulb, no
fancy lightning bolt, just use zigzags which seem to display well on
typical fonts and typically have a width of 1.
* lisp/progmodes/project.el (project-prompter)
(project-prompt-project-dir, project-prompt-project-name):
Delete ALLOW-EMPTY parameter. Default to the current project if
there is one.
* lisp/vc/vc.el (project-root): Declare.
(vc--prompt-other-working-tree): Replace ALLOW-EMPTY parameter
with new ALLOW-CURRENT parameter.
(vc-working-tree-switch-project): Allow selecting the current
working tree, for symmetry with project-switch-project.
* etc/NEWS: Update.
* configure.ac: When configured with --enable-gcc-warnings,
use the -Wno-analyzer-allocation-size option if available.
This works around a false positive bug in
GCC 16.0.1 20260321 (Red Hat 16.0.1-0) x86-64; see
<https://gcc.gnu.org/bugzilla/show_bug.cgi?id=125116>.
* src/gtkutil.c (xg_frame_set_char_size): Resize child frame and
its GTK widget hierarchy immediately. Update the "desired" Cairo
surface dimensions. Skip waiting for events. (bug#80662)
Remove the unnecessary call to clear_under_internal_border.
* src/gtkutil.c (xg_frame_set_char_size): Simplify. Use the
fullscreen value check to alter the values of outer_width and
outer_height rather than have several larger branches (bug#80662).
* src/gtkutil.c (xg_frame_set_char_size): Remove the effect of
x_gtk_resize_child_frames, effectively reverting that part of
c49d379f17 (bug#80662).
* src/pgtkfns.c (syms_of_pgtkfns): Remove defsyms Qhide and
Qresize_mode, never used with PGTK.
* src/xfns.c (x-gtk-resize-child-frames): Update docstring.
* src/xterm.c (x_wait_for_event): If f->wait_event_type has been
cleared (in handle_one_xevent), don't go into pselect wait.
* src/androidterm.c (android_wait_for_event): Likewise.
This pertains to X11 toolkit builds. Other ports (including
PGTK) seem to have mostly atomic window updates already.
* src/xterm.c (x_set_window_size_1): Resize the Xt widget eagerly,
so the next redraw is not clipped. Update the "desired" Cairo
surface dimensions. Skip waiting for next XEvent. Do all that
for child frames only. Update old comments (bug#80662).
(x_set_window_size_and_position_1): Same. Also clear the widget's
cached position coordinates (we don't keep them up to date).
(x_set_window_size, x_set_window_size_and_position): Skip
redrawing the border on child frames, it will happen during
redisplay anyway.
* src/gtkutil.c (xg_frame_set_size_and_position): On child
frames, resize the GTK widget hierarchy immediately. Update the
"desired" Cairo surface dimensions. Skip waiting for events.
* src/widget.c (EmacsFrameResize):
When resize should be a no-op, exit early (minor optimization).
(EmacsFrameExpose): Redraw the border on the last Expose event.
* src/xdisp.c (clear_garbaged_frames): Don't redraw borders here.
* src/xfns.c (x_window): Undo the previous change in bit_gravity
in the no-toolkit build. StaticGravity works the best for it
thanks to no nesting in window configuration.
* src/xdisp.c (glyph_string_containing_background_width):
Although it’s not immediately obvious whether the GCC 16 warning
is valid, adding an eassume here shouldn’t hurt.
* etc/ERC-NEWS: Add entry for option `erc-log-insert-log-on-open'.
Mention deprecation of `erc-log-setup-logging'.
* lisp/erc/erc-log.el (erc-log-insert-log-on-open): Expand type from
boolean to choice of boolean, predicate, and new function item
`erc-log-new-target-buffer-p'.
(erc-log-mode, erc-log-enable, erc-log-disable): Replace
`erc-log-setup-logging' on `erc-connect-pre-hook' with
`erc-log--insert-log-on-open' at depth 80. Replace calls to
`erc-log-setup-logging' with ones to `erc-log--setup'.
(erc-log-new-target-buffer-p): New function. While the name could
perhaps do more to indicate that it's only useful when called from
`erc-open', that's the only place ERC typically sets up new target
buffers.
(erc-log-setup-logging): Deprecate and replace body with adapter that
calls `erc-log--setup' and `erc-log--insert-log-on-open'.
(erc-log--setup): New function whose body is mostly from the
"nondestructive" portion of `erc-log-setup-logging'. Instead of moving
the `erc-saved-last-position' marker to the old value, expect it not to
have been initialized by `erc-initialize-log-marker' because
`erc-connect-pre-hook' now runs after this code, which is now
incorporated more judiciously into the module's "enable body".
(erc-log--insert-log-on-open): New function whose body is mostly from
the "destructive" portion of the previous incarnation of
`erc-log-setup-logging'. Unlike the original, if option
`erc-log-insert-log-on-open' is a function, call it to decide whether to
insert a log file atop its buffer. Also, don't advance the marker
`erc-last-saved-position' to the prompt area, where it can get stuck and
prevent logs from being saved when `erc-log-insert-log-on-open' is
non-nil. Thanks to Libera user Lionyx for reporting the bug, which has
been around since at least ERC 5.4 and Emacs 28.1.
(erc-log-disable-logging): Remove `erc-save-buffer-in-logs' from
`write-file-functions' to undo its buffer-local addition in what is now
`erc--log-setup'.
* test/lisp/erc/erc-scenarios-log-options.el: New file. (Bug#79665)
* lisp/erc/erc-log.el (erc-log-setup-logging): Restore
`erc-last-saved-position' from previous session. By default, a
non-/QUIT disconnect does not write out any remaining buffer text to
logs, instead leaving it until the buffer or Emacs is killed. But if a
successful reconnect occurs beforehand, the uncommitted portion must be
seen to somehow. Before this change, it would be lost because the
function `erc-initialize-log-marker' remakes the marker at the prompt
instead of recovering the previous value as now done here. Moreover,
the traditional workaround of customizing `erc-log-write-after-insert'
and `erc-log-write-after-send' to t should not be required to prevent
gaps in any decent IRC client.
* test/lisp/erc/erc-scenarios-log.el (erc-scenarios-log--reconnect): New
function.
(erc-scenarios-log--reconnect/auto, erc-scenarios-log--reconnect/manual):
New tests.
;; * test/lisp/erc/resources/join/reconnect/foonet-again.eld: Add QUIT.
* lisp/erc/erc-pcomplete.el (erc-completion-mode): New alias for the
variable `erc-pcomplete-mode' to complement the function alias of the
corresponding minor-mode command. Given that user code operating on the
value of `erc-modules' needs to detect whether members are active, it
only makes sense to address this specially. Before this change,
applying `bound-and-true-p' to `erc-completion-mode' would always return
nil, even when the module was active. For normal aliases, that's indeed
expected because `define-erc-module' doesn't automatically define a mode
variable for a non-nil ALIAS argument. Although in the long term it
probably should, while also obsoleting the "new" alias simultaneously,
that would likely break some user code and doubtless complicate things
majorly for `pcomplete', the one in-tree outlier. The latter module
would then require changing either its preferred name, the one
advertised by `erc-modules' in its Custom definition, to `pcomplete' or
its primary name to `completion'. Both are quite churn-inducing.
* test/lisp/erc/erc-scenarios-keep-place-indicator.el
(erc-scenarios-keep-place-indicator--follow): Intersperse more
`redisplay' calls to update the indicator's overlay.
* test/lisp/erc/erc-tests.el (erc-tests--assert-printed-in-subprocess):
Wrap CODE form in keyword sentinel.
(erc--find-mode, erc--essential-hook-ordering): Use modified interface.
(erc--find-group--real, erc--find-group/realistic): Rename former to
latter and run in subprocess.
(erc--update-modules/realistic): Redo to run in subprocess instead of
mocking.
* test/lisp/erc/resources/erc-d/erc-d-t.el
(erc-d-t-kill-related-buffers): Don't bother canceling
`erc-server-flood-timer', even in an actual ERC buffer, since
`erc-server-send-queue' first checks whether its BUFFER argument is
still live before sending anything to the process. Also, don't bother
collecting buffers only to immediately kill them.
* test/lisp/erc/resources/erc-d/erc-d.el (erc-d--filter): Always clear
remainder. Otherwise, partial emissions from the peer that aren't
terminated by a newline will confuse subsequent processing.
* test/lisp/erc/resources/erc-scenarios-common.el
(erc-scenarios-common--run-in-term): Look for a library called
`erc-tests-compat', which ERC uses in its external CI to provide
compatibility shims of definitions too obscure or unfit for inclusion in
the Compat package on ELPA.
* test/lisp/erc/resources/erc-tests-common.el
(erc-tests-common-kill-buffers): Also kill non-`erc-mode' buffers whose
names match a scheme used by ERC for work buffers. Allow for the
EXTRA-BUFFERS argument to possibly contain killed and null buffers.
* lisp/completion-preview.el (completion-preview-is-calling):
New variable.
(completion-preview--capf-wrapper): Bind it to t when calling
the CAPF.
* etc/NEWS: Announce it.