From b224605d305f71c798877c4228afe18ded7a39ef Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=A3o=20T=C3=A1vora?= Date: Mon, 26 Jan 2026 22:56:33 +0000 Subject: [PATCH] Jsonrpc: avoid redisplay_internal calls from jsonrpc-request The 'jsonrpc-request' function, when called with non-nil CANCEL-ON-INPUT, relies on 'sit-for' to stop immediately when the user inputs something into Emacs. Although this behavior is working well, it has the hitherto undiscovered side effect of invoking 'redisplay_internal', which triggers expensive operations such as fontification. This bug was noticied when using the 'breadcrumb' package in conjunction with Eglot and a narrowed buffer. To provide breadcrumbs for the current context, breadcrumb.el invokes 'imenu--make-index-alist' on a timer. That function temporarily widens the buffer and then eventually calls 'redisplay_internal' (through 'eglot-imenu', 'jsonrpc-request', and 'sit-for'). This has the effect that the temporarily widened buffer is re-rendered and displayed to the user until the LSP server answers the request and 'imenu--make-index-alist' restores the restriction, an effect that lasts between 0.5 and 2 seconds usually and is annoying and confusing. To fix this, using a non-nil NODISP argument in the 'sit-for' is not enough (though it's arguable it should be and maybe that's a separate bug). Binding 'inhibit-redisplay' to 't' around 'sit-for' seems to fix the issue robustly. * lisp/jsonrpc.el (jsonrpc-request): Bind inhibit-redisplay to t and pass NODISP to sit-for. --- lisp/jsonrpc.el | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/lisp/jsonrpc.el b/lisp/jsonrpc.el index 74a59a04095..fca00dd2fc7 100644 --- a/lisp/jsonrpc.el +++ b/lisp/jsonrpc.el @@ -488,7 +488,8 @@ to the original request (normal or error) are ignored." ,@(when (plist-member args :timeout) `(:timeout ,timeout))))) (cond (cancel-on-input (unwind-protect - (let ((inhibit-quit t)) (while (sit-for 30))) + (let ((inhibit-quit t) (inhibit-redisplay t)) + (while (sit-for 30 t))) (setq canceled t)) (when (functionp cancel-on-input) (funcall cancel-on-input (car id-and-timer)))