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
bug-gnu-emacs <at> gnu.org:bug#80163; Package emacs.
(Fri, 09 Jan 2026 16:58:02 GMT) Full text and rfc822 format available.Platon Pronko <platon7pronko <at> gmail.com>: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))
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
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.
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
GNU bug tracking system
Copyright (C) 1999 Darren O. Benham,
1997,2003 nCipher Corporation Ltd,
1994-97 Ian Jackson.