GNU bug report logs - #80163
31.0.50; regression in 61b1554332c - help buffer shown when opening emacs

Previous Next

Package: emacs;

Reported by: Platon Pronko <platon7pronko <at> gmail.com>

Date: Fri, 9 Jan 2026 16:58:02 UTC

Severity: normal

Found in version 31.0.50

To reply to this bug, email your comments to 80163 AT debbugs.gnu.org.

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#80163; Package emacs. (Fri, 09 Jan 2026 16:58:02 GMT) Full text and rfc822 format available.

Acknowledgement sent to Platon Pronko <platon7pronko <at> gmail.com>:
New bug report received and forwarded. Copy sent to bug-gnu-emacs <at> gnu.org. (Fri, 09 Jan 2026 16:58:02 GMT) Full text and rfc822 format available.

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

From: Platon Pronko <platon7pronko <at> gmail.com>
To: bug-gnu-emacs <at> gnu.org, Jared Finder <jared <at> finder.org>
Subject: 31.0.50; regression in 61b1554332c - help buffer shown when opening
 emacs
Date: Fri, 9 Jan 2026 20:56:43 +0400
If async xterm queries are used (setq xterm-query-timeout nil) then when opening new terminal instance (emacs -nw) *Help* buffer is immediately shown.

How to reproduce: leave only `(setq xterm-query-timeout nil)` in init.el, run `emacs -nw`.
(running `emacs -Q -nw -e '(setq xterm-query-timeout nil)'` won't trigger the bug)

This regression was introduced by commit 61b1554332cb9b40b25976e12bbc6e1e33e4802e, 2025-12-25, by Jared Finder.



In GNU Emacs 31.0.50 (build 1, x86_64-pc-linux-gnu, GTK+ Version
 3.24.51, cairo version 1.18.4) of 2026-01-09 built on the-big-maker
Repository revision: d9cc684d104e83dd0e020d76616914f200836f6f
Repository branch: master
Windowing system distributor 'The X.Org Foundation', version 11.0.12101021
System Description: Arch Linux

Configured using:
 'configure --prefix=/usr --sysconfdir=/etc --libexecdir=/usr/lib
 --localstatedir=/var --mandir=/usr/share/man --with-gameuser=:games
 --with-modules --without-m17n-flt --without-gconf
 --with-native-compilation=no --with-xinput2 --with-x-toolkit=gtk3
 --without-xaw3d --with-sound=no --with-tree-sitter --without-gpm
 --without-compress-install
 '--program-transform-name=s/\([ec]tags\)/\1.emacs/'
 'CFLAGS=-march=x86-64 -mtune=generic -O2 -pipe -fno-plt -fexceptions
 -Wp,-D_FORTIFY_SOURCE=3 -Wformat -Werror=format-security
 -fstack-clash-protection -fcf-protection -fno-omit-frame-pointer
 -mno-omit-leaf-frame-pointer'
 LDFLAGS=-Wl,-O1,--sort-common,--as-needed,-z,relro,-z,now'

Configured features:
ACL CAIRO DBUS FREETYPE GIF GLIB GMP GNUTLS GSETTINGS HARFBUZZ JPEG
LCMS2 LIBOTF LIBSYSTEMD LIBXML2 MODULES NOTIFY INOTIFY PDUMPER PNG RSVG
SECCOMP SQLITE3 THREADS TIFF TOOLKIT_SCROLL_BARS TREE_SITTER WEBP X11
XDBE XIM XINERAMA XINPUT2 XPM XRANDR GTK3 ZLIB

Important settings:
  value of $LC_TIME: en_SE.UTF-8
  value of $LANG: en_US.UTF-8
  locale-coding-system: utf-8-unix

Major mode: Lisp Interaction

Minor modes in effect:
  smartparens-strict-mode: t
  smartparens-mode: t
  rainbow-delimiters-mode: t
  global-git-gutter-mode: t
  counsel-mode: t
  ivy-mode: t
  global-whitespace-mode: t
  whitespace-mode: t
  global-dvorak-mode: t
  dvorak-minor-mode: t
  global-auto-revert-mode: t
  global-so-long-mode: t
  tooltip-mode: t
  global-eldoc-mode: t
  eldoc-mode: t
  show-paren-mode: t
  electric-indent-mode: t
  mouse-wheel-mode: t
  file-name-shadow-mode: t
  global-font-lock-mode: t
  font-lock-mode: t
  blink-cursor-mode: t
  minibuffer-nonselected-mode: t
  minibuffer-regexp-mode: t
  column-number-mode: t
  line-number-mode: t
  transient-mark-mode: t
  auto-composition-mode: t
  auto-encryption-mode: t
  auto-compression-mode: t

Load-path shadows:
/home/platon/.emacs.d/elpa/transient-20260104.1649/transient hides /usr/share/emacs/31.0.50/lisp/transient
/home/platon/.emacs.d/elpa/elixir-ts-mode-20241228.919/elixir-ts-mode hides /usr/share/emacs/31.0.50/lisp/progmodes/elixir-ts-mode
/home/platon/.emacs.d/elpa/heex-ts-mode-20250511.643/heex-ts-mode hides /usr/share/emacs/31.0.50/lisp/progmodes/heex-ts-mode

Features:
(shadow sort mail-extr emacsbug lisp-mnt message yank-media puny dired
dired-loaddefs rfc822 mml mml-sec epa derived epg rfc6068 epg-config
gnus-util text-property-search time-date mm-decode mm-bodies mm-encode
mailabbrev gmm-utils mailheader sendmail mail-parse rfc2231 rfc2047
rfc2045 ietf-drums mm-util mail-prsvr mail-utils color edmacro kmacro
smartparens-config smartparens-text smartparens advice loadhist dash
rainbow-delimiters dabbrev yasnippet git-gutter-fringe fringe-helper
git-gutter counsel swiper ivy-hydra ivy ivy-faces colir hydra lv rx
format-spec thingatpt disp-table whitespace quail easy-mmode ace-window
avy ring cl-extra help-mode use-package-core darcula-theme autorevert
filenotify so-long finder-inf ace-window-autoloads avy-autoloads
company-box-autoloads company-autoloads counsel-autoloads
elixir-ts-mode-autoloads erlang-autoloads frame-local-autoloads
git-gutter-autoloads go-mode-autoloads gptel-autoloads
haskell-mode-autoloads heex-ts-mode-autoloads ivy-hydra-autoloads
hydra-autoloads lorem-ipsum-autoloads lsp-pyright-autoloads
lsp-mode-autoloads ht-autoloads f-autoloads magit-autoloads pcase
magit-section-autoloads llama-autoloads markdown-mode-autoloads
pyim-basedict-autoloads pyim-autoloads async-autoloads
rust-mode-autoloads s-autoloads scala-mode-autoloads
smartparens-autoloads dash-autoloads solidity-mode-autoloads
svg-lib-autoloads swiper-autoloads ivy-autoloads transient-autoloads
cond-let-autoloads typescript-mode-autoloads web-mode-autoloads
wgrep-autoloads info with-editor-autoloads xr-autoloads
yaml-mode-autoloads yasnippet-autoloads package browse-url xdg url
url-proxy url-privacy url-expand url-methods url-history url-cookie
generate-lisp-file url-domsuf url-util mailcap url-handlers url-parse
auth-source cl-seq eieio eieio-core cl-macs icons password-cache json
subr-x map byte-opt gv bytecomp byte-compile url-vars cl-loaddefs cl-lib
rmc iso-transl tooltip cconv eldoc paren electric uniquify ediff-hook
vc-hooks lisp-float-type elisp-mode mwheel term/x-win x-win
term/common-win x-dnd touch-screen tool-bar dnd fontset image regexp-opt
fringe tabulated-list replace newcomment text-mode lisp-mode prog-mode
register page tab-bar menu-bar rfn-eshadow isearch easymenu timer select
scroll-bar mouse jit-lock font-lock syntax font-core term/tty-colors
frame minibuffer nadvice seq simple cl-generic indonesian philippine
cham georgian utf-8-lang misc-lang vietnamese tibetan thai tai-viet lao
korean japanese eucjp-ms cp51932 hebrew greek romanian slovak czech
european ethiopic indian cyrillic chinese composite emoji-zwj charscript
charprop case-table epa-hook jka-cmpr-hook help abbrev obarray oclosure
cl-preloaded button loaddefs theme-loaddefs faces cus-face macroexp
files window text-properties overlay sha1 md5 base64 format env
code-pages mule custom widget keymap hashtable-print-readable backquote
threads dbusbind inotify lcms2 dynamic-setting system-font-setting
font-render-setting cairo gtk x-toolkit xinput2 x multi-tty move-toolbar
make-network-process tty-child-frames emacs)

Memory information:
((conses 16 352937 34937) (symbols 48 21799 0)
 (strings 32 121665 3637) (string-bytes 1 2880853) (vectors 16 33480)
 (vector-slots 8 323979 12362) (floats 8 190 628) (intervals 56 498 0)
 (buffers 1064 11))




Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#80163; Package emacs. (Sat, 10 Jan 2026 05:18:04 GMT) Full text and rfc822 format available.

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

From: Jared Finder <jared <at> finder.org>
To: Platon Pronko <platon7pronko <at> gmail.com>, 80163 <at> debbugs.gnu.org
Subject: regression in 61b1554332c - help buffer shown when opening emacs
Date: Fri, 09 Jan 2026 21:16:58 -0800
On 2026-01-09 08:56, Platon Pronko wrote:
> If async xterm queries are used (setq xterm-query-timeout nil) then 
> when opening new terminal instance (emacs -nw) *Help* buffer is 
> immediately shown.
> 
> How to reproduce: leave only `(setq xterm-query-timeout nil)` in 
> init.el, run `emacs -nw`.
> (running `emacs -Q -nw -e '(setq xterm-query-timeout nil)'` won't 
> trigger the bug)
> 
> This regression was introduced by commit 
> 61b1554332cb9b40b25976e12bbc6e1e33e4802e, 2025-12-25, by Jared Finder.

I can confirm this behavior locally, but I see the regression from 
d4dde314ffbc97cb3431e8803e8fb46ce36c2274 instead. Specifically, adding 
the query for the primary DA. Removing that query avoids the issue.

The fundamental issue is the "asynchronous path" in xterm-query causes 
the Primary DA and Secondary DA queries to conflict. The following 
happens:

1. Secondary DA query registers handlers in input-decode-map "\e[?" and 
"\e[>".
2. Secondary DA query sends "\e[>0c" to terminal
3. Primary DA query overwrites the handler in input-decode-map "\e[?".
4. Primary DA query sends "\e[c" to terminal
5. Terminal response to secondary DA query with prefix "\e[>" is read. 
Secondary DA handler executes. xterm--query then cleans up both "\e[?" 
and "\e[>" registrations.
6. Terminal response to primary DA query with prefix "\e[?" is read. 
Primary DA handler was erased in step 5, so this goes to normal Emacs 
handling, which ends up calling describe-prefix-bindings since ESC [ is 
the prefix for Xterm responses, ? is unbound in that prefix, and ? is in 
help-even-list.

I see a few possible solutions here (in my order of preference):

We could remove the "\e[?" response registration in the secondary DA 
query. This is not a proper response. Testing on MacOS 26.2, the 
terminal properly responds to "\e>0c" with a "\e[>" prefixed response. 
Downside: I don't know how recent the MacOS terminal bugfix to send a 
proper terminal response is and those will regress.

We could not send a Primary DA query if xterm-query-timeout is nil. 
Downside: We no longer can detect automatically that OSC52 (clipboard 
interaction) is supported.

We could also just delete the asynchronous code path for when 
xterm-query-timeout is nil. This codepath will cause more problems in 
the future because many terminal queries have the same response prefix. 
For example "\e[> ... c", "\e[? ... g", and "\e[? ... m" all have 
responses with the prefix "\e[>". Or "\e[> ... q", "\e[ ... $w", and 
"\e[ ... *y" all responses with the prefix "\eP". Downside is we're 
changing behavior on everyone who benefits from xterm-query-timeout's 
async code path.


If someone has an older version of MacOS lying around, it'd be really 
helpful to see if we can just proceed with removing the "\e[?" response.

  -- MJF




Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#80163; Package emacs. (Sat, 10 Jan 2026 09:13:02 GMT) Full text and rfc822 format available.

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

From: Platon Pronko <platon7pronko <at> gmail.com>
To: Jared Finder <jared <at> finder.org>, 80163 <at> debbugs.gnu.org
Subject: Re: regression in 61b1554332c - help buffer shown when opening emacs
Date: Sat, 10 Jan 2026 13:12:12 +0400
> We could also just delete the asynchronous code path for when xterm-query-timeout is nil. This codepath will cause more problems in the future because many terminal queries have the same response prefix. For example "\e[> ... c", "\e[? ... g", and "\e[? ... m" all have responses with the prefix "\e[>". Or "\e[> ... q", "\e[ ... $w", and "\e[ ... *y" all responses with the prefix "\eP". Downside is we're changing behavior on everyone who benefits from xterm-query-timeout's async code path.
I initially enabled the async code path (xterm-query-timeout nil) many years before, because it fixed an issue where interleaving input resulted in garbage being inserted into the buffer: https://debbugs.gnu.org/cgi/bugreport.cgi?bug=34821
At that time, I thought that it's the only "correct" approach - because synchronous terminal query-response mechanism is inherently not "parallel safe" against other input.

So I think just disabling async code path would also cause regressions. In fact, comment in xterm--query suggests that maybe async code path should be used always.

I'd like to add a fourth solution to the proposed list.
Instead of overwriting the handler, perhaps it's possible to make a "queue" of response handlers? This of course assumes that terminal is guaranteed (or at least "highly likely") to send responses to these queries in order of arrival.
However, I don't know how to implement such a queue. Simple solutions are incomplete, and complete solutions are very complex (I think a global variable for holding xterm-query response hanlders will be required).

For clarity, if using response handler queue the event sequence will be as follows:

1. Secondary DA query registers handlers in input-decode-map "\e[?" and "\e[>".
2. Secondary DA query sends "\e[>0c" to terminal
3. Primary DA query tries overwriting the handler in input-decode-map for "\e[?", but notices that there's a handler already.
4. Primary DA query appends it's response handler to response handler queue for "\e[?".
5. Primary DA query sends "\e[c" to terminal.
6. Terminal response to secondary DA query with prefix "\e[>" is read. Secondary DA handler executes, it's handlers are removed, leaving primary DA response handler alone in the queue.
7. Terminal response to primary DA query with prefix "\e[?" is read. Primary DA handler executes.





Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#80163; Package emacs. (Sat, 10 Jan 2026 15:07:01 GMT) Full text and rfc822 format available.

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

From: Jared Finder <jared <at> finder.org>
To: Platon Pronko <platon7pronko <at> gmail.com>
Cc: 80163 <at> debbugs.gnu.org
Subject: Re: regression in 61b1554332c - help buffer shown when opening emacs
Date: Sat, 10 Jan 2026 07:06:52 -0800
On 2026-01-10 01:12, Platon Pronko wrote:
>> We could also just delete the asynchronous code path for when 
>> xterm-query-timeout is nil. This codepath will cause more problems in 
>> the future because many terminal queries have the same response 
>> prefix. For example "\e[> ... c", "\e[? ... g", and "\e[? ... m" all 
>> have responses with the prefix "\e[>". Or "\e[> ... q", "\e[ ... $w", 
>> and "\e[ ... *y" all responses with the prefix "\eP". Downside is 
>> we're changing behavior on everyone who benefits from 
>> xterm-query-timeout's async code path.
> I initially enabled the async code path (xterm-query-timeout nil) many 
> years before, because it fixed an issue where interleaving input 
> resulted in garbage being inserted into the buffer: 
> https://debbugs.gnu.org/cgi/bugreport.cgi?bug=34821
> At that time, I thought that it's the only "correct" approach - because 
> synchronous terminal query-response mechanism is inherently not 
> "parallel safe" against other input.
> 
> So I think just disabling async code path would also cause regressions.

Yeah, such is the nature of dealing with a single shared data stream for 
both user input and escape sequence query responses. There's no way to 
prevent valid user pressed characters to come in between Lisp execution 
of (send-string-to-terminal) and a terminal's response with multiple 
processes (Emacs and the terminal) executing concurrently here. And 
these valid user pressed characters could themselves be escape 
sequences, like if the user pressed <f1> or <left>.

To be safe, I think any query to the terminal with escape sequences 
needs to satisfy the following principles:

1. Tolerate a lack of response, which is what terminals do when they 
don't support a particular query.  This should be assumed to be likely 
for any escape sequence; no terminal supports all possible escape 
sequences.
2. Tolerate a validly terminated ill-formed response. This is sadly 
common because of the significant number of terminal implementations. I 
think these are incrementally discovered per-terminal workarounds, like 
the MacOS default Terminal workaround in question here.
3. Handle valid user input that may come in between the query request 
and the query response.

The current sync code path minimizes the chance of #3 by discarding 
input before sending the query, minimizing the time of a response.  Not 
great but very simple.

The current async code path doesn't really handle #1 at all because it 
has no logic to timeout waiting for a response. Maybe it can be 
augmented with timers to detect a lack of response? It also has an issue 
with #2 because of the shared response prefixes I mentioned before.

> In fact, comment in xterm--query suggests that maybe async code path 
> should be used always.
> 
> I'd like to add a fourth solution to the proposed list.
> Instead of overwriting the handler, perhaps it's possible to make a 
> "queue" of response handlers? This of course assumes that terminal is 
> guaranteed (or at least "highly likely") to send responses to these 
> queries in order of arrival.
> However, I don't know how to implement such a queue. Simple solutions 
> are incomplete, and complete solutions are very complex (I think a 
> global variable for holding xterm-query response handlers will be 
> required).

As a variant of this approach, perhaps we build on the sync path 
instead.  Instead of queueing the response handling, perhaps Emacs could 
queue up input found that wasn't an expected escape sequence instead of 
discarding that input.  After encountering a proper response or timing 
out due to a lack of response, this queued input would be re-injected 
into Emacs via unread-command-events.

This is also a complex solution. But it has the benefit of keeping all 
complexity within the duration of the call to xterm--query.  I suspect 
that makes the complexity way more manageable.

  -- MJF




This bug report was last modified 1 day ago.

Previous Next


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