From unknown Sun Jun 15 08:26:38 2025 Content-Disposition: inline Content-Transfer-Encoding: quoted-printable MIME-Version: 1.0 X-Mailer: MIME-tools 5.509 (Entity 5.509) Content-Type: text/plain; charset=utf-8 From: bug#77658 <77658@debbugs.gnu.org> To: bug#77658 <77658@debbugs.gnu.org> Subject: Status: 30.1.50; Eglot: wrong-type-argument: consp, # when saving Reply-To: bug#77658 <77658@debbugs.gnu.org> Date: Sun, 15 Jun 2025 15:26:38 +0000 retitle 77658 30.1.50; Eglot: wrong-type-argument: consp, # when saving reassign 77658 emacs submitter 77658 Aaron Zeng severity 77658 normal thanks From debbugs-submit-bounces@debbugs.gnu.org Tue Apr 08 18:05:57 2025 Received: (at submit) by debbugs.gnu.org; 8 Apr 2025 22:05:57 +0000 Received: from localhost ([127.0.0.1]:35905 helo=debbugs.gnu.org) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1u2H4s-0001Ww-Fr for submit@debbugs.gnu.org; Tue, 08 Apr 2025 18:05:57 -0400 Received: from lists.gnu.org ([2001:470:142::17]:42886) by debbugs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.84_2) (envelope-from ) id 1u2H4m-0001WP-ID for submit@debbugs.gnu.org; Tue, 08 Apr 2025 18:05:52 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1u2H4b-0008GD-5c for bug-gnu-emacs@gnu.org; Tue, 08 Apr 2025 18:05:37 -0400 Received: from mxout5.mail.janestreet.com ([64.215.233.18]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1u2H4V-0000mM-MF for bug-gnu-emacs@gnu.org; Tue, 08 Apr 2025 18:05:36 -0400 From: Aaron Zeng To: bug-gnu-emacs@gnu.org Subject: 30.1.50; Eglot: wrong-type-argument: consp, # when saving X-Debbugs-Cc: Date: Tue, 08 Apr 2025 18:05:27 -0400 Message-ID: MIME-Version: 1.0 Content-Type: text/plain Content-Transfer-Encoding: quoted-printable DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=janestreet.com; s=waixah; t=1744149928; bh=xdMm4RA0hjBT7c+3tteNbrDRaCcGI6FygC/dCrQJhuA=; h=From:To:Cc:Subject:Date; b=cINbmyL2GyOucAXLSQsRY/u8uPWQSfHTjkVAC8lSpIz9ofdt4m/NASOvYlsKWo2au TGrfPmPxpLdtHCh+twq/VhMs+yZFkwyqp7vgBQHNA3rjv+VN+ZY317a9yROd+xJ9RB Co6XJZTE6fdRfNbSA/O/h+RvniA6qki0jE7xL077GpfXOBlPQEtcf0puHjTK4sHzUR ILJ+viwW2Muhlk/kfg8zTab9YBFHKknoN8vThyGyG3E1vCkJEFoDA+ddObR1gbXOFi NZ4lojcqCYKaqIQddL0R+3ORpFokewvVerpFf//jfruRNh71R3WmMPuNnnN4KZa8g4 0j0zWMEwTYw0A== Received-SPF: pass client-ip=64.215.233.18; envelope-from=azeng@janestreet.com; helo=mxout5.mail.janestreet.com X-Spam_score_int: -43 X-Spam_score: -4.4 X-Spam_bar: ---- X-Spam_report: (-4.4 / 5.0 requ) BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, RCVD_IN_DNSWL_MED=-2.3, RCVD_IN_MSPIKE_H2=0.001, RCVD_IN_VALIDITY_CERTIFIED_BLOCKED=0.001, RCVD_IN_VALIDITY_RPBL_BLOCKED=0.001, SPF_HELO_PASS=-0.001, SPF_PASS=-0.001 autolearn=ham autolearn_force=no X-Spam_action: no action X-Spam-Score: 0.9 (/) X-Debbugs-Envelope-To: submit Cc: app-emacs-dev@janestreet.com X-BeenThere: debbugs-submit@debbugs.gnu.org X-Mailman-Version: 2.1.18 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: debbugs-submit-bounces@debbugs.gnu.org Sender: "Debbugs-submit" X-Spam-Score: -0.1 (/) When saving an empty buffer, and while `before-save-hook` has some function= for reformatting the buffer (such as an auto-styler), the following error = is issued: ``` Error running timer: (wrong-type-argument consp #>) ``` This error can also happen synchronously in `basic-save-buffer` rather than= in a timer. Reproduction recipe: With `~/src/emacs/trunk` checked out to `9663c959c73d6cca0c56f833d80ff1d9e9= 708b70`: 1. emacs -Q -l ~/src/emacs/trunk/lisp/progmodes/eglot.el 2. Evaluate the following code: ```emacs-lisp (add-hook 'before-save-hook #'no-op-file-formatter) (defun no-op-file-formatter () (let ((temp-file (make-temp-file "no-op-file-formatter"))) (save-restriction (widen) (write-region nil nil temp-file) (insert-file-contents temp-file nil nil nil 'replace)))) ``` This adds a dummy "reformatter" to `before-save-hook` that is always a no-o= p. 3. `C-x C-f /tmp/z.c` 4. `M-x eglot` (clangd must be installed, I suppose) 5. Make some trivial edits, then `C-x h DEL` to erase the buffer contents 6. `C-x C-s` An error is issued as described above. Also, since `eglot--recent-changes`= now includes a malformatted entry, random other things break, too, for exa= mple just inserting a space character. Backtrace included below. I believe what is happening here, is that `insert-file-contents`, when inse= rting an empty file into an empty buffer (maybe in other situations as well= ), may cause `before-change-functions` to be run but `after-change-function= s` never runs. Therefore, `eglot--before-changes` inserts an element into = `eglot--recent-changes` that `eglot--after-changes` never gets a chance to = fix up. According to the manual (https://www.gnu.org/software/emacs/manual/html_nod= e/elisp/Change-Hooks.html), this is allowed to happen (i.e., `after-change-= functions` might not always run after a change). Backtrace for eglot--post-self-insert-hook: ``` Debugger entered--Lisp error: (wrong-type-argument consp #) json-serialize((:jsonrpc "2.0" :method "textDocument/didChange" :params (= :textDocument (:uri "file:///tmp/z.c" :version 8) :contentChanges [(:range = (:start (:line 0 :character 0) :end (:line 0 :character 0)) :rangeLength (1= . #) :text (1 . #)) (:range (:start (:line 0 :character 0) :end (:line 0 :character 0= )) :rangeLength 0 :text " ") (:range (:start (:line 0 :character 1) :end (:= line 0 :character 1)) :rangeLength 0 :text "\n") (:range (:start (:line 0 := character 0) :end (:line 0 :character 1)) :rangeLength 1 :text "") (:range = (:start (:line 0 :character 0) :end (:line 0 :character 0)) :rangeLength 0 = :text "\n") (:range (:start (:line 1 :character 0) :end (:line 1 :character= 0)) :rangeLength 0 :text "\n") (:range (:start (:line 1 :character 0) :end= (:line 2 :character 0)) :rangeLength 1 :text "") (:range (:start (:line 0 = :character 0) :end (:line 1 :character 0)) :rangeLength 1 :text "") (:range= (:start (:line 0 :character 0) :end (:line 0 :character 0)) :rangeLength 0= :text "\n")])) :false-object :json-false :null-object nil) jsonrpc--json-encode((:jsonrpc "2.0" :method "textDocument/didChange" :pa= rams (:textDocument (:uri "file:///tmp/z.c" :version 8) :contentChanges [(:= range (:start (:line 0 :character 0) :end (:line 0 :character 0)) :rangeLen= gth (1 . #) :text (1 . #)) (:range (:start (:line 0 :character 0) :end (:line 0 :chara= cter 0)) :rangeLength 0 :text " ") (:range (:start (:line 0 :character 1) := end (:line 0 :character 1)) :rangeLength 0 :text "\n") (:range (:start (:li= ne 0 :character 0) :end (:line 0 :character 1)) :rangeLength 1 :text "") (:= range (:start (:line 0 :character 0) :end (:line 0 :character 0)) :rangeLen= gth 0 :text "\n") (:range (:start (:line 1 :character 0) :end (:line 1 :cha= racter 0)) :rangeLength 0 :text "\n") (:range (:start (:line 1 :character 0= ) :end (:line 2 :character 0)) :rangeLength 1 :text "") (:range (:start (:l= ine 0 :character 0) :end (:line 1 :character 0)) :rangeLength 1 :text "") (= :range (:start (:line 0 :character 0) :end (:line 0 :character 0)) :rangeLe= ngth 0 :text "\n")]))) #f(compiled-function (arg1 &rest rest) "Send MESSAGE, a JSON object, to C= ONNECTION." #)(# :method :textDocument/didChange :params (:textDocument (:uri= "file:///tmp/z.c" :version 8) :contentChanges [(:range (:start (:line 0 :c= haracter 0) :end (:line 0 :character 0)) :rangeLength (1 . #) :text (1 . #)) (:range (= :start (:line 0 :character 0) :end (:line 0 :character 0)) :rangeLength 0 := text " ") (:range (:start (:line 0 :character 1) :end (:line 0 :character 1= )) :rangeLength 0 :text "\n") (:range (:start (:line 0 :character 0) :end (= :line 0 :character 1)) :rangeLength 1 :text "") (:range (:start (:line 0 :c= haracter 0) :end (:line 0 :character 0)) :rangeLength 0 :text "\n") (:range= (:start (:line 1 :character 0) :end (:line 1 :character 0)) :rangeLength 0= :text "\n") (:range (:start (:line 1 :character 0) :end (:line 2 :characte= r 0)) :rangeLength 1 :text "") (:range (:start (:line 0 :character 0) :end = (:line 1 :character 0)) :rangeLength 1 :text "") (:range (:start (:line 0 := character 0) :end (:line 0 :character 0)) :rangeLength 0 :text "\n")])) apply(#f(compiled-function (arg1 &rest rest) "Send MESSAGE, a JSON object= , to CONNECTION." #) # (:method :textDocument/didChange :params (:textDocumen= t (:uri "file:///tmp/z.c" :version 8) :contentChanges [(:range (:start (:li= ne 0 :character 0) :end (:line 0 :character 0)) :rangeLength (1 . #) :text (1 . #)) (:= range (:start (:line 0 :character 0) :end (:line 0 :character 0)) :rangeLen= gth 0 :text " ") (:range (:start (:line 0 :character 1) :end (:line 0 :char= acter 1)) :rangeLength 0 :text "\n") (:range (:start (:line 0 :character 0)= :end (:line 0 :character 1)) :rangeLength 1 :text "") (:range (:start (:li= ne 0 :character 0) :end (:line 0 :character 0)) :rangeLength 0 :text "\n") = (:range (:start (:line 1 :character 0) :end (:line 1 :character 0)) :rangeL= ength 0 :text "\n") (:range (:start (:line 1 :character 0) :end (:line 2 :c= haracter 0)) :rangeLength 1 :text "") (:range (:start (:line 0 :character 0= ) :end (:line 1 :character 0)) :rangeLength 1 :text "") (:range (:start (:l= ine 0 :character 0) :end (:line 0 :character 0)) :rangeLength 0 :text "\n")= ]))) jsonrpc-connection-send(# :met= hod :textDocument/didChange :params (:textDocument (:uri "file:///tmp/z.c" = :version 8) :contentChanges [(:range (:start (:line 0 :character 0) :end (:= line 0 :character 0)) :rangeLength (1 . #) :text (1 . #= )) (:range (:start (:line 0 :ch= aracter 0) :end (:line 0 :character 0)) :rangeLength 0 :text " ") (:range (= :start (:line 0 :character 1) :end (:line 0 :character 1)) :rangeLength 0 := text "\n") (:range (:start (:line 0 :character 0) :end (:line 0 :character = 1)) :rangeLength 1 :text "") (:range (:start (:line 0 :character 0) :end (:= line 0 :character 0)) :rangeLength 0 :text "\n") (:range (:start (:line 1 := character 0) :end (:line 1 :character 0)) :rangeLength 0 :text "\n") (:rang= e (:start (:line 1 :character 0) :end (:line 2 :character 0)) :rangeLength = 1 :text "") (:range (:start (:line 0 :character 0) :end (:line 1 :character= 0)) :rangeLength 1 :text "") (:range (:start (:line 0 :character 0) :end (= :line 0 :character 0)) :rangeLength 0 :text "\n")])) jsonrpc-notify(# :textDocument= /didChange (:textDocument (:uri "file:///tmp/z.c" :version 8) :contentChang= es [(:range (:start (:line 0 :character 0) :end (:line 0 :character 0)) :ra= ngeLength (1 . #) :text (1 . #)) (:range (:start (:line 0 :character 0) :end (:line 0 = :character 0)) :rangeLength 0 :text " ") (:range (:start (:line 0 :characte= r 1) :end (:line 0 :character 1)) :rangeLength 0 :text "\n") (:range (:star= t (:line 0 :character 0) :end (:line 0 :character 1)) :rangeLength 1 :text = "") (:range (:start (:line 0 :character 0) :end (:line 0 :character 0)) :ra= ngeLength 0 :text "\n") (:range (:start (:line 1 :character 0) :end (:line = 1 :character 0)) :rangeLength 0 :text "\n") (:range (:start (:line 1 :chara= cter 0) :end (:line 2 :character 0)) :rangeLength 1 :text "") (:range (:sta= rt (:line 0 :character 0) :end (:line 1 :character 0)) :rangeLength 1 :text= "") (:range (:start (:line 0 :character 0) :end (:line 0 :character 0)) :r= angeLength 0 :text "\n")])) (let* ((server (eglot--current-server-or-lose)) (sync-capability (eglot-s= erver-capable :textDocumentSync)) (sync-kind (if (numberp sync-capability) = sync-capability (plist-get sync-capability :change))) (full-sync-p (or (eq = sync-kind 1) (eq :emacs-messup eglot--recent-changes)))) (jsonrpc-notify se= rver :textDocument/didChange (list :textDocument (eglot--VersionedTextDocum= entIdentifier) :contentChanges (if full-sync-p (vector (list ':text (save-e= xcursion (save-restriction ... ...)))) (let* ((--cl-var-- (reverse eglot--r= ecent-changes)) (beg nil) (end nil) (len nil) (text nil) (--cl-var--) (--cl= -var-- [])) (while (consp --cl-var--) (progn (setq --cl-var-- ...) (setq be= g ...) (setq end ...) (setq len ...) (setq text ...)) (setq --cl-var-- (vco= ncat --cl-var-- ...)) (setq --cl-var-- (cdr --cl-var--))) --cl-var--)))) (s= etq eglot--recent-changes nil) (jsonrpc--call-deferred server)) (progn (let* ((server (eglot--current-server-or-lose)) (sync-capability (= eglot-server-capable :textDocumentSync)) (sync-kind (if (numberp sync-capab= ility) sync-capability (plist-get sync-capability :change))) (full-sync-p (= or (eq sync-kind 1) (eq :emacs-messup eglot--recent-changes)))) (jsonrpc-no= tify server :textDocument/didChange (list :textDocument (eglot--VersionedTe= xtDocumentIdentifier) :contentChanges (if full-sync-p (vector (list ':text = (save-excursion ...))) (let* ((--cl-var-- ...) (beg nil) (end nil) (len nil= ) (text nil) (--cl-var--) (--cl-var-- ...)) (while (consp --cl-var--) (prog= n ... ... ... ... ...) (setq --cl-var-- ...) (setq --cl-var-- ...)) --cl-va= r--)))) (setq eglot--recent-changes nil) (jsonrpc--call-deferred server))) (if eglot--recent-changes (progn (let* ((server (eglot--current-server-or= -lose)) (sync-capability (eglot-server-capable :textDocumentSync)) (sync-ki= nd (if (numberp sync-capability) sync-capability (plist-get sync-capability= :change))) (full-sync-p (or (eq sync-kind 1) (eq :emacs-messup eglot--rece= nt-changes)))) (jsonrpc-notify server :textDocument/didChange (list :textDo= cument (eglot--VersionedTextDocumentIdentifier) :contentChanges (if full-sy= nc-p (vector (list ... ...)) (let* (... ... ... ... ... ... ...) (while ...= ... ... ...) --cl-var--)))) (setq eglot--recent-changes nil) (jsonrpc--cal= l-deferred server)))) eglot--signal-textDocument/didChange() (if immediate nil (eglot--signal-textDocument/didChange)) (progn (if immediate nil (eglot--signal-textDocument/didChange)) (jsonrpc= -request server method params :timeout timeout :cancel-on-input (cond ((and= cancel-on-input eglot-advertise-cancellation) #'(lambda (id) (jsonrpc-noti= fy server '$/cancelRequest (list ... id)))) (cancel-on-input)) :cancel-on-i= nput-retval cancel-on-input-retval)) (progn (let ((--cl-keys-- --cl-rest--)) (while --cl-keys-- (cond ((memq (= car --cl-keys--) '(:immediate :timeout :cancel-on-input :cancel-on-input-re= tval :allow-other-keys)) (if (cdr --cl-keys--) nil (error "Missing argument= for %s" (car --cl-keys--))) (setq --cl-keys-- (cdr (cdr --cl-keys--)))) ((= car (cdr (memq ... --cl-rest--))) (setq --cl-keys-- nil)) (t (error "Keywor= d argument %s not one of (:immediate :timeout :cancel-on-input :cancel-on-i= nput-retval)" (car --cl-keys--)))))) (progn (if immediate nil (eglot--signa= l-textDocument/didChange)) (jsonrpc-request server method params :timeout t= imeout :cancel-on-input (cond ((and cancel-on-input eglot-advertise-cancell= ation) #'(lambda (id) (jsonrpc-notify server ... ...))) (cancel-on-input)) = :cancel-on-input-retval cancel-on-input-retval))) (let* ((immediate (car (cdr (plist-member --cl-rest-- ':immediate)))) (ti= meout (car (cdr (plist-member --cl-rest-- ':timeout)))) (cancel-on-input (c= ar (cdr (plist-member --cl-rest-- ':cancel-on-input)))) (cancel-on-input-re= tval (car (cdr (plist-member --cl-rest-- ':cancel-on-input-retval))))) (pro= gn (let ((--cl-keys-- --cl-rest--)) (while --cl-keys-- (cond ((memq (car --= cl-keys--) '...) (if (cdr --cl-keys--) nil (error "Missing argument for %s"= ...)) (setq --cl-keys-- (cdr ...))) ((car (cdr ...)) (setq --cl-keys-- nil= )) (t (error "Keyword argument %s not one of (:immediate :timeout :cancel-o= n-input :cancel-on-input-retval)" (car --cl-keys--)))))) (progn (if immedia= te nil (eglot--signal-textDocument/didChange)) (jsonrpc-request server meth= od params :timeout timeout :cancel-on-input (cond ((and cancel-on-input egl= ot-advertise-cancellation) #'(lambda ... ...)) (cancel-on-input)) :cancel-o= n-input-retval cancel-on-input-retval)))) eglot--request(# :textDocument= /onTypeFormatting (:textDocument (:uri "file:///tmp/z.c") :options (:tabSiz= e 8 :insertSpaces :json-false :insertFinalNewline t :trimFinalNewlines t) := position (:line 1 :character 0) :ch "\n")) (eglot--apply-text-edits (eglot--request (eglot--current-server-or-lose) = method (cons :textDocument (cons (eglot--TextDocumentIdentifier) (cons :opt= ions (cons (list :tabSize tab-width :insertSpaces (if indent-tabs-mode :jso= n-false t) :insertFinalNewline (if require-final-newline t :json-false) :tr= imFinalNewlines (if delete-trailing-lines t :json-false)) args))))) nil on-= type-format) (progn (eglot-server-capable-or-lose cap) (eglot--apply-text-edits (eglot= --request (eglot--current-server-or-lose) method (cons :textDocument (cons = (eglot--TextDocumentIdentifier) (cons :options (cons (list :tabSize tab-wid= th :insertSpaces ... :insertFinalNewline ... :trimFinalNewlines ...) args))= ))) nil on-type-format)) (let ((method x37) (cap x39) (args x41)) (progn (eglot-server-capable-or-= lose cap) (eglot--apply-text-edits (eglot--request (eglot--current-server-o= r-lose) method (cons :textDocument (cons (eglot--TextDocumentIdentifier) (c= ons :options (cons ... args))))) nil on-type-format))) (progn (ignore (null x42)) (let ((method x37) (cap x39) (args x41)) (prog= n (eglot-server-capable-or-lose cap) (eglot--apply-text-edits (eglot--reque= st (eglot--current-server-or-lose) method (cons :textDocument (cons (eglot-= -TextDocumentIdentifier) (cons :options ...)))) nil on-type-format)))) (let* ((x41 (car-safe x40)) (x42 (cdr-safe x40))) (progn (ignore (null x4= 2)) (let ((method x37) (cap x39) (args x41)) (progn (eglot-server-capable-o= r-lose cap) (eglot--apply-text-edits (eglot--request (eglot--current-server= -or-lose) method (cons :textDocument (cons ... ...))) nil on-type-format)))= )) (progn (ignore (consp x40)) (let* ((x41 (car-safe x40)) (x42 (cdr-safe x4= 0))) (progn (ignore (null x42)) (let ((method x37) (cap x39) (args x41)) (p= rogn (eglot-server-capable-or-lose cap) (eglot--apply-text-edits (eglot--re= quest (eglot--current-server-or-lose) method (cons :textDocument ...)) nil = on-type-format)))))) (let* ((x39 (car-safe x38)) (x40 (cdr-safe x38))) (progn (ignore (consp x= 40)) (let* ((x41 (car-safe x40)) (x42 (cdr-safe x40))) (progn (ignore (null= x42)) (let ((method x37) (cap x39) (args x41)) (progn (eglot-server-capabl= e-or-lose cap) (eglot--apply-text-edits (eglot--request ... method ...) nil= on-type-format))))))) (progn (ignore (consp x38)) (let* ((x39 (car-safe x38)) (x40 (cdr-safe x3= 8))) (progn (ignore (consp x40)) (let* ((x41 (car-safe x40)) (x42 (cdr-safe= x40))) (progn (ignore (null x42)) (let ((method x37) (cap x39) (args x41))= (progn (eglot-server-capable-or-lose cap) (eglot--apply-text-edits ... nil= on-type-format)))))))) (let* ((x37 (car-safe val)) (x38 (cdr-safe val))) (progn (ignore (consp x= 38)) (let* ((x39 (car-safe x38)) (x40 (cdr-safe x38))) (progn (ignore (cons= p x40)) (let* ((x41 (car-safe x40)) (x42 (cdr-safe x40))) (progn (ignore (n= ull x42)) (let (... ... ...) (progn ... ...)))))))) (progn (ignore (consp val)) (let* ((x37 (car-safe val)) (x38 (cdr-safe va= l))) (progn (ignore (consp x38)) (let* ((x39 (car-safe x38)) (x40 (cdr-safe= x38))) (progn (ignore (consp x40)) (let* ((x41 ...) (x42 ...)) (progn (ign= ore ...) (let ... ...)))))))) (let* ((val (cond ((and beg on-type-format) (list ':textDocument/onTypeFo= rmatting ':documentOnTypeFormattingProvider (list ':position (eglot--pos-to= -lsp-position beg) ':ch (string on-type-format)))) ((and beg end) (list ':t= extDocument/rangeFormatting ':documentRangeFormattingProvider (list ':range= (list :start ... :end ...)))) (t '(:textDocument/formatting :documentForma= ttingProvider nil))))) (progn (ignore (consp val)) (let* ((x37 (car-safe va= l)) (x38 (cdr-safe val))) (progn (ignore (consp x38)) (let* ((x39 (car-safe= x38)) (x40 (cdr-safe x38))) (progn (ignore (consp x40)) (let* (... ...) (p= rogn ... ...)))))))) eglot-format(2 nil 10) (progn (eglot-format (point) nil eglot--last-inserted-char)) (if (and ot-provider (condition-case nil (progn (or (eq eglot--last-inser= ted-char (seq-first (plist-get ot-provider :firstTriggerCharacter))) (cl-fi= nd eglot--last-inserted-char (plist-get ot-provider :moreTriggerCharacter) = :key #'seq-first))) (error nil))) (progn (eglot-format (point) nil eglot--l= ast-inserted-char))) (let ((ot-provider (eglot-server-capable :documentOnTypeFormattingProvide= r))) (if (and ot-provider (condition-case nil (progn (or (eq eglot--last-in= serted-char (seq-first ...)) (cl-find eglot--last-inserted-char (plist-get = ot-provider :moreTriggerCharacter) :key #'seq-first))) (error nil))) (progn= (eglot-format (point) nil eglot--last-inserted-char)))) eglot--post-self-insert-hook() newline(nil 1) funcall-interactively(newline nil 1) command-execute(newline) ``` In GNU Emacs 30.1.50 (build 2, x86_64-pc-linux-gnu, X toolkit, cairo version 1.15.12, Xaw scroll bars) of 2025-03-28 built on igm-qws-u22796a Repository revision: 3e6424e1f1816332e574035bc73143551a69efb6 Windowing system distributor 'The X.Org Foundation', version 11.0.12011000 System Description: Rocky Linux 8.10 (Green Obsidian) Configured using: 'configure --config-cache --with-x-toolkit=3Dlucid --without-gpm --without-gconf --without-selinux --without-imagemagick --with-modules --with-gif=3Dno --with-cairo --with-rsvg --without-compress-install --with-tree-sitter --with-native-compilation=3Daot --prefix=3D/usr/local/home/garnish/raw-emacs/30-20250328_130425' Configured features: CAIRO DBUS FREETYPE GLIB GMP GNUTLS GSETTINGS HARFBUZZ JPEG LIBSYSTEMD LIBXML2 MODULES NATIVE_COMP NOTIFY INOTIFY PDUMPER PNG RSVG SECCOMP SOUND SQLITE3 THREADS TIFF TOOLKIT_SCROLL_BARS TREE_SITTER X11 XDBE XIM XINPUT2 XPM LUCID ZLIB Important settings: value of $LANG: en_US.utf8 locale-coding-system: utf-8-unix Major mode: Fundamental Minor modes in effect: delete-selection-mode: t jane-fe-minor-mode: t dired-omit-mode: t editorconfig-mode: t mode-line-bell-mode: t tooltip-mode: t global-eldoc-mode: t show-paren-mode: t electric-indent-mode: t mouse-wheel-mode: t tool-bar-mode: t menu-bar-mode: t file-name-shadow-mode: t context-menu-mode: t global-font-lock-mode: t blink-cursor-mode: t minibuffer-regexp-mode: t buffer-read-only: t line-number-mode: t transient-mark-mode: t auto-composition-mode: t auto-encryption-mode: t auto-compression-mode: t Load-path shadows: /usr/local/home/azeng/workspaces/24833141-bffb-3c99-a9d6-c366d37c4f5e/+shar= e+/app/emacs/site-lisp/elpa/helm-4.0.2/helm-x-icons hides /usr/local/home/a= zeng/workspaces/24833141-bffb-3c99-a9d6-c366d37c4f5e/+share+/app/emacs/site= -lisp/elpa/helm-core-4.0.2/helm-x-icons /usr/local/home/azeng/workspaces/24833141-bffb-3c99-a9d6-c366d37c4f5e/+shar= e+/app/emacs/site-lisp/elpa/helm-4.0.2/helm-packages hides /usr/local/home/= azeng/workspaces/24833141-bffb-3c99-a9d6-c366d37c4f5e/+share+/app/emacs/sit= e-lisp/elpa/helm-core-4.0.2/helm-packages /usr/local/home/azeng/workspaces/24833141-bffb-3c99-a9d6-c366d37c4f5e/+shar= e+/app/emacs/site-lisp/elpa/magit-4.3.1/magit-autorevert hides /usr/local/h= ome/azeng/workspaces/24833141-bffb-3c99-a9d6-c366d37c4f5e/+share+/app/emacs= /site-lisp/elpa/magit-section-4.3.1/magit-autorevert /usr/local/home/azeng/workspaces/24833141-bffb-3c99-a9d6-c366d37c4f5e/+shar= e+/app/emacs/site-lisp/elpa/transient-0.8.6/transient hides /usr/local/home= /garnish/raw-emacs/30-20250328_130425/share/emacs/30.1.50/lisp/transient /usr/local/home/azeng/workspaces/24833141-bffb-3c99-a9d6-c366d37c4f5e/+shar= e+/app/emacs/site-lisp/elpa/eglot-1.18/eglot hides /usr/local/home/garnish/= raw-emacs/30-20250328_130425/share/emacs/30.1.50/lisp/progmodes/eglot /usr/local/home/azeng/workspaces/24833141-bffb-3c99-a9d6-c366d37c4f5e/+shar= e+/app/emacs/site-lisp/elpa/org-9.7.27/ox hides /usr/local/home/garnish/raw= -emacs/30-20250328_130425/share/emacs/30.1.50/lisp/org/ox /usr/local/home/azeng/workspaces/24833141-bffb-3c99-a9d6-c366d37c4f5e/+shar= e+/app/emacs/site-lisp/elpa/org-9.7.27/ox-texinfo hides /usr/local/home/gar= nish/raw-emacs/30-20250328_130425/share/emacs/30.1.50/lisp/org/ox-texinfo /usr/local/home/azeng/workspaces/24833141-bffb-3c99-a9d6-c366d37c4f5e/+shar= e+/app/emacs/site-lisp/elpa/org-9.7.27/ox-publish hides /usr/local/home/gar= nish/raw-emacs/30-20250328_130425/share/emacs/30.1.50/lisp/org/ox-publish /usr/local/home/azeng/workspaces/24833141-bffb-3c99-a9d6-c366d37c4f5e/+shar= e+/app/emacs/site-lisp/elpa/org-9.7.27/ox-org hides /usr/local/home/garnish= /raw-emacs/30-20250328_130425/share/emacs/30.1.50/lisp/org/ox-org /usr/local/home/azeng/workspaces/24833141-bffb-3c99-a9d6-c366d37c4f5e/+shar= e+/app/emacs/site-lisp/elpa/org-9.7.27/ox-odt hides /usr/local/home/garnish= /raw-emacs/30-20250328_130425/share/emacs/30.1.50/lisp/org/ox-odt /usr/local/home/azeng/workspaces/24833141-bffb-3c99-a9d6-c366d37c4f5e/+shar= e+/app/emacs/site-lisp/elpa/org-9.7.27/ox-md hides /usr/local/home/garnish/= raw-emacs/30-20250328_130425/share/emacs/30.1.50/lisp/org/ox-md /usr/local/home/azeng/workspaces/24833141-bffb-3c99-a9d6-c366d37c4f5e/+shar= e+/app/emacs/site-lisp/elpa/org-9.7.27/ox-man hides /usr/local/home/garnish= /raw-emacs/30-20250328_130425/share/emacs/30.1.50/lisp/org/ox-man /usr/local/home/azeng/workspaces/24833141-bffb-3c99-a9d6-c366d37c4f5e/+shar= e+/app/emacs/site-lisp/elpa/org-9.7.27/ox-latex hides /usr/local/home/garni= sh/raw-emacs/30-20250328_130425/share/emacs/30.1.50/lisp/org/ox-latex /usr/local/home/azeng/workspaces/24833141-bffb-3c99-a9d6-c366d37c4f5e/+shar= e+/app/emacs/site-lisp/elpa/org-9.7.27/ox-koma-letter hides /usr/local/home= /garnish/raw-emacs/30-20250328_130425/share/emacs/30.1.50/lisp/org/ox-koma-= letter /usr/local/home/azeng/workspaces/24833141-bffb-3c99-a9d6-c366d37c4f5e/+shar= e+/app/emacs/site-lisp/elpa/org-9.7.27/ox-icalendar hides /usr/local/home/g= arnish/raw-emacs/30-20250328_130425/share/emacs/30.1.50/lisp/org/ox-icalend= ar /usr/local/home/azeng/workspaces/24833141-bffb-3c99-a9d6-c366d37c4f5e/+shar= e+/app/emacs/site-lisp/elpa/org-9.7.27/ox-html hides /usr/local/home/garnis= h/raw-emacs/30-20250328_130425/share/emacs/30.1.50/lisp/org/ox-html /usr/local/home/azeng/workspaces/24833141-bffb-3c99-a9d6-c366d37c4f5e/+shar= e+/app/emacs/site-lisp/elpa/org-9.7.27/ox-beamer hides /usr/local/home/garn= ish/raw-emacs/30-20250328_130425/share/emacs/30.1.50/lisp/org/ox-beamer /usr/local/home/azeng/workspaces/24833141-bffb-3c99-a9d6-c366d37c4f5e/+shar= e+/app/emacs/site-lisp/elpa/org-9.7.27/ox-ascii hides /usr/local/home/garni= sh/raw-emacs/30-20250328_130425/share/emacs/30.1.50/lisp/org/ox-ascii /usr/local/home/azeng/workspaces/24833141-bffb-3c99-a9d6-c366d37c4f5e/+shar= e+/app/emacs/site-lisp/elpa/org-9.7.27/org hides /usr/local/home/garnish/ra= w-emacs/30-20250328_130425/share/emacs/30.1.50/lisp/org/org /usr/local/home/azeng/workspaces/24833141-bffb-3c99-a9d6-c366d37c4f5e/+shar= e+/app/emacs/site-lisp/elpa/org-9.7.27/org-version hides /usr/local/home/ga= rnish/raw-emacs/30-20250328_130425/share/emacs/30.1.50/lisp/org/org-version /usr/local/home/azeng/workspaces/24833141-bffb-3c99-a9d6-c366d37c4f5e/+shar= e+/app/emacs/site-lisp/elpa/org-9.7.27/org-timer hides /usr/local/home/garn= ish/raw-emacs/30-20250328_130425/share/emacs/30.1.50/lisp/org/org-timer /usr/local/home/azeng/workspaces/24833141-bffb-3c99-a9d6-c366d37c4f5e/+shar= e+/app/emacs/site-lisp/elpa/org-9.7.27/org-tempo hides /usr/local/home/garn= ish/raw-emacs/30-20250328_130425/share/emacs/30.1.50/lisp/org/org-tempo /usr/local/home/azeng/workspaces/24833141-bffb-3c99-a9d6-c366d37c4f5e/+shar= e+/app/emacs/site-lisp/elpa/org-9.7.27/org-table hides /usr/local/home/garn= ish/raw-emacs/30-20250328_130425/share/emacs/30.1.50/lisp/org/org-table /usr/local/home/azeng/workspaces/24833141-bffb-3c99-a9d6-c366d37c4f5e/+shar= e+/app/emacs/site-lisp/elpa/org-9.7.27/org-src hides /usr/local/home/garnis= h/raw-emacs/30-20250328_130425/share/emacs/30.1.50/lisp/org/org-src /usr/local/home/azeng/workspaces/24833141-bffb-3c99-a9d6-c366d37c4f5e/+shar= e+/app/emacs/site-lisp/elpa/org-9.7.27/org-refile hides /usr/local/home/gar= nish/raw-emacs/30-20250328_130425/share/emacs/30.1.50/lisp/org/org-refile /usr/local/home/azeng/workspaces/24833141-bffb-3c99-a9d6-c366d37c4f5e/+shar= e+/app/emacs/site-lisp/elpa/org-9.7.27/org-protocol hides /usr/local/home/g= arnish/raw-emacs/30-20250328_130425/share/emacs/30.1.50/lisp/org/org-protoc= ol /usr/local/home/azeng/workspaces/24833141-bffb-3c99-a9d6-c366d37c4f5e/+shar= e+/app/emacs/site-lisp/elpa/org-9.7.27/org-plot hides /usr/local/home/garni= sh/raw-emacs/30-20250328_130425/share/emacs/30.1.50/lisp/org/org-plot /usr/local/home/azeng/workspaces/24833141-bffb-3c99-a9d6-c366d37c4f5e/+shar= e+/app/emacs/site-lisp/elpa/org-9.7.27/org-persist hides /usr/local/home/ga= rnish/raw-emacs/30-20250328_130425/share/emacs/30.1.50/lisp/org/org-persist /usr/local/home/azeng/workspaces/24833141-bffb-3c99-a9d6-c366d37c4f5e/+shar= e+/app/emacs/site-lisp/elpa/org-9.7.27/org-pcomplete hides /usr/local/home/= garnish/raw-emacs/30-20250328_130425/share/emacs/30.1.50/lisp/org/org-pcomp= lete /usr/local/home/azeng/workspaces/24833141-bffb-3c99-a9d6-c366d37c4f5e/+shar= e+/app/emacs/site-lisp/elpa/org-9.7.27/org-num hides /usr/local/home/garnis= h/raw-emacs/30-20250328_130425/share/emacs/30.1.50/lisp/org/org-num /usr/local/home/azeng/workspaces/24833141-bffb-3c99-a9d6-c366d37c4f5e/+shar= e+/app/emacs/site-lisp/elpa/org-9.7.27/org-mouse hides /usr/local/home/garn= ish/raw-emacs/30-20250328_130425/share/emacs/30.1.50/lisp/org/org-mouse /usr/local/home/azeng/workspaces/24833141-bffb-3c99-a9d6-c366d37c4f5e/+shar= e+/app/emacs/site-lisp/elpa/org-9.7.27/org-mobile hides /usr/local/home/gar= nish/raw-emacs/30-20250328_130425/share/emacs/30.1.50/lisp/org/org-mobile /usr/local/home/azeng/workspaces/24833141-bffb-3c99-a9d6-c366d37c4f5e/+shar= e+/app/emacs/site-lisp/elpa/org-9.7.27/org-macs hides /usr/local/home/garni= sh/raw-emacs/30-20250328_130425/share/emacs/30.1.50/lisp/org/org-macs /usr/local/home/azeng/workspaces/24833141-bffb-3c99-a9d6-c366d37c4f5e/+shar= e+/app/emacs/site-lisp/elpa/org-9.7.27/org-macro hides /usr/local/home/garn= ish/raw-emacs/30-20250328_130425/share/emacs/30.1.50/lisp/org/org-macro /usr/local/home/azeng/workspaces/24833141-bffb-3c99-a9d6-c366d37c4f5e/+shar= e+/app/emacs/site-lisp/elpa/org-9.7.27/org-loaddefs hides /usr/local/home/g= arnish/raw-emacs/30-20250328_130425/share/emacs/30.1.50/lisp/org/org-loadde= fs /usr/local/home/azeng/workspaces/24833141-bffb-3c99-a9d6-c366d37c4f5e/+shar= e+/app/emacs/site-lisp/elpa/org-9.7.27/org-list hides /usr/local/home/garni= sh/raw-emacs/30-20250328_130425/share/emacs/30.1.50/lisp/org/org-list /usr/local/home/azeng/workspaces/24833141-bffb-3c99-a9d6-c366d37c4f5e/+shar= e+/app/emacs/site-lisp/elpa/org-9.7.27/org-lint hides /usr/local/home/garni= sh/raw-emacs/30-20250328_130425/share/emacs/30.1.50/lisp/org/org-lint /usr/local/home/azeng/workspaces/24833141-bffb-3c99-a9d6-c366d37c4f5e/+shar= e+/app/emacs/site-lisp/elpa/org-9.7.27/org-keys hides /usr/local/home/garni= sh/raw-emacs/30-20250328_130425/share/emacs/30.1.50/lisp/org/org-keys /usr/local/home/azeng/workspaces/24833141-bffb-3c99-a9d6-c366d37c4f5e/+shar= e+/app/emacs/site-lisp/elpa/org-9.7.27/org-inlinetask hides /usr/local/home= /garnish/raw-emacs/30-20250328_130425/share/emacs/30.1.50/lisp/org/org-inli= netask /usr/local/home/azeng/workspaces/24833141-bffb-3c99-a9d6-c366d37c4f5e/+shar= e+/app/emacs/site-lisp/elpa/org-9.7.27/org-indent hides /usr/local/home/gar= nish/raw-emacs/30-20250328_130425/share/emacs/30.1.50/lisp/org/org-indent /usr/local/home/azeng/workspaces/24833141-bffb-3c99-a9d6-c366d37c4f5e/+shar= e+/app/emacs/site-lisp/elpa/org-9.7.27/org-id hides /usr/local/home/garnish= /raw-emacs/30-20250328_130425/share/emacs/30.1.50/lisp/org/org-id /usr/local/home/azeng/workspaces/24833141-bffb-3c99-a9d6-c366d37c4f5e/+shar= e+/app/emacs/site-lisp/elpa/org-9.7.27/org-habit hides /usr/local/home/garn= ish/raw-emacs/30-20250328_130425/share/emacs/30.1.50/lisp/org/org-habit /usr/local/home/azeng/workspaces/24833141-bffb-3c99-a9d6-c366d37c4f5e/+shar= e+/app/emacs/site-lisp/elpa/org-9.7.27/org-goto hides /usr/local/home/garni= sh/raw-emacs/30-20250328_130425/share/emacs/30.1.50/lisp/org/org-goto /usr/local/home/azeng/workspaces/24833141-bffb-3c99-a9d6-c366d37c4f5e/+shar= e+/app/emacs/site-lisp/elpa/org-9.7.27/org-footnote hides /usr/local/home/g= arnish/raw-emacs/30-20250328_130425/share/emacs/30.1.50/lisp/org/org-footno= te /usr/local/home/azeng/workspaces/24833141-bffb-3c99-a9d6-c366d37c4f5e/+shar= e+/app/emacs/site-lisp/elpa/org-9.7.27/org-fold hides /usr/local/home/garni= sh/raw-emacs/30-20250328_130425/share/emacs/30.1.50/lisp/org/org-fold /usr/local/home/azeng/workspaces/24833141-bffb-3c99-a9d6-c366d37c4f5e/+shar= e+/app/emacs/site-lisp/elpa/org-9.7.27/org-fold-core hides /usr/local/home/= garnish/raw-emacs/30-20250328_130425/share/emacs/30.1.50/lisp/org/org-fold-= core /usr/local/home/azeng/workspaces/24833141-bffb-3c99-a9d6-c366d37c4f5e/+shar= e+/app/emacs/site-lisp/elpa/org-9.7.27/org-feed hides /usr/local/home/garni= sh/raw-emacs/30-20250328_130425/share/emacs/30.1.50/lisp/org/org-feed /usr/local/home/azeng/workspaces/24833141-bffb-3c99-a9d6-c366d37c4f5e/+shar= e+/app/emacs/site-lisp/elpa/org-9.7.27/org-faces hides /usr/local/home/garn= ish/raw-emacs/30-20250328_130425/share/emacs/30.1.50/lisp/org/org-faces /usr/local/home/azeng/workspaces/24833141-bffb-3c99-a9d6-c366d37c4f5e/+shar= e+/app/emacs/site-lisp/elpa/org-9.7.27/org-entities hides /usr/local/home/g= arnish/raw-emacs/30-20250328_130425/share/emacs/30.1.50/lisp/org/org-entiti= es /usr/local/home/azeng/workspaces/24833141-bffb-3c99-a9d6-c366d37c4f5e/+shar= e+/app/emacs/site-lisp/elpa/org-9.7.27/org-element hides /usr/local/home/ga= rnish/raw-emacs/30-20250328_130425/share/emacs/30.1.50/lisp/org/org-element /usr/local/home/azeng/workspaces/24833141-bffb-3c99-a9d6-c366d37c4f5e/+shar= e+/app/emacs/site-lisp/elpa/org-9.7.27/org-element-ast hides /usr/local/hom= e/garnish/raw-emacs/30-20250328_130425/share/emacs/30.1.50/lisp/org/org-ele= ment-ast /usr/local/home/azeng/workspaces/24833141-bffb-3c99-a9d6-c366d37c4f5e/+shar= e+/app/emacs/site-lisp/elpa/org-9.7.27/org-duration hides /usr/local/home/g= arnish/raw-emacs/30-20250328_130425/share/emacs/30.1.50/lisp/org/org-durati= on /usr/local/home/azeng/workspaces/24833141-bffb-3c99-a9d6-c366d37c4f5e/+shar= e+/app/emacs/site-lisp/elpa/org-9.7.27/org-datetree hides /usr/local/home/g= arnish/raw-emacs/30-20250328_130425/share/emacs/30.1.50/lisp/org/org-datetr= ee /usr/local/home/azeng/workspaces/24833141-bffb-3c99-a9d6-c366d37c4f5e/+shar= e+/app/emacs/site-lisp/elpa/org-9.7.27/org-cycle hides /usr/local/home/garn= ish/raw-emacs/30-20250328_130425/share/emacs/30.1.50/lisp/org/org-cycle /usr/local/home/azeng/workspaces/24833141-bffb-3c99-a9d6-c366d37c4f5e/+shar= e+/app/emacs/site-lisp/elpa/org-9.7.27/org-ctags hides /usr/local/home/garn= ish/raw-emacs/30-20250328_130425/share/emacs/30.1.50/lisp/org/org-ctags /usr/local/home/azeng/workspaces/24833141-bffb-3c99-a9d6-c366d37c4f5e/+shar= e+/app/emacs/site-lisp/elpa/org-9.7.27/org-crypt hides /usr/local/home/garn= ish/raw-emacs/30-20250328_130425/share/emacs/30.1.50/lisp/org/org-crypt /usr/local/home/azeng/workspaces/24833141-bffb-3c99-a9d6-c366d37c4f5e/+shar= e+/app/emacs/site-lisp/elpa/org-9.7.27/org-compat hides /usr/local/home/gar= nish/raw-emacs/30-20250328_130425/share/emacs/30.1.50/lisp/org/org-compat /usr/local/home/azeng/workspaces/24833141-bffb-3c99-a9d6-c366d37c4f5e/+shar= e+/app/emacs/site-lisp/elpa/org-9.7.27/org-colview hides /usr/local/home/ga= rnish/raw-emacs/30-20250328_130425/share/emacs/30.1.50/lisp/org/org-colview /usr/local/home/azeng/workspaces/24833141-bffb-3c99-a9d6-c366d37c4f5e/+shar= e+/app/emacs/site-lisp/elpa/org-9.7.27/org-clock hides /usr/local/home/garn= ish/raw-emacs/30-20250328_130425/share/emacs/30.1.50/lisp/org/org-clock /usr/local/home/azeng/workspaces/24833141-bffb-3c99-a9d6-c366d37c4f5e/+shar= e+/app/emacs/site-lisp/elpa/org-9.7.27/org-capture hides /usr/local/home/ga= rnish/raw-emacs/30-20250328_130425/share/emacs/30.1.50/lisp/org/org-capture /usr/local/home/azeng/workspaces/24833141-bffb-3c99-a9d6-c366d37c4f5e/+shar= e+/app/emacs/site-lisp/elpa/org-9.7.27/org-attach hides /usr/local/home/gar= nish/raw-emacs/30-20250328_130425/share/emacs/30.1.50/lisp/org/org-attach /usr/local/home/azeng/workspaces/24833141-bffb-3c99-a9d6-c366d37c4f5e/+shar= e+/app/emacs/site-lisp/elpa/org-9.7.27/org-attach-git hides /usr/local/home= /garnish/raw-emacs/30-20250328_130425/share/emacs/30.1.50/lisp/org/org-atta= ch-git /usr/local/home/azeng/workspaces/24833141-bffb-3c99-a9d6-c366d37c4f5e/+shar= e+/app/emacs/site-lisp/elpa/org-9.7.27/org-archive hides /usr/local/home/ga= rnish/raw-emacs/30-20250328_130425/share/emacs/30.1.50/lisp/org/org-archive /usr/local/home/azeng/workspaces/24833141-bffb-3c99-a9d6-c366d37c4f5e/+shar= e+/app/emacs/site-lisp/elpa/org-9.7.27/org-agenda hides /usr/local/home/gar= nish/raw-emacs/30-20250328_130425/share/emacs/30.1.50/lisp/org/org-agenda /usr/local/home/azeng/workspaces/24833141-bffb-3c99-a9d6-c366d37c4f5e/+shar= e+/app/emacs/site-lisp/elpa/org-9.7.27/ol hides /usr/local/home/garnish/raw= -emacs/30-20250328_130425/share/emacs/30.1.50/lisp/org/ol /usr/local/home/azeng/workspaces/24833141-bffb-3c99-a9d6-c366d37c4f5e/+shar= e+/app/emacs/site-lisp/elpa/org-9.7.27/ol-w3m hides /usr/local/home/garnish= /raw-emacs/30-20250328_130425/share/emacs/30.1.50/lisp/org/ol-w3m /usr/local/home/azeng/workspaces/24833141-bffb-3c99-a9d6-c366d37c4f5e/+shar= e+/app/emacs/site-lisp/elpa/org-9.7.27/ol-rmail hides /usr/local/home/garni= sh/raw-emacs/30-20250328_130425/share/emacs/30.1.50/lisp/org/ol-rmail /usr/local/home/azeng/workspaces/24833141-bffb-3c99-a9d6-c366d37c4f5e/+shar= e+/app/emacs/site-lisp/elpa/org-9.7.27/ol-mhe hides /usr/local/home/garnish= /raw-emacs/30-20250328_130425/share/emacs/30.1.50/lisp/org/ol-mhe /usr/local/home/azeng/workspaces/24833141-bffb-3c99-a9d6-c366d37c4f5e/+shar= e+/app/emacs/site-lisp/elpa/org-9.7.27/ol-man hides /usr/local/home/garnish= /raw-emacs/30-20250328_130425/share/emacs/30.1.50/lisp/org/ol-man /usr/local/home/azeng/workspaces/24833141-bffb-3c99-a9d6-c366d37c4f5e/+shar= e+/app/emacs/site-lisp/elpa/org-9.7.27/ol-irc hides /usr/local/home/garnish= /raw-emacs/30-20250328_130425/share/emacs/30.1.50/lisp/org/ol-irc /usr/local/home/azeng/workspaces/24833141-bffb-3c99-a9d6-c366d37c4f5e/+shar= e+/app/emacs/site-lisp/elpa/org-9.7.27/ol-info hides /usr/local/home/garnis= h/raw-emacs/30-20250328_130425/share/emacs/30.1.50/lisp/org/ol-info /usr/local/home/azeng/workspaces/24833141-bffb-3c99-a9d6-c366d37c4f5e/+shar= e+/app/emacs/site-lisp/elpa/org-9.7.27/ol-gnus hides /usr/local/home/garnis= h/raw-emacs/30-20250328_130425/share/emacs/30.1.50/lisp/org/ol-gnus /usr/local/home/azeng/workspaces/24833141-bffb-3c99-a9d6-c366d37c4f5e/+shar= e+/app/emacs/site-lisp/elpa/org-9.7.27/ol-eww hides /usr/local/home/garnish= /raw-emacs/30-20250328_130425/share/emacs/30.1.50/lisp/org/ol-eww /usr/local/home/azeng/workspaces/24833141-bffb-3c99-a9d6-c366d37c4f5e/+shar= e+/app/emacs/site-lisp/elpa/org-9.7.27/ol-eshell hides /usr/local/home/garn= ish/raw-emacs/30-20250328_130425/share/emacs/30.1.50/lisp/org/ol-eshell /usr/local/home/azeng/workspaces/24833141-bffb-3c99-a9d6-c366d37c4f5e/+shar= e+/app/emacs/site-lisp/elpa/org-9.7.27/ol-doi hides /usr/local/home/garnish= /raw-emacs/30-20250328_130425/share/emacs/30.1.50/lisp/org/ol-doi /usr/local/home/azeng/workspaces/24833141-bffb-3c99-a9d6-c366d37c4f5e/+shar= e+/app/emacs/site-lisp/elpa/org-9.7.27/ol-docview hides /usr/local/home/gar= nish/raw-emacs/30-20250328_130425/share/emacs/30.1.50/lisp/org/ol-docview /usr/local/home/azeng/workspaces/24833141-bffb-3c99-a9d6-c366d37c4f5e/+shar= e+/app/emacs/site-lisp/elpa/org-9.7.27/ol-bibtex hides /usr/local/home/garn= ish/raw-emacs/30-20250328_130425/share/emacs/30.1.50/lisp/org/ol-bibtex /usr/local/home/azeng/workspaces/24833141-bffb-3c99-a9d6-c366d37c4f5e/+shar= e+/app/emacs/site-lisp/elpa/org-9.7.27/ol-bbdb hides /usr/local/home/garnis= h/raw-emacs/30-20250328_130425/share/emacs/30.1.50/lisp/org/ol-bbdb /usr/local/home/azeng/workspaces/24833141-bffb-3c99-a9d6-c366d37c4f5e/+shar= e+/app/emacs/site-lisp/elpa/org-9.7.27/oc hides /usr/local/home/garnish/raw= -emacs/30-20250328_130425/share/emacs/30.1.50/lisp/org/oc /usr/local/home/azeng/workspaces/24833141-bffb-3c99-a9d6-c366d37c4f5e/+shar= e+/app/emacs/site-lisp/elpa/org-9.7.27/oc-natbib hides /usr/local/home/garn= ish/raw-emacs/30-20250328_130425/share/emacs/30.1.50/lisp/org/oc-natbib /usr/local/home/azeng/workspaces/24833141-bffb-3c99-a9d6-c366d37c4f5e/+shar= e+/app/emacs/site-lisp/elpa/org-9.7.27/oc-csl hides /usr/local/home/garnish= /raw-emacs/30-20250328_130425/share/emacs/30.1.50/lisp/org/oc-csl /usr/local/home/azeng/workspaces/24833141-bffb-3c99-a9d6-c366d37c4f5e/+shar= e+/app/emacs/site-lisp/elpa/org-9.7.27/oc-bibtex hides /usr/local/home/garn= ish/raw-emacs/30-20250328_130425/share/emacs/30.1.50/lisp/org/oc-bibtex /usr/local/home/azeng/workspaces/24833141-bffb-3c99-a9d6-c366d37c4f5e/+shar= e+/app/emacs/site-lisp/elpa/org-9.7.27/oc-biblatex hides /usr/local/home/ga= rnish/raw-emacs/30-20250328_130425/share/emacs/30.1.50/lisp/org/oc-biblatex /usr/local/home/azeng/workspaces/24833141-bffb-3c99-a9d6-c366d37c4f5e/+shar= e+/app/emacs/site-lisp/elpa/org-9.7.27/oc-basic hides /usr/local/home/garni= sh/raw-emacs/30-20250328_130425/share/emacs/30.1.50/lisp/org/oc-basic /usr/local/home/azeng/workspaces/24833141-bffb-3c99-a9d6-c366d37c4f5e/+shar= e+/app/emacs/site-lisp/elpa/org-9.7.27/ob hides /usr/local/home/garnish/raw= -emacs/30-20250328_130425/share/emacs/30.1.50/lisp/org/ob /usr/local/home/azeng/workspaces/24833141-bffb-3c99-a9d6-c366d37c4f5e/+shar= e+/app/emacs/site-lisp/elpa/org-9.7.27/ob-tangle hides /usr/local/home/garn= ish/raw-emacs/30-20250328_130425/share/emacs/30.1.50/lisp/org/ob-tangle /usr/local/home/azeng/workspaces/24833141-bffb-3c99-a9d6-c366d37c4f5e/+shar= e+/app/emacs/site-lisp/elpa/org-9.7.27/ob-table hides /usr/local/home/garni= sh/raw-emacs/30-20250328_130425/share/emacs/30.1.50/lisp/org/ob-table /usr/local/home/azeng/workspaces/24833141-bffb-3c99-a9d6-c366d37c4f5e/+shar= e+/app/emacs/site-lisp/elpa/org-9.7.27/ob-sqlite hides /usr/local/home/garn= ish/raw-emacs/30-20250328_130425/share/emacs/30.1.50/lisp/org/ob-sqlite /usr/local/home/azeng/workspaces/24833141-bffb-3c99-a9d6-c366d37c4f5e/+shar= e+/app/emacs/site-lisp/elpa/org-9.7.27/ob-sql hides /usr/local/home/garnish= /raw-emacs/30-20250328_130425/share/emacs/30.1.50/lisp/org/ob-sql /usr/local/home/azeng/workspaces/24833141-bffb-3c99-a9d6-c366d37c4f5e/+shar= e+/app/emacs/site-lisp/elpa/org-9.7.27/ob-shell hides /usr/local/home/garni= sh/raw-emacs/30-20250328_130425/share/emacs/30.1.50/lisp/org/ob-shell /usr/local/home/azeng/workspaces/24833141-bffb-3c99-a9d6-c366d37c4f5e/+shar= e+/app/emacs/site-lisp/elpa/org-9.7.27/ob-sed hides /usr/local/home/garnish= /raw-emacs/30-20250328_130425/share/emacs/30.1.50/lisp/org/ob-sed /usr/local/home/azeng/workspaces/24833141-bffb-3c99-a9d6-c366d37c4f5e/+shar= e+/app/emacs/site-lisp/elpa/org-9.7.27/ob-screen hides /usr/local/home/garn= ish/raw-emacs/30-20250328_130425/share/emacs/30.1.50/lisp/org/ob-screen /usr/local/home/azeng/workspaces/24833141-bffb-3c99-a9d6-c366d37c4f5e/+shar= e+/app/emacs/site-lisp/elpa/org-9.7.27/ob-scheme hides /usr/local/home/garn= ish/raw-emacs/30-20250328_130425/share/emacs/30.1.50/lisp/org/ob-scheme /usr/local/home/azeng/workspaces/24833141-bffb-3c99-a9d6-c366d37c4f5e/+shar= e+/app/emacs/site-lisp/elpa/org-9.7.27/ob-sass hides /usr/local/home/garnis= h/raw-emacs/30-20250328_130425/share/emacs/30.1.50/lisp/org/ob-sass /usr/local/home/azeng/workspaces/24833141-bffb-3c99-a9d6-c366d37c4f5e/+shar= e+/app/emacs/site-lisp/elpa/org-9.7.27/ob-ruby hides /usr/local/home/garnis= h/raw-emacs/30-20250328_130425/share/emacs/30.1.50/lisp/org/ob-ruby /usr/local/home/azeng/workspaces/24833141-bffb-3c99-a9d6-c366d37c4f5e/+shar= e+/app/emacs/site-lisp/elpa/org-9.7.27/ob-ref hides /usr/local/home/garnish= /raw-emacs/30-20250328_130425/share/emacs/30.1.50/lisp/org/ob-ref /usr/local/home/azeng/workspaces/24833141-bffb-3c99-a9d6-c366d37c4f5e/+shar= e+/app/emacs/site-lisp/elpa/org-9.7.27/ob-python hides /usr/local/home/garn= ish/raw-emacs/30-20250328_130425/share/emacs/30.1.50/lisp/org/ob-python /usr/local/home/azeng/workspaces/24833141-bffb-3c99-a9d6-c366d37c4f5e/+shar= e+/app/emacs/site-lisp/elpa/org-9.7.27/ob-processing hides /usr/local/home/= garnish/raw-emacs/30-20250328_130425/share/emacs/30.1.50/lisp/org/ob-proces= sing /usr/local/home/azeng/workspaces/24833141-bffb-3c99-a9d6-c366d37c4f5e/+shar= e+/app/emacs/site-lisp/elpa/org-9.7.27/ob-plantuml hides /usr/local/home/ga= rnish/raw-emacs/30-20250328_130425/share/emacs/30.1.50/lisp/org/ob-plantuml /usr/local/home/azeng/workspaces/24833141-bffb-3c99-a9d6-c366d37c4f5e/+shar= e+/app/emacs/site-lisp/elpa/org-9.7.27/ob-perl hides /usr/local/home/garnis= h/raw-emacs/30-20250328_130425/share/emacs/30.1.50/lisp/org/ob-perl /usr/local/home/azeng/workspaces/24833141-bffb-3c99-a9d6-c366d37c4f5e/+shar= e+/app/emacs/site-lisp/elpa/org-9.7.27/ob-org hides /usr/local/home/garnish= /raw-emacs/30-20250328_130425/share/emacs/30.1.50/lisp/org/ob-org /usr/local/home/azeng/workspaces/24833141-bffb-3c99-a9d6-c366d37c4f5e/+shar= e+/app/emacs/site-lisp/elpa/org-9.7.27/ob-octave hides /usr/local/home/garn= ish/raw-emacs/30-20250328_130425/share/emacs/30.1.50/lisp/org/ob-octave /usr/local/home/azeng/workspaces/24833141-bffb-3c99-a9d6-c366d37c4f5e/+shar= e+/app/emacs/site-lisp/elpa/org-9.7.27/ob-ocaml hides /usr/local/home/garni= sh/raw-emacs/30-20250328_130425/share/emacs/30.1.50/lisp/org/ob-ocaml /usr/local/home/azeng/workspaces/24833141-bffb-3c99-a9d6-c366d37c4f5e/+shar= e+/app/emacs/site-lisp/elpa/org-9.7.27/ob-maxima hides /usr/local/home/garn= ish/raw-emacs/30-20250328_130425/share/emacs/30.1.50/lisp/org/ob-maxima /usr/local/home/azeng/workspaces/24833141-bffb-3c99-a9d6-c366d37c4f5e/+shar= e+/app/emacs/site-lisp/elpa/org-9.7.27/ob-matlab hides /usr/local/home/garn= ish/raw-emacs/30-20250328_130425/share/emacs/30.1.50/lisp/org/ob-matlab /usr/local/home/azeng/workspaces/24833141-bffb-3c99-a9d6-c366d37c4f5e/+shar= e+/app/emacs/site-lisp/elpa/org-9.7.27/ob-makefile hides /usr/local/home/ga= rnish/raw-emacs/30-20250328_130425/share/emacs/30.1.50/lisp/org/ob-makefile /usr/local/home/azeng/workspaces/24833141-bffb-3c99-a9d6-c366d37c4f5e/+shar= e+/app/emacs/site-lisp/elpa/org-9.7.27/ob-lua hides /usr/local/home/garnish= /raw-emacs/30-20250328_130425/share/emacs/30.1.50/lisp/org/ob-lua /usr/local/home/azeng/workspaces/24833141-bffb-3c99-a9d6-c366d37c4f5e/+shar= e+/app/emacs/site-lisp/elpa/org-9.7.27/ob-lob hides /usr/local/home/garnish= /raw-emacs/30-20250328_130425/share/emacs/30.1.50/lisp/org/ob-lob /usr/local/home/azeng/workspaces/24833141-bffb-3c99-a9d6-c366d37c4f5e/+shar= e+/app/emacs/site-lisp/elpa/org-9.7.27/ob-lisp hides /usr/local/home/garnis= h/raw-emacs/30-20250328_130425/share/emacs/30.1.50/lisp/org/ob-lisp /usr/local/home/azeng/workspaces/24833141-bffb-3c99-a9d6-c366d37c4f5e/+shar= e+/app/emacs/site-lisp/elpa/org-9.7.27/ob-lilypond hides /usr/local/home/ga= rnish/raw-emacs/30-20250328_130425/share/emacs/30.1.50/lisp/org/ob-lilypond /usr/local/home/azeng/workspaces/24833141-bffb-3c99-a9d6-c366d37c4f5e/+shar= e+/app/emacs/site-lisp/elpa/org-9.7.27/ob-latex hides /usr/local/home/garni= sh/raw-emacs/30-20250328_130425/share/emacs/30.1.50/lisp/org/ob-latex /usr/local/home/azeng/workspaces/24833141-bffb-3c99-a9d6-c366d37c4f5e/+shar= e+/app/emacs/site-lisp/elpa/org-9.7.27/ob-julia hides /usr/local/home/garni= sh/raw-emacs/30-20250328_130425/share/emacs/30.1.50/lisp/org/ob-julia /usr/local/home/azeng/workspaces/24833141-bffb-3c99-a9d6-c366d37c4f5e/+shar= e+/app/emacs/site-lisp/elpa/org-9.7.27/ob-js hides /usr/local/home/garnish/= raw-emacs/30-20250328_130425/share/emacs/30.1.50/lisp/org/ob-js /usr/local/home/azeng/workspaces/24833141-bffb-3c99-a9d6-c366d37c4f5e/+shar= e+/app/emacs/site-lisp/elpa/org-9.7.27/ob-java hides /usr/local/home/garnis= h/raw-emacs/30-20250328_130425/share/emacs/30.1.50/lisp/org/ob-java /usr/local/home/azeng/workspaces/24833141-bffb-3c99-a9d6-c366d37c4f5e/+shar= e+/app/emacs/site-lisp/elpa/org-9.7.27/ob-haskell hides /usr/local/home/gar= nish/raw-emacs/30-20250328_130425/share/emacs/30.1.50/lisp/org/ob-haskell /usr/local/home/azeng/workspaces/24833141-bffb-3c99-a9d6-c366d37c4f5e/+shar= e+/app/emacs/site-lisp/elpa/org-9.7.27/ob-groovy hides /usr/local/home/garn= ish/raw-emacs/30-20250328_130425/share/emacs/30.1.50/lisp/org/ob-groovy /usr/local/home/azeng/workspaces/24833141-bffb-3c99-a9d6-c366d37c4f5e/+shar= e+/app/emacs/site-lisp/elpa/org-9.7.27/ob-gnuplot hides /usr/local/home/gar= nish/raw-emacs/30-20250328_130425/share/emacs/30.1.50/lisp/org/ob-gnuplot /usr/local/home/azeng/workspaces/24833141-bffb-3c99-a9d6-c366d37c4f5e/+shar= e+/app/emacs/site-lisp/elpa/org-9.7.27/ob-fortran hides /usr/local/home/gar= nish/raw-emacs/30-20250328_130425/share/emacs/30.1.50/lisp/org/ob-fortran /usr/local/home/azeng/workspaces/24833141-bffb-3c99-a9d6-c366d37c4f5e/+shar= e+/app/emacs/site-lisp/elpa/org-9.7.27/ob-forth hides /usr/local/home/garni= sh/raw-emacs/30-20250328_130425/share/emacs/30.1.50/lisp/org/ob-forth /usr/local/home/azeng/workspaces/24833141-bffb-3c99-a9d6-c366d37c4f5e/+shar= e+/app/emacs/site-lisp/elpa/org-9.7.27/ob-exp hides /usr/local/home/garnish= /raw-emacs/30-20250328_130425/share/emacs/30.1.50/lisp/org/ob-exp /usr/local/home/azeng/workspaces/24833141-bffb-3c99-a9d6-c366d37c4f5e/+shar= e+/app/emacs/site-lisp/elpa/org-9.7.27/ob-eval hides /usr/local/home/garnis= h/raw-emacs/30-20250328_130425/share/emacs/30.1.50/lisp/org/ob-eval /usr/local/home/azeng/workspaces/24833141-bffb-3c99-a9d6-c366d37c4f5e/+shar= e+/app/emacs/site-lisp/elpa/org-9.7.27/ob-eshell hides /usr/local/home/garn= ish/raw-emacs/30-20250328_130425/share/emacs/30.1.50/lisp/org/ob-eshell /usr/local/home/azeng/workspaces/24833141-bffb-3c99-a9d6-c366d37c4f5e/+shar= e+/app/emacs/site-lisp/elpa/org-9.7.27/ob-emacs-lisp hides /usr/local/home/= garnish/raw-emacs/30-20250328_130425/share/emacs/30.1.50/lisp/org/ob-emacs-= lisp /usr/local/home/azeng/workspaces/24833141-bffb-3c99-a9d6-c366d37c4f5e/+shar= e+/app/emacs/site-lisp/elpa/org-9.7.27/ob-dot hides /usr/local/home/garnish= /raw-emacs/30-20250328_130425/share/emacs/30.1.50/lisp/org/ob-dot /usr/local/home/azeng/workspaces/24833141-bffb-3c99-a9d6-c366d37c4f5e/+shar= e+/app/emacs/site-lisp/elpa/org-9.7.27/ob-ditaa hides /usr/local/home/garni= sh/raw-emacs/30-20250328_130425/share/emacs/30.1.50/lisp/org/ob-ditaa /usr/local/home/azeng/workspaces/24833141-bffb-3c99-a9d6-c366d37c4f5e/+shar= e+/app/emacs/site-lisp/elpa/org-9.7.27/ob-css hides /usr/local/home/garnish= /raw-emacs/30-20250328_130425/share/emacs/30.1.50/lisp/org/ob-css /usr/local/home/azeng/workspaces/24833141-bffb-3c99-a9d6-c366d37c4f5e/+shar= e+/app/emacs/site-lisp/elpa/org-9.7.27/ob-core hides /usr/local/home/garnis= h/raw-emacs/30-20250328_130425/share/emacs/30.1.50/lisp/org/ob-core /usr/local/home/azeng/workspaces/24833141-bffb-3c99-a9d6-c366d37c4f5e/+shar= e+/app/emacs/site-lisp/elpa/org-9.7.27/ob-comint hides /usr/local/home/garn= ish/raw-emacs/30-20250328_130425/share/emacs/30.1.50/lisp/org/ob-comint /usr/local/home/azeng/workspaces/24833141-bffb-3c99-a9d6-c366d37c4f5e/+shar= e+/app/emacs/site-lisp/elpa/org-9.7.27/ob-clojure hides /usr/local/home/gar= nish/raw-emacs/30-20250328_130425/share/emacs/30.1.50/lisp/org/ob-clojure /usr/local/home/azeng/workspaces/24833141-bffb-3c99-a9d6-c366d37c4f5e/+shar= e+/app/emacs/site-lisp/elpa/org-9.7.27/ob-calc hides /usr/local/home/garnis= h/raw-emacs/30-20250328_130425/share/emacs/30.1.50/lisp/org/ob-calc /usr/local/home/azeng/workspaces/24833141-bffb-3c99-a9d6-c366d37c4f5e/+shar= e+/app/emacs/site-lisp/elpa/org-9.7.27/ob-awk hides /usr/local/home/garnish= /raw-emacs/30-20250328_130425/share/emacs/30.1.50/lisp/org/ob-awk /usr/local/home/azeng/workspaces/24833141-bffb-3c99-a9d6-c366d37c4f5e/+shar= e+/app/emacs/site-lisp/elpa/org-9.7.27/ob-R hides /usr/local/home/garnish/r= aw-emacs/30-20250328_130425/share/emacs/30.1.50/lisp/org/ob-R /usr/local/home/azeng/workspaces/24833141-bffb-3c99-a9d6-c366d37c4f5e/+shar= e+/app/emacs/site-lisp/elpa/org-9.7.27/ob-C hides /usr/local/home/garnish/r= aw-emacs/30-20250328_130425/share/emacs/30.1.50/lisp/org/ob-C Features: (shadow sort mail-extr emacsbug message yank-media rfc822 mml mml-sec epa epg rfc6068 epg-config gnus-util time-date mm-decode mm-bodies mm-encode mailabbrev gmm-utils mailheader sendmail mail-utils overseer pkg-info url-http url-auth mail-parse rfc2231 rfc2047 rfc2045 mm-util ietf-drums mail-prsvr url-gw nsm puny lisp-mnt epl dash site-start jane-customization jane-which-key which-key delsel jane-fe-regex jane-build-status jane-patdiff jane-diagnose jane-merlin merlin-xref xref merlin-cap merlin hi-lock crm jane-async-merlin jane-completion jane-yasnippet jane-fe-project jane-fe-feature-table imenu jane-fe-menu ecaml_plugin view edmacro kmacro bookmark ecaml dired-x editorconfig editorconfig-core editorconfig-core-handle editorconfig-fnmatch mode-line-bell help-at-pt jane-micro-features server jane-diff smerge-mode diff unified-test-mode shell-file dired dired-loaddefs jane-sexp derived rainbow-delimiters jane-python jane-ocaml hydra advice lv jane-aide diff-mode track-changes easy-mmode ert ewoc debug backtrace find-func tuareg tuareg-compat tuareg-opam flymake project thingatpt smie find-file compile text-property-search jane-cr jane-align shell pcomplete comint ansi-osc ansi-color ring vc vc-dispatcher jane-telemetry comp comp-cstr cl-extra help-mode warnings comp-run comp-common jane-rust ocp-indent jane-eglot jane-elisp-loaddefs jane-util jane-elpa-pin ace-jump-helm-line-autoloads ace-link-autoloads aggressive-indent-autoloads ahk-mode-autoloads all-the-icons-ivy-rich-autoloads auto-compile-autoloads auto-dictionary-autoloads auto-highlight-symbol-autoloads auto-yasnippet-autoloads base16-theme-autoloads bash-completion-autoloads blacken-autoloads browse-at-remote-autoloads centered-cursor-mode-autoloads clean-aindent-mode-autoloads code-cells-autoloads column-enforce-mode-autoloads company-box-autoloads company-lua-autoloads company-posframe-autoloads company-quickhelp-autoloads company-shell-autoloads company-statistics-autoloads company-web-autoloads consult-yasnippet-autoloads corfu-autoloads counsel-css-autoloads counsel-projectile-autoloads counsel-autoloads csv-mode-autoloads dap-mode-autoloads bui-autoloads debbugs-autoloads define-word-autoloads diff-hl-autoloads diminish-autoloads dired-quick-sort-autoloads disable-mouse-autoloads doom-modeline-autoloads doom-themes-autoloads dotenv-mode-autoloads drag-stuff-autoloads eat-autoloads edit-indirect-autoloads eldoc-box-autoloads elisp-def-autoloads elisp-slime-nav-autoloads embark-consult-autoloads consult-autoloads embark-autoloads emmet-mode-autoloads emr-autoloads clang-format-autoloads esh-help-autoloads eshell-prompt-extras-autoloads eshell-z-autoloads ess-autoloads eval-sexp-fu-autoloads evil-anzu-autoloads anzu-autoloads evil-args-autoloads evil-cleverparens-autoloads evil-collection-autoloads annalist-autoloads evil-easymotion-autoloads evil-escape-autoloads evil-exchange-autoloads evil-goggles-autoloads evil-iedit-state-autoloads evil-indent-plus-autoloads evil-lion-autoloads evil-lisp-state-autoloads bind-map-autoloads evil-matchit-autoloads evil-mc-autoloads evil-nerd-commenter-autoloads evil-numbers-autoloads evil-org-autoloads evil-surround-autoloads evil-textobj-line-autoloads evil-tutor-autoloads evil-visual-mark-mode-autoloads evil-visualstar-autoloads expand-region-autoloads explain-pause-mode-autoloads eyebrowse-autoloads fish-mode-autoloads flx-autoloads flycheck-bashate-autoloads flycheck-eglot-autoloads eglot-autoloads flycheck-elsa-autoloads flycheck-package-autoloads flycheck-pos-tip-autoloads flyspell-correct-helm-autoloads flyspell-correct-ivy-autoloads flyspell-correct-popup-autoloads flyspell-correct-autoloads flyspell-popup-autoloads frame-local-autoloads fzf-autoloads gh-md-autoloads git-gutter-autoloads git-link-autoloads git-messenger-autoloads git-modes-autoloads git-timemachine-autoloads gitignore-templates-autoloads gnu-elpa-keyring-update-autoloads gnuplot-autoloads golden-ratio-autoloads goto-chg-autoloads gruvbox-theme-autoloads autothemer-autoloads haskell-mode-autoloads hc-zenburn-theme-autoloads helm-ag-autoloads helm-c-yasnippet-autoloads helm-comint-autoloads helm-company-autoloads company-autoloads helm-css-scss-autoloads helm-descbinds-autoloads helm-git-grep-autoloads helm-make-autoloads helm-mode-manager-autoloads helm-org-autoloads helm-easymenu helm-org-rifle-autoloads helm-projectile-autoloads helm-purpose-autoloads helm-pydoc-autoloads helm-swoop-autoloads helm-autoloads helm-themes-autoloads helm-core-autoloads helpful-autoloads elisp-refs-autoloads highlight-indentation-autoloads highlight-numbers-autoloads highlight-parentheses-autoloads ibuffer-projectile-autoloads iedit-autoloads impatient-mode-autoloads importmagic-autoloads epc-autoloads ctable-autoloads concurrent-autoloads deferred-autoloads indent-guide-autoloads ivy-avy-autoloads ivy-hydra-autoloads ivy-purpose-autoloads ivy-rich-autoloads ivy-xref-autoloads ivy-yasnippet-autoloads js-doc-autoloads js2-refactor-autoloads json-mode-autoloads json-navigator-autoloads json-reformat-autoloads json-snatcher-autoloads jsonnet-mode-autoloads ligature-autoloads link-hint-autoloads livid-mode-autoloads lorem-ipsum-autoloads lsp-docker-autoloads lsp-treemacs-autoloads lsp-mode-autoloads lua-mode-autoloads macrostep-autoloads magit-gitflow-autoloads magit-popup-autoloads magit-svn-autoloads magit-todos-autoloads hl-todo-autoloads marginalia-autoloads markdown-toc-autoloads material-theme-autoloads merlin-eldoc-autoloads merlin-autoloads mode-line-bell-autoloads monokai-theme-autoloads multi-line-autoloads multi-term-autoloads multiple-cursors-autoloads mwim-autoloads nameless-autoloads nerd-icons-autoloads nix-mode-autoloads nodejs-repl-autoloads npm-mode-autoloads ob-powershell-autoloads ocp-indent-autoloads open-junk-file-autoloads orderless-autoloads org-appear-autoloads org-cliplink-autoloads org-contrib-autoloads org-download-autoloads org-mime-autoloads org-modern-autoloads org-pomodoro-autoloads org-present-autoloads org-projectile-autoloads org-project-capture-autoloads org-category-capture-autoloads org-re-reveal-autoloads htmlize-autoloads org-rich-yank-autoloads org-roam-autoloads org-sticky-header-autoloads org-superstar-autoloads org-transclusion-autoloads org-wild-notifier-autoloads async-autoloads alert-autoloads log4e-autoloads gntp-autoloads orgit-forge-autoloads orgit-autoloads forge-autoloads ghub-autoloads closql-autoloads emacsql-autoloads overseer-autoloads ox-gfm-autoloads ox-jira-autoloads org-autoloads package-lint-autoloads paradox-autoloads paredit-autoloads parent-mode-autoloads pcre2el-autoloads persistent-scratch-autoloads pip-requirements-autoloads pippel-autoloads pkg-info-autoloads epl-autoloads poly-markdown-autoloads polymode-autoloads popup-autoloads popwin-autoloads pos-tip-autoloads powershell-autoloads prettier-js-autoloads protobuf-mode-autoloads pug-mode-autoloads py-isort-autoloads pydoc-autoloads pytest-autoloads pyvenv-autoloads quickrun-autoloads rainbow-delimiters-autoloads rg-autoloads ron-mode-autoloads rustic-autoloads flycheck-autoloads markdown-mode-autoloads rust-mode-autoloads sass-mode-autoloads haml-mode-autoloads scss-mode-autoloads shell-pop-autoloads shfmt-autoloads reformatter-autoloads shrink-path-autoloads f-autoloads shut-up-autoloads skewer-mode-autoloads js2-mode-autoloads simple-httpd-autoloads slim-mode-autoloads smartparens-autoloads smeargle-autoloads smex-autoloads sml-mode-autoloads solarized-theme-autoloads sphinx-doc-autoloads spinner-autoloads string-edit-at-point-autoloads string-inflection-autoloads swiper-autoloads ivy-autoloads symbol-overlay-autoloads tagedit-autoloads term-cursor-autoloads terminal-here-autoloads toc-org-autoloads toml-mode-autoloads treemacs-all-the-icons-autoloads all-the-icons-autoloads treemacs-evil-autoloads evil-autoloads treemacs-icons-dired-autoloads treemacs-magit-autoloads magit-autoloads pcase transient-autoloads magit-section-autoloads llama-autoloads treemacs-persp-autoloads persp-mode-autoloads treemacs-projectile-autoloads treemacs-autoloads cfrs-autoloads ht-autoloads hydra-autoloads lv-autoloads pfuture-autoloads ace-window-autoloads avy-autoloads s-autoloads projectile-autoloads treepy-autoloads typescript-mode-autoloads undo-fu-autoloads undo-fu-session-autoloads unfill-autoloads unicode-fonts-autoloads ucs-utils-autoloads font-utils-autoloads persistent-soft-autoloads list-utils-autoloads pcache-autoloads urgrep-autoloads utop-autoloads tuareg-autoloads rx uuidgen-autoloads valign-autoloads vba-mode-autoloads verb-autoloads vertico-autoloads vi-tilde-fringe-autoloads vmd-mode-autoloads volatile-highlights-autoloads vundo-autoloads web-beautify-autoloads web-completion-data-autoloads web-mode-autoloads wfnames-autoloads wgrep-autoloads which-key-posframe-autoloads posframe-autoloads window-purpose-autoloads imenu-list-autoloads winum-autoloads dash-autoloads with-editor-autoloads info writeroom-mode-autoloads visual-fill-column-autoloads ws-butler-autoloads xterm-color-autoloads yaml-autoloads yasnippet-snippets-autoloads yasnippet-autoloads zenburn-theme-autoloads finder-inf package browse-url 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 password-cache json subr-x map byte-opt gv bytecomp byte-compile url-vars cus-edit pp cus-load icons wid-edit 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 dynamic-setting system-font-setting font-render-setting cairo x-toolkit xinput2 x multi-tty move-toolbar make-network-process native-compile emacs) Memory information: ((conses 16 391760 54534) (symbols 48 32259 0) (strings 32 94496 6285) (string-bytes 1 3916931) (vectors 16 39356) (vector-slots 8 402217 40518) (floats 8 112 0) (intervals 56 900 0) (buffers 992 12)) From debbugs-submit-bounces@debbugs.gnu.org Wed Apr 09 08:10:17 2025 Received: (at 77658) by debbugs.gnu.org; 9 Apr 2025 12:10:17 +0000 Received: from localhost ([127.0.0.1]:38133 helo=debbugs.gnu.org) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1u2UFz-0001to-QW for submit@debbugs.gnu.org; Wed, 09 Apr 2025 08:10:17 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:49022) by debbugs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.84_2) (envelope-from ) id 1u2UFt-0001ow-NH for 77658@debbugs.gnu.org; Wed, 09 Apr 2025 08:10:13 -0400 Received: from fencepost.gnu.org ([2001:470:142:3::e]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1u2UFn-0006yV-Ey; Wed, 09 Apr 2025 08:10:03 -0400 DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=gnu.org; s=fencepost-gnu-org; h=MIME-Version:References:Subject:In-Reply-To:To:From: Date; bh=rrKzgOMbIj88N8IRt2/rdj3GEVuqynLRY/yDJ199m/A=; b=YOXJPNE9CFOhiLjgjBiC Xc88EeT4UERCXsu/6D2EI4xC+277EkIk6qpd9zyxMuryS/rGHgdefZ+669RwOYeOmoKpQPvBvFPfv SxWF9eDciTOmSUqFckPGhUriV+ILGuhCw/mDMPzOL8Rg6ijF8ubZX9D0E3S07U/Ie1/A7grGapCiz gbPQtkBNdupP/6dF84QHSQxcJwzojLe7MJpnYXw18RR+vZNQ0gMk0Xsf6Lti6ZjmuKeTGlxZ3/bot GCNdmfZOiualDSwz6vDHTTBgZR6ajrq+Lf/C9Q02IqgrzIu3WiJqWpa9XbGPCGbzCcyQywL6JDF6a uyfrCNDBH3nxSQ==; Date: Wed, 09 Apr 2025 15:09:40 +0300 Message-Id: <86o6x5sfi3.fsf@gnu.org> From: Eli Zaretskii To: Aaron Zeng , =?iso-8859-1?Q?Jo=E3o_T=E1vora?= In-Reply-To: (bug-gnu-emacs@gnu.org) Subject: Re: bug#77658: 30.1.50; Eglot: wrong-type-argument: consp, # when saving References: MIME-Version: 1.0 Content-Type: text/plain; charset=iso-8859-1 Content-Transfer-Encoding: quoted-printable X-Spam-Score: -2.3 (--) X-Debbugs-Envelope-To: 77658 Cc: 77658@debbugs.gnu.org, app-emacs-dev@janestreet.com X-BeenThere: debbugs-submit@debbugs.gnu.org X-Mailman-Version: 2.1.18 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: debbugs-submit-bounces@debbugs.gnu.org Sender: "Debbugs-submit" X-Spam-Score: -3.3 (---) > Cc: app-emacs-dev@janestreet.com > Date: Tue, 08 Apr 2025 18:05:27 -0400 > From: Aaron Zeng via "Bug reports for GNU Emacs, > the Swiss army knife of text editors" >=20 >=20 > When saving an empty buffer, and while `before-save-hook` has some functi= on for reformatting the buffer (such as an auto-styler), the following erro= r is issued: >=20 > ``` > Error running timer: (wrong-type-argument consp #>) > ``` >=20 > This error can also happen synchronously in `basic-save-buffer` rather th= an in a timer. Adding Jo=E3o. > Reproduction recipe: >=20 > With `~/src/emacs/trunk` checked out to `9663c959c73d6cca0c56f833d80ff1d9= e9708b70`: >=20 > 1. emacs -Q -l ~/src/emacs/trunk/lisp/progmodes/eglot.el > 2. Evaluate the following code: >=20 > ```emacs-lisp > (add-hook 'before-save-hook #'no-op-file-formatter) >=20 > (defun no-op-file-formatter () > (let ((temp-file (make-temp-file "no-op-file-formatter"))) > (save-restriction > (widen) > (write-region nil nil temp-file) > (insert-file-contents temp-file nil nil nil 'replace)))) > ``` >=20 > This adds a dummy "reformatter" to `before-save-hook` that is always a no= -op. >=20 > 3. `C-x C-f /tmp/z.c` > 4. `M-x eglot` (clangd must be installed, I suppose) > 5. Make some trivial edits, then `C-x h DEL` to erase the buffer contents > 6. `C-x C-s` >=20 > An error is issued as described above. Also, since `eglot--recent-change= s` now includes a malformatted entry, random other things break, too, for e= xample just inserting a space character. Backtrace included below. >=20 > I believe what is happening here, is that `insert-file-contents`, when in= serting an empty file into an empty buffer (maybe in other situations as we= ll), may cause `before-change-functions` to be run but `after-change-functi= ons` never runs. Therefore, `eglot--before-changes` inserts an element int= o `eglot--recent-changes` that `eglot--after-changes` never gets a chance t= o fix up. >=20 > According to the manual (https://www.gnu.org/software/emacs/manual/html_n= ode/elisp/Change-Hooks.html), this is allowed to happen (i.e., `after-chang= e-functions` might not always run after a change). >=20 > Backtrace for eglot--post-self-insert-hook: > ``` > Debugger entered--Lisp error: (wrong-type-argument consp #) > json-serialize((:jsonrpc "2.0" :method "textDocument/didChange" :params= (:textDocument (:uri "file:///tmp/z.c" :version 8) :contentChanges [(:rang= e (:start (:line 0 :character 0) :end (:line 0 :character 0)) :rangeLength = (1 . #) :text (1 . #)) (:range (:start (:line 0 :character 0) :end (:line 0 :character= 0)) :rangeLength 0 :text " ") (:range (:start (:line 0 :character 1) :end = (:line 0 :character 1)) :rangeLength 0 :text "\n") (:range (:start (:line 0= :character 0) :end (:line 0 :character 1)) :rangeLength 1 :text "") (:rang= e (:start (:line 0 :character 0) :end (:line 0 :character 0)) :rangeLength = 0 :text "\n") (:range (:start (:line 1 :character 0) :end (:line 1 :charact= er 0)) :rangeLength 0 :text "\n") (:range (:start (:line 1 :character 0) :e= nd (:line 2 :character 0)) :rangeLength 1 :text "") (:range (:start (:line = 0 :character 0) :end (:line 1 :character 0)) :rangeLength 1 :text "") (:ran= ge (:start (:line 0 :character 0) :end (:line 0 :character 0)) :rangeLength= 0 :text "\n")])) :false-object :json-false :null-object nil) > jsonrpc--json-encode((:jsonrpc "2.0" :method "textDocument/didChange" := params (:textDocument (:uri "file:///tmp/z.c" :version 8) :contentChanges [= (:range (:start (:line 0 :character 0) :end (:line 0 :character 0)) :rangeL= ength (1 . #) :text (1 . #)) (:range (:start (:line 0 :character 0) :end (:line 0 :cha= racter 0)) :rangeLength 0 :text " ") (:range (:start (:line 0 :character 1)= :end (:line 0 :character 1)) :rangeLength 0 :text "\n") (:range (:start (:= line 0 :character 0) :end (:line 0 :character 1)) :rangeLength 1 :text "") = (:range (:start (:line 0 :character 0) :end (:line 0 :character 0)) :rangeL= ength 0 :text "\n") (:range (:start (:line 1 :character 0) :end (:line 1 :c= haracter 0)) :rangeLength 0 :text "\n") (:range (:start (:line 1 :character= 0) :end (:line 2 :character 0)) :rangeLength 1 :text "") (:range (:start (= :line 0 :character 0) :end (:line 1 :character 0)) :rangeLength 1 :text "")= (:range (:start (:line 0 :character 0) :end (:line 0 :character 0)) :range= Length 0 :text "\n")]))) > #f(compiled-function (arg1 &rest rest) "Send MESSAGE, a JSON object, to= CONNECTION." #)(# :method :textDocument/didChange :params (:textDocument (:u= ri "file:///tmp/z.c" :version 8) :contentChanges [(:range (:start (:line 0 = :character 0) :end (:line 0 :character 0)) :rangeLength (1 . #) :text (1 . #)) (:range= (:start (:line 0 :character 0) :end (:line 0 :character 0)) :rangeLength 0= :text " ") (:range (:start (:line 0 :character 1) :end (:line 0 :character= 1)) :rangeLength 0 :text "\n") (:range (:start (:line 0 :character 0) :end= (:line 0 :character 1)) :rangeLength 1 :text "") (:range (:start (:line 0 = :character 0) :end (:line 0 :character 0)) :rangeLength 0 :text "\n") (:ran= ge (:start (:line 1 :character 0) :end (:line 1 :character 0)) :rangeLength= 0 :text "\n") (:range (:start (:line 1 :character 0) :end (:line 2 :charac= ter 0)) :rangeLength 1 :text "") (:range (:start (:line 0 :character 0) :en= d (:line 1 :character 0)) :rangeLength 1 :text "") (:range (:start (:line 0= :character 0) :end (:line 0 :character 0)) :rangeLength 0 :text "\n")])) > apply(#f(compiled-function (arg1 &rest rest) "Send MESSAGE, a JSON obje= ct, to CONNECTION." #) # (:method :textDocument/didChange :params (:textDocum= ent (:uri "file:///tmp/z.c" :version 8) :contentChanges [(:range (:start (:= line 0 :character 0) :end (:line 0 :character 0)) :rangeLength (1 . #) :text (1 . #)) = (:range (:start (:line 0 :character 0) :end (:line 0 :character 0)) :rangeL= ength 0 :text " ") (:range (:start (:line 0 :character 1) :end (:line 0 :ch= aracter 1)) :rangeLength 0 :text "\n") (:range (:start (:line 0 :character = 0) :end (:line 0 :character 1)) :rangeLength 1 :text "") (:range (:start (:= line 0 :character 0) :end (:line 0 :character 0)) :rangeLength 0 :text "\n"= ) (:range (:start (:line 1 :character 0) :end (:line 1 :character 0)) :rang= eLength 0 :text "\n") (:range (:start (:line 1 :character 0) :end (:line 2 = :character 0)) :rangeLength 1 :text "") (:range (:start (:line 0 :character= 0) :end (:line 1 :character 0)) :rangeLength 1 :text "") (:range (:start (= :line 0 :character 0) :end (:line 0 :character 0)) :rangeLength 0 :text "\n= ")]))) > jsonrpc-connection-send(# :m= ethod :textDocument/didChange :params (:textDocument (:uri "file:///tmp/z.c= " :version 8) :contentChanges [(:range (:start (:line 0 :character 0) :end = (:line 0 :character 0)) :rangeLength (1 . #) :text (1 .= #)) (:range (:start (:line 0 := character 0) :end (:line 0 :character 0)) :rangeLength 0 :text " ") (:range= (:start (:line 0 :character 1) :end (:line 0 :character 1)) :rangeLength 0= :text "\n") (:range (:start (:line 0 :character 0) :end (:line 0 :characte= r 1)) :rangeLength 1 :text "") (:range (:start (:line 0 :character 0) :end = (:line 0 :character 0)) :rangeLength 0 :text "\n") (:range (:start (:line 1= :character 0) :end (:line 1 :character 0)) :rangeLength 0 :text "\n") (:ra= nge (:start (:line 1 :character 0) :end (:line 2 :character 0)) :rangeLengt= h 1 :text "") (:range (:start (:line 0 :character 0) :end (:line 1 :charact= er 0)) :rangeLength 1 :text "") (:range (:start (:line 0 :character 0) :end= (:line 0 :character 0)) :rangeLength 0 :text "\n")])) > jsonrpc-notify(# :textDocume= nt/didChange (:textDocument (:uri "file:///tmp/z.c" :version 8) :contentCha= nges [(:range (:start (:line 0 :character 0) :end (:line 0 :character 0)) := rangeLength (1 . #) :text (1 . #)) (:range (:start (:line 0 :character 0) :end (:line = 0 :character 0)) :rangeLength 0 :text " ") (:range (:start (:line 0 :charac= ter 1) :end (:line 0 :character 1)) :rangeLength 0 :text "\n") (:range (:st= art (:line 0 :character 0) :end (:line 0 :character 1)) :rangeLength 1 :tex= t "") (:range (:start (:line 0 :character 0) :end (:line 0 :character 0)) := rangeLength 0 :text "\n") (:range (:start (:line 1 :character 0) :end (:lin= e 1 :character 0)) :rangeLength 0 :text "\n") (:range (:start (:line 1 :cha= racter 0) :end (:line 2 :character 0)) :rangeLength 1 :text "") (:range (:s= tart (:line 0 :character 0) :end (:line 1 :character 0)) :rangeLength 1 :te= xt "") (:range (:start (:line 0 :character 0) :end (:line 0 :character 0)) = :rangeLength 0 :text "\n")])) > (let* ((server (eglot--current-server-or-lose)) (sync-capability (eglot= -server-capable :textDocumentSync)) (sync-kind (if (numberp sync-capability= ) sync-capability (plist-get sync-capability :change))) (full-sync-p (or (e= q sync-kind 1) (eq :emacs-messup eglot--recent-changes)))) (jsonrpc-notify = server :textDocument/didChange (list :textDocument (eglot--VersionedTextDoc= umentIdentifier) :contentChanges (if full-sync-p (vector (list ':text (save= -excursion (save-restriction ... ...)))) (let* ((--cl-var-- (reverse eglot-= -recent-changes)) (beg nil) (end nil) (len nil) (text nil) (--cl-var--) (--= cl-var-- [])) (while (consp --cl-var--) (progn (setq --cl-var-- ...) (setq = beg ...) (setq end ...) (setq len ...) (setq text ...)) (setq --cl-var-- (v= concat --cl-var-- ...)) (setq --cl-var-- (cdr --cl-var--))) --cl-var--)))) = (setq eglot--recent-changes nil) (jsonrpc--call-deferred server)) > (progn (let* ((server (eglot--current-server-or-lose)) (sync-capability= (eglot-server-capable :textDocumentSync)) (sync-kind (if (numberp sync-cap= ability) sync-capability (plist-get sync-capability :change))) (full-sync-p= (or (eq sync-kind 1) (eq :emacs-messup eglot--recent-changes)))) (jsonrpc-= notify server :textDocument/didChange (list :textDocument (eglot--Versioned= TextDocumentIdentifier) :contentChanges (if full-sync-p (vector (list ':tex= t (save-excursion ...))) (let* ((--cl-var-- ...) (beg nil) (end nil) (len n= il) (text nil) (--cl-var--) (--cl-var-- ...)) (while (consp --cl-var--) (pr= ogn ... ... ... ... ...) (setq --cl-var-- ...) (setq --cl-var-- ...)) --cl-= var--)))) (setq eglot--recent-changes nil) (jsonrpc--call-deferred server))) > (if eglot--recent-changes (progn (let* ((server (eglot--current-server-= or-lose)) (sync-capability (eglot-server-capable :textDocumentSync)) (sync-= kind (if (numberp sync-capability) sync-capability (plist-get sync-capabili= ty :change))) (full-sync-p (or (eq sync-kind 1) (eq :emacs-messup eglot--re= cent-changes)))) (jsonrpc-notify server :textDocument/didChange (list :text= Document (eglot--VersionedTextDocumentIdentifier) :contentChanges (if full-= sync-p (vector (list ... ...)) (let* (... ... ... ... ... ... ...) (while .= .. ... ... ...) --cl-var--)))) (setq eglot--recent-changes nil) (jsonrpc--c= all-deferred server)))) > eglot--signal-textDocument/didChange() > (if immediate nil (eglot--signal-textDocument/didChange)) > (progn (if immediate nil (eglot--signal-textDocument/didChange)) (jsonr= pc-request server method params :timeout timeout :cancel-on-input (cond ((a= nd cancel-on-input eglot-advertise-cancellation) #'(lambda (id) (jsonrpc-no= tify server '$/cancelRequest (list ... id)))) (cancel-on-input)) :cancel-on= -input-retval cancel-on-input-retval)) > (progn (let ((--cl-keys-- --cl-rest--)) (while --cl-keys-- (cond ((memq= (car --cl-keys--) '(:immediate :timeout :cancel-on-input :cancel-on-input-= retval :allow-other-keys)) (if (cdr --cl-keys--) nil (error "Missing argume= nt for %s" (car --cl-keys--))) (setq --cl-keys-- (cdr (cdr --cl-keys--)))) = ((car (cdr (memq ... --cl-rest--))) (setq --cl-keys-- nil)) (t (error "Keyw= ord argument %s not one of (:immediate :timeout :cancel-on-input :cancel-on= -input-retval)" (car --cl-keys--)))))) (progn (if immediate nil (eglot--sig= nal-textDocument/didChange)) (jsonrpc-request server method params :timeout= timeout :cancel-on-input (cond ((and cancel-on-input eglot-advertise-cance= llation) #'(lambda (id) (jsonrpc-notify server ... ...))) (cancel-on-input)= ) :cancel-on-input-retval cancel-on-input-retval))) > (let* ((immediate (car (cdr (plist-member --cl-rest-- ':immediate)))) (= timeout (car (cdr (plist-member --cl-rest-- ':timeout)))) (cancel-on-input = (car (cdr (plist-member --cl-rest-- ':cancel-on-input)))) (cancel-on-input-= retval (car (cdr (plist-member --cl-rest-- ':cancel-on-input-retval))))) (p= rogn (let ((--cl-keys-- --cl-rest--)) (while --cl-keys-- (cond ((memq (car = --cl-keys--) '...) (if (cdr --cl-keys--) nil (error "Missing argument for %= s" ...)) (setq --cl-keys-- (cdr ...))) ((car (cdr ...)) (setq --cl-keys-- n= il)) (t (error "Keyword argument %s not one of (:immediate :timeout :cancel= -on-input :cancel-on-input-retval)" (car --cl-keys--)))))) (progn (if immed= iate nil (eglot--signal-textDocument/didChange)) (jsonrpc-request server me= thod params :timeout timeout :cancel-on-input (cond ((and cancel-on-input e= glot-advertise-cancellation) #'(lambda ... ...)) (cancel-on-input)) :cancel= -on-input-retval cancel-on-input-retval)))) > eglot--request(# :textDocume= nt/onTypeFormatting (:textDocument (:uri "file:///tmp/z.c") :options (:tabS= ize 8 :insertSpaces :json-false :insertFinalNewline t :trimFinalNewlines t)= :position (:line 1 :character 0) :ch "\n")) > (eglot--apply-text-edits (eglot--request (eglot--current-server-or-lose= ) method (cons :textDocument (cons (eglot--TextDocumentIdentifier) (cons :o= ptions (cons (list :tabSize tab-width :insertSpaces (if indent-tabs-mode :j= son-false t) :insertFinalNewline (if require-final-newline t :json-false) := trimFinalNewlines (if delete-trailing-lines t :json-false)) args))))) nil o= n-type-format) > (progn (eglot-server-capable-or-lose cap) (eglot--apply-text-edits (egl= ot--request (eglot--current-server-or-lose) method (cons :textDocument (con= s (eglot--TextDocumentIdentifier) (cons :options (cons (list :tabSize tab-w= idth :insertSpaces ... :insertFinalNewline ... :trimFinalNewlines ...) args= ))))) nil on-type-format)) > (let ((method x37) (cap x39) (args x41)) (progn (eglot-server-capable-o= r-lose cap) (eglot--apply-text-edits (eglot--request (eglot--current-server= -or-lose) method (cons :textDocument (cons (eglot--TextDocumentIdentifier) = (cons :options (cons ... args))))) nil on-type-format))) > (progn (ignore (null x42)) (let ((method x37) (cap x39) (args x41)) (pr= ogn (eglot-server-capable-or-lose cap) (eglot--apply-text-edits (eglot--req= uest (eglot--current-server-or-lose) method (cons :textDocument (cons (eglo= t--TextDocumentIdentifier) (cons :options ...)))) nil on-type-format)))) > (let* ((x41 (car-safe x40)) (x42 (cdr-safe x40))) (progn (ignore (null = x42)) (let ((method x37) (cap x39) (args x41)) (progn (eglot-server-capable= -or-lose cap) (eglot--apply-text-edits (eglot--request (eglot--current-serv= er-or-lose) method (cons :textDocument (cons ... ...))) nil on-type-format)= )))) > (progn (ignore (consp x40)) (let* ((x41 (car-safe x40)) (x42 (cdr-safe = x40))) (progn (ignore (null x42)) (let ((method x37) (cap x39) (args x41)) = (progn (eglot-server-capable-or-lose cap) (eglot--apply-text-edits (eglot--= request (eglot--current-server-or-lose) method (cons :textDocument ...)) ni= l on-type-format)))))) > (let* ((x39 (car-safe x38)) (x40 (cdr-safe x38))) (progn (ignore (consp= x40)) (let* ((x41 (car-safe x40)) (x42 (cdr-safe x40))) (progn (ignore (nu= ll x42)) (let ((method x37) (cap x39) (args x41)) (progn (eglot-server-capa= ble-or-lose cap) (eglot--apply-text-edits (eglot--request ... method ...) n= il on-type-format))))))) > (progn (ignore (consp x38)) (let* ((x39 (car-safe x38)) (x40 (cdr-safe = x38))) (progn (ignore (consp x40)) (let* ((x41 (car-safe x40)) (x42 (cdr-sa= fe x40))) (progn (ignore (null x42)) (let ((method x37) (cap x39) (args x41= )) (progn (eglot-server-capable-or-lose cap) (eglot--apply-text-edits ... n= il on-type-format)))))))) > (let* ((x37 (car-safe val)) (x38 (cdr-safe val))) (progn (ignore (consp= x38)) (let* ((x39 (car-safe x38)) (x40 (cdr-safe x38))) (progn (ignore (co= nsp x40)) (let* ((x41 (car-safe x40)) (x42 (cdr-safe x40))) (progn (ignore = (null x42)) (let (... ... ...) (progn ... ...)))))))) > (progn (ignore (consp val)) (let* ((x37 (car-safe val)) (x38 (cdr-safe = val))) (progn (ignore (consp x38)) (let* ((x39 (car-safe x38)) (x40 (cdr-sa= fe x38))) (progn (ignore (consp x40)) (let* ((x41 ...) (x42 ...)) (progn (i= gnore ...) (let ... ...)))))))) > (let* ((val (cond ((and beg on-type-format) (list ':textDocument/onType= Formatting ':documentOnTypeFormattingProvider (list ':position (eglot--pos-= to-lsp-position beg) ':ch (string on-type-format)))) ((and beg end) (list '= :textDocument/rangeFormatting ':documentRangeFormattingProvider (list ':ran= ge (list :start ... :end ...)))) (t '(:textDocument/formatting :documentFor= mattingProvider nil))))) (progn (ignore (consp val)) (let* ((x37 (car-safe = val)) (x38 (cdr-safe val))) (progn (ignore (consp x38)) (let* ((x39 (car-sa= fe x38)) (x40 (cdr-safe x38))) (progn (ignore (consp x40)) (let* (... ...) = (progn ... ...)))))))) > eglot-format(2 nil 10) > (progn (eglot-format (point) nil eglot--last-inserted-char)) > (if (and ot-provider (condition-case nil (progn (or (eq eglot--last-ins= erted-char (seq-first (plist-get ot-provider :firstTriggerCharacter))) (cl-= find eglot--last-inserted-char (plist-get ot-provider :moreTriggerCharacter= ) :key #'seq-first))) (error nil))) (progn (eglot-format (point) nil eglot-= -last-inserted-char))) > (let ((ot-provider (eglot-server-capable :documentOnTypeFormattingProvi= der))) (if (and ot-provider (condition-case nil (progn (or (eq eglot--last-= inserted-char (seq-first ...)) (cl-find eglot--last-inserted-char (plist-ge= t ot-provider :moreTriggerCharacter) :key #'seq-first))) (error nil))) (pro= gn (eglot-format (point) nil eglot--last-inserted-char)))) > eglot--post-self-insert-hook() > newline(nil 1) > funcall-interactively(newline nil 1) > command-execute(newline) > ``` >=20 >=20 > In GNU Emacs 30.1.50 (build 2, x86_64-pc-linux-gnu, X toolkit, cairo > version 1.15.12, Xaw scroll bars) of 2025-03-28 built on > igm-qws-u22796a > Repository revision: 3e6424e1f1816332e574035bc73143551a69efb6 > Windowing system distributor 'The X.Org Foundation', version 11.0.12011000 > System Description: Rocky Linux 8.10 (Green Obsidian) >=20 > Configured using: > 'configure --config-cache --with-x-toolkit=3Dlucid --without-gpm > --without-gconf --without-selinux --without-imagemagick --with-modules > --with-gif=3Dno --with-cairo --with-rsvg --without-compress-install > --with-tree-sitter --with-native-compilation=3Daot > --prefix=3D/usr/local/home/garnish/raw-emacs/30-20250328_130425' >=20 > Configured features: > CAIRO DBUS FREETYPE GLIB GMP GNUTLS GSETTINGS HARFBUZZ JPEG LIBSYSTEMD > LIBXML2 MODULES NATIVE_COMP NOTIFY INOTIFY PDUMPER PNG RSVG SECCOMP > SOUND SQLITE3 THREADS TIFF TOOLKIT_SCROLL_BARS TREE_SITTER X11 XDBE XIM > XINPUT2 XPM LUCID ZLIB >=20 > Important settings: > value of $LANG: en_US.utf8 > locale-coding-system: utf-8-unix >=20 > Major mode: Fundamental From debbugs-submit-bounces@debbugs.gnu.org Sat Apr 26 07:08:55 2025 Received: (at 77658) by debbugs.gnu.org; 26 Apr 2025 11:08:55 +0000 Received: from localhost ([127.0.0.1]:58637 helo=debbugs.gnu.org) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1u8dOw-00008f-0k for submit@debbugs.gnu.org; Sat, 26 Apr 2025 07:08:55 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:60174) by debbugs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.84_2) (envelope-from ) id 1u8dOt-00008K-4f for 77658@debbugs.gnu.org; Sat, 26 Apr 2025 07:08:52 -0400 Received: from fencepost.gnu.org ([2001:470:142:3::e]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1u8dOn-0005Ki-9p; Sat, 26 Apr 2025 07:08:45 -0400 DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=gnu.org; s=fencepost-gnu-org; h=MIME-Version:References:Subject:In-Reply-To:To:From: Date; bh=4SFt8M89Yngat4ka+6jeYiUiMKlG0QDPz33a/ll+ME8=; b=Ag1GJ0lPq0B1L5h0NKw3 PzCN8UXFoRw6e/0XICoDAduWNHeZEvFioD73rpqt9d2lXJQeh4K+PmYILRJdZpjdQPMtLhJ2BnLSQ ImnkegQhJZFRTsQiwYoMueK4nZW83QI4YzjeZ0QLMJdYkuUyFv/IjS8YwTpFB6a5PBnk/BfCCKWoR 9/VDvDYZ9UyiPBA+9CQNcwoaGJntMmB2qLLbKT1daTeH6m1bqZKMOIkFXvoPzQ+2Uew1pHzjBmTTi cbUIc2ez2CbZ4IvuWmXw4RVjhWXvWPSQo9ydqrgyn7NKJpjc47QOx1sE/5jJTITN+RT6GnYBNmN/A sWFdBUqgB+7YbQ==; Date: Sat, 26 Apr 2025 14:08:37 +0300 Message-Id: <86jz77uqmi.fsf@gnu.org> From: Eli Zaretskii To: azeng@janestreet.com, joaotavora@gmail.com In-Reply-To: <86o6x5sfi3.fsf@gnu.org> (message from Eli Zaretskii on Wed, 09 Apr 2025 15:09:40 +0300) Subject: Re: bug#77658: 30.1.50; Eglot: wrong-type-argument: consp, # when saving References: <86o6x5sfi3.fsf@gnu.org> MIME-Version: 1.0 Content-Type: text/plain; charset=iso-8859-1 Content-Transfer-Encoding: quoted-printable X-Spam-Score: -2.3 (--) X-Debbugs-Envelope-To: 77658 Cc: 77658@debbugs.gnu.org, app-emacs-dev@janestreet.com X-BeenThere: debbugs-submit@debbugs.gnu.org X-Mailman-Version: 2.1.18 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: debbugs-submit-bounces@debbugs.gnu.org Sender: "Debbugs-submit" X-Spam-Score: -3.3 (---) Ping! Jo=E3o, any suggestions or comments? > Cc: 77658@debbugs.gnu.org, app-emacs-dev@janestreet.com > Date: Wed, 09 Apr 2025 15:09:40 +0300 > From: Eli Zaretskii >=20 > > Cc: app-emacs-dev@janestreet.com > > Date: Tue, 08 Apr 2025 18:05:27 -0400 > > From: Aaron Zeng via "Bug reports for GNU Emacs, > > the Swiss army knife of text editors" > >=20 > >=20 > > When saving an empty buffer, and while `before-save-hook` has some func= tion for reformatting the buffer (such as an auto-styler), the following er= ror is issued: > >=20 > > ``` > > Error running timer: (wrong-type-argument consp #>) > > ``` > >=20 > > This error can also happen synchronously in `basic-save-buffer` rather = than in a timer. >=20 > Adding Jo=E3o. >=20 > > Reproduction recipe: > >=20 > > With `~/src/emacs/trunk` checked out to `9663c959c73d6cca0c56f833d80ff1= d9e9708b70`: > >=20 > > 1. emacs -Q -l ~/src/emacs/trunk/lisp/progmodes/eglot.el > > 2. Evaluate the following code: > >=20 > > ```emacs-lisp > > (add-hook 'before-save-hook #'no-op-file-formatter) > >=20 > > (defun no-op-file-formatter () > > (let ((temp-file (make-temp-file "no-op-file-formatter"))) > > (save-restriction > > (widen) > > (write-region nil nil temp-file) > > (insert-file-contents temp-file nil nil nil 'replace)))) > > ``` > >=20 > > This adds a dummy "reformatter" to `before-save-hook` that is always a = no-op. > >=20 > > 3. `C-x C-f /tmp/z.c` > > 4. `M-x eglot` (clangd must be installed, I suppose) > > 5. Make some trivial edits, then `C-x h DEL` to erase the buffer conten= ts > > 6. `C-x C-s` > >=20 > > An error is issued as described above. Also, since `eglot--recent-chan= ges` now includes a malformatted entry, random other things break, too, for= example just inserting a space character. Backtrace included below. > >=20 > > I believe what is happening here, is that `insert-file-contents`, when = inserting an empty file into an empty buffer (maybe in other situations as = well), may cause `before-change-functions` to be run but `after-change-func= tions` never runs. Therefore, `eglot--before-changes` inserts an element i= nto `eglot--recent-changes` that `eglot--after-changes` never gets a chance= to fix up. > >=20 > > According to the manual (https://www.gnu.org/software/emacs/manual/html= _node/elisp/Change-Hooks.html), this is allowed to happen (i.e., `after-cha= nge-functions` might not always run after a change). > >=20 > > Backtrace for eglot--post-self-insert-hook: > > ``` > > Debugger entered--Lisp error: (wrong-type-argument consp #) > > json-serialize((:jsonrpc "2.0" :method "textDocument/didChange" :para= ms (:textDocument (:uri "file:///tmp/z.c" :version 8) :contentChanges [(:ra= nge (:start (:line 0 :character 0) :end (:line 0 :character 0)) :rangeLengt= h (1 . #) :text (1 . #)) (:range (:start (:line 0 :character 0) :end (:line 0 :charact= er 0)) :rangeLength 0 :text " ") (:range (:start (:line 0 :character 1) :en= d (:line 0 :character 1)) :rangeLength 0 :text "\n") (:range (:start (:line= 0 :character 0) :end (:line 0 :character 1)) :rangeLength 1 :text "") (:ra= nge (:start (:line 0 :character 0) :end (:line 0 :character 0)) :rangeLengt= h 0 :text "\n") (:range (:start (:line 1 :character 0) :end (:line 1 :chara= cter 0)) :rangeLength 0 :text "\n") (:range (:start (:line 1 :character 0) = :end (:line 2 :character 0)) :rangeLength 1 :text "") (:range (:start (:lin= e 0 :character 0) :end (:line 1 :character 0)) :rangeLength 1 :text "") (:r= ange (:start (:line 0 :character 0) :end (:line 0 :character 0)) :rangeLeng= th 0 :text "\n")])) :false-object :json-false :null-object nil) > > jsonrpc--json-encode((:jsonrpc "2.0" :method "textDocument/didChange"= :params (:textDocument (:uri "file:///tmp/z.c" :version 8) :contentChanges= [(:range (:start (:line 0 :character 0) :end (:line 0 :character 0)) :rang= eLength (1 . #) :text (1 . #)) (:range (:start (:line 0 :character 0) :end (:line 0 :c= haracter 0)) :rangeLength 0 :text " ") (:range (:start (:line 0 :character = 1) :end (:line 0 :character 1)) :rangeLength 0 :text "\n") (:range (:start = (:line 0 :character 0) :end (:line 0 :character 1)) :rangeLength 1 :text ""= ) (:range (:start (:line 0 :character 0) :end (:line 0 :character 0)) :rang= eLength 0 :text "\n") (:range (:start (:line 1 :character 0) :end (:line 1 = :character 0)) :rangeLength 0 :text "\n") (:range (:start (:line 1 :charact= er 0) :end (:line 2 :character 0)) :rangeLength 1 :text "") (:range (:start= (:line 0 :character 0) :end (:line 1 :character 0)) :rangeLength 1 :text "= ") (:range (:start (:line 0 :character 0) :end (:line 0 :character 0)) :ran= geLength 0 :text "\n")]))) > > #f(compiled-function (arg1 &rest rest) "Send MESSAGE, a JSON object, = to CONNECTION." #)(# :method :textDocument/didChange :params (:textDocument (= :uri "file:///tmp/z.c" :version 8) :contentChanges [(:range (:start (:line = 0 :character 0) :end (:line 0 :character 0)) :rangeLength (1 . #) :text (1 . #)) (:ran= ge (:start (:line 0 :character 0) :end (:line 0 :character 0)) :rangeLength= 0 :text " ") (:range (:start (:line 0 :character 1) :end (:line 0 :charact= er 1)) :rangeLength 0 :text "\n") (:range (:start (:line 0 :character 0) :e= nd (:line 0 :character 1)) :rangeLength 1 :text "") (:range (:start (:line = 0 :character 0) :end (:line 0 :character 0)) :rangeLength 0 :text "\n") (:r= ange (:start (:line 1 :character 0) :end (:line 1 :character 0)) :rangeLeng= th 0 :text "\n") (:range (:start (:line 1 :character 0) :end (:line 2 :char= acter 0)) :rangeLength 1 :text "") (:range (:start (:line 0 :character 0) := end (:line 1 :character 0)) :rangeLength 1 :text "") (:range (:start (:line= 0 :character 0) :end (:line 0 :character 0)) :rangeLength 0 :text "\n")])) > > apply(#f(compiled-function (arg1 &rest rest) "Send MESSAGE, a JSON ob= ject, to CONNECTION." #) # (:method :textDocument/didChange :params (:textDoc= ument (:uri "file:///tmp/z.c" :version 8) :contentChanges [(:range (:start = (:line 0 :character 0) :end (:line 0 :character 0)) :rangeLength (1 . #) :text (1 . #)= ) (:range (:start (:line 0 :character 0) :end (:line 0 :character 0)) :rang= eLength 0 :text " ") (:range (:start (:line 0 :character 1) :end (:line 0 := character 1)) :rangeLength 0 :text "\n") (:range (:start (:line 0 :characte= r 0) :end (:line 0 :character 1)) :rangeLength 1 :text "") (:range (:start = (:line 0 :character 0) :end (:line 0 :character 0)) :rangeLength 0 :text "\= n") (:range (:start (:line 1 :character 0) :end (:line 1 :character 0)) :ra= ngeLength 0 :text "\n") (:range (:start (:line 1 :character 0) :end (:line = 2 :character 0)) :rangeLength 1 :text "") (:range (:start (:line 0 :charact= er 0) :end (:line 1 :character 0)) :rangeLength 1 :text "") (:range (:start= (:line 0 :character 0) :end (:line 0 :character 0)) :rangeLength 0 :text "= \n")]))) > > jsonrpc-connection-send(# = :method :textDocument/didChange :params (:textDocument (:uri "file:///tmp/z= .c" :version 8) :contentChanges [(:range (:start (:line 0 :character 0) :en= d (:line 0 :character 0)) :rangeLength (1 . #) :text (1= . #)) (:range (:start (:line 0= :character 0) :end (:line 0 :character 0)) :rangeLength 0 :text " ") (:ran= ge (:start (:line 0 :character 1) :end (:line 0 :character 1)) :rangeLength= 0 :text "\n") (:range (:start (:line 0 :character 0) :end (:line 0 :charac= ter 1)) :rangeLength 1 :text "") (:range (:start (:line 0 :character 0) :en= d (:line 0 :character 0)) :rangeLength 0 :text "\n") (:range (:start (:line= 1 :character 0) :end (:line 1 :character 0)) :rangeLength 0 :text "\n") (:= range (:start (:line 1 :character 0) :end (:line 2 :character 0)) :rangeLen= gth 1 :text "") (:range (:start (:line 0 :character 0) :end (:line 1 :chara= cter 0)) :rangeLength 1 :text "") (:range (:start (:line 0 :character 0) :e= nd (:line 0 :character 0)) :rangeLength 0 :text "\n")])) > > jsonrpc-notify(# :textDocu= ment/didChange (:textDocument (:uri "file:///tmp/z.c" :version 8) :contentC= hanges [(:range (:start (:line 0 :character 0) :end (:line 0 :character 0))= :rangeLength (1 . #) :text (1 . #)) (:range (:start (:line 0 :character 0) :end (:lin= e 0 :character 0)) :rangeLength 0 :text " ") (:range (:start (:line 0 :char= acter 1) :end (:line 0 :character 1)) :rangeLength 0 :text "\n") (:range (:= start (:line 0 :character 0) :end (:line 0 :character 1)) :rangeLength 1 :t= ext "") (:range (:start (:line 0 :character 0) :end (:line 0 :character 0))= :rangeLength 0 :text "\n") (:range (:start (:line 1 :character 0) :end (:l= ine 1 :character 0)) :rangeLength 0 :text "\n") (:range (:start (:line 1 :c= haracter 0) :end (:line 2 :character 0)) :rangeLength 1 :text "") (:range (= :start (:line 0 :character 0) :end (:line 1 :character 0)) :rangeLength 1 := text "") (:range (:start (:line 0 :character 0) :end (:line 0 :character 0)= ) :rangeLength 0 :text "\n")])) > > (let* ((server (eglot--current-server-or-lose)) (sync-capability (egl= ot-server-capable :textDocumentSync)) (sync-kind (if (numberp sync-capabili= ty) sync-capability (plist-get sync-capability :change))) (full-sync-p (or = (eq sync-kind 1) (eq :emacs-messup eglot--recent-changes)))) (jsonrpc-notif= y server :textDocument/didChange (list :textDocument (eglot--VersionedTextD= ocumentIdentifier) :contentChanges (if full-sync-p (vector (list ':text (sa= ve-excursion (save-restriction ... ...)))) (let* ((--cl-var-- (reverse eglo= t--recent-changes)) (beg nil) (end nil) (len nil) (text nil) (--cl-var--) (= --cl-var-- [])) (while (consp --cl-var--) (progn (setq --cl-var-- ...) (set= q beg ...) (setq end ...) (setq len ...) (setq text ...)) (setq --cl-var-- = (vconcat --cl-var-- ...)) (setq --cl-var-- (cdr --cl-var--))) --cl-var--)))= ) (setq eglot--recent-changes nil) (jsonrpc--call-deferred server)) > > (progn (let* ((server (eglot--current-server-or-lose)) (sync-capabili= ty (eglot-server-capable :textDocumentSync)) (sync-kind (if (numberp sync-c= apability) sync-capability (plist-get sync-capability :change))) (full-sync= -p (or (eq sync-kind 1) (eq :emacs-messup eglot--recent-changes)))) (jsonrp= c-notify server :textDocument/didChange (list :textDocument (eglot--Version= edTextDocumentIdentifier) :contentChanges (if full-sync-p (vector (list ':t= ext (save-excursion ...))) (let* ((--cl-var-- ...) (beg nil) (end nil) (len= nil) (text nil) (--cl-var--) (--cl-var-- ...)) (while (consp --cl-var--) (= progn ... ... ... ... ...) (setq --cl-var-- ...) (setq --cl-var-- ...)) --c= l-var--)))) (setq eglot--recent-changes nil) (jsonrpc--call-deferred server= ))) > > (if eglot--recent-changes (progn (let* ((server (eglot--current-serve= r-or-lose)) (sync-capability (eglot-server-capable :textDocumentSync)) (syn= c-kind (if (numberp sync-capability) sync-capability (plist-get sync-capabi= lity :change))) (full-sync-p (or (eq sync-kind 1) (eq :emacs-messup eglot--= recent-changes)))) (jsonrpc-notify server :textDocument/didChange (list :te= xtDocument (eglot--VersionedTextDocumentIdentifier) :contentChanges (if ful= l-sync-p (vector (list ... ...)) (let* (... ... ... ... ... ... ...) (while= ... ... ... ...) --cl-var--)))) (setq eglot--recent-changes nil) (jsonrpc-= -call-deferred server)))) > > eglot--signal-textDocument/didChange() > > (if immediate nil (eglot--signal-textDocument/didChange)) > > (progn (if immediate nil (eglot--signal-textDocument/didChange)) (jso= nrpc-request server method params :timeout timeout :cancel-on-input (cond (= (and cancel-on-input eglot-advertise-cancellation) #'(lambda (id) (jsonrpc-= notify server '$/cancelRequest (list ... id)))) (cancel-on-input)) :cancel-= on-input-retval cancel-on-input-retval)) > > (progn (let ((--cl-keys-- --cl-rest--)) (while --cl-keys-- (cond ((me= mq (car --cl-keys--) '(:immediate :timeout :cancel-on-input :cancel-on-inpu= t-retval :allow-other-keys)) (if (cdr --cl-keys--) nil (error "Missing argu= ment for %s" (car --cl-keys--))) (setq --cl-keys-- (cdr (cdr --cl-keys--)))= ) ((car (cdr (memq ... --cl-rest--))) (setq --cl-keys-- nil)) (t (error "Ke= yword argument %s not one of (:immediate :timeout :cancel-on-input :cancel-= on-input-retval)" (car --cl-keys--)))))) (progn (if immediate nil (eglot--s= ignal-textDocument/didChange)) (jsonrpc-request server method params :timeo= ut timeout :cancel-on-input (cond ((and cancel-on-input eglot-advertise-can= cellation) #'(lambda (id) (jsonrpc-notify server ... ...))) (cancel-on-inpu= t)) :cancel-on-input-retval cancel-on-input-retval))) > > (let* ((immediate (car (cdr (plist-member --cl-rest-- ':immediate))))= (timeout (car (cdr (plist-member --cl-rest-- ':timeout)))) (cancel-on-inpu= t (car (cdr (plist-member --cl-rest-- ':cancel-on-input)))) (cancel-on-inpu= t-retval (car (cdr (plist-member --cl-rest-- ':cancel-on-input-retval))))) = (progn (let ((--cl-keys-- --cl-rest--)) (while --cl-keys-- (cond ((memq (ca= r --cl-keys--) '...) (if (cdr --cl-keys--) nil (error "Missing argument for= %s" ...)) (setq --cl-keys-- (cdr ...))) ((car (cdr ...)) (setq --cl-keys--= nil)) (t (error "Keyword argument %s not one of (:immediate :timeout :canc= el-on-input :cancel-on-input-retval)" (car --cl-keys--)))))) (progn (if imm= ediate nil (eglot--signal-textDocument/didChange)) (jsonrpc-request server = method params :timeout timeout :cancel-on-input (cond ((and cancel-on-input= eglot-advertise-cancellation) #'(lambda ... ...)) (cancel-on-input)) :canc= el-on-input-retval cancel-on-input-retval)))) > > eglot--request(# :textDocu= ment/onTypeFormatting (:textDocument (:uri "file:///tmp/z.c") :options (:ta= bSize 8 :insertSpaces :json-false :insertFinalNewline t :trimFinalNewlines = t) :position (:line 1 :character 0) :ch "\n")) > > (eglot--apply-text-edits (eglot--request (eglot--current-server-or-lo= se) method (cons :textDocument (cons (eglot--TextDocumentIdentifier) (cons = :options (cons (list :tabSize tab-width :insertSpaces (if indent-tabs-mode = :json-false t) :insertFinalNewline (if require-final-newline t :json-false)= :trimFinalNewlines (if delete-trailing-lines t :json-false)) args))))) nil= on-type-format) > > (progn (eglot-server-capable-or-lose cap) (eglot--apply-text-edits (e= glot--request (eglot--current-server-or-lose) method (cons :textDocument (c= ons (eglot--TextDocumentIdentifier) (cons :options (cons (list :tabSize tab= -width :insertSpaces ... :insertFinalNewline ... :trimFinalNewlines ...) ar= gs))))) nil on-type-format)) > > (let ((method x37) (cap x39) (args x41)) (progn (eglot-server-capable= -or-lose cap) (eglot--apply-text-edits (eglot--request (eglot--current-serv= er-or-lose) method (cons :textDocument (cons (eglot--TextDocumentIdentifier= ) (cons :options (cons ... args))))) nil on-type-format))) > > (progn (ignore (null x42)) (let ((method x37) (cap x39) (args x41)) (= progn (eglot-server-capable-or-lose cap) (eglot--apply-text-edits (eglot--r= equest (eglot--current-server-or-lose) method (cons :textDocument (cons (eg= lot--TextDocumentIdentifier) (cons :options ...)))) nil on-type-format)))) > > (let* ((x41 (car-safe x40)) (x42 (cdr-safe x40))) (progn (ignore (nul= l x42)) (let ((method x37) (cap x39) (args x41)) (progn (eglot-server-capab= le-or-lose cap) (eglot--apply-text-edits (eglot--request (eglot--current-se= rver-or-lose) method (cons :textDocument (cons ... ...))) nil on-type-forma= t))))) > > (progn (ignore (consp x40)) (let* ((x41 (car-safe x40)) (x42 (cdr-saf= e x40))) (progn (ignore (null x42)) (let ((method x37) (cap x39) (args x41)= ) (progn (eglot-server-capable-or-lose cap) (eglot--apply-text-edits (eglot= --request (eglot--current-server-or-lose) method (cons :textDocument ...)) = nil on-type-format)))))) > > (let* ((x39 (car-safe x38)) (x40 (cdr-safe x38))) (progn (ignore (con= sp x40)) (let* ((x41 (car-safe x40)) (x42 (cdr-safe x40))) (progn (ignore (= null x42)) (let ((method x37) (cap x39) (args x41)) (progn (eglot-server-ca= pable-or-lose cap) (eglot--apply-text-edits (eglot--request ... method ...)= nil on-type-format))))))) > > (progn (ignore (consp x38)) (let* ((x39 (car-safe x38)) (x40 (cdr-saf= e x38))) (progn (ignore (consp x40)) (let* ((x41 (car-safe x40)) (x42 (cdr-= safe x40))) (progn (ignore (null x42)) (let ((method x37) (cap x39) (args x= 41)) (progn (eglot-server-capable-or-lose cap) (eglot--apply-text-edits ...= nil on-type-format)))))))) > > (let* ((x37 (car-safe val)) (x38 (cdr-safe val))) (progn (ignore (con= sp x38)) (let* ((x39 (car-safe x38)) (x40 (cdr-safe x38))) (progn (ignore (= consp x40)) (let* ((x41 (car-safe x40)) (x42 (cdr-safe x40))) (progn (ignor= e (null x42)) (let (... ... ...) (progn ... ...)))))))) > > (progn (ignore (consp val)) (let* ((x37 (car-safe val)) (x38 (cdr-saf= e val))) (progn (ignore (consp x38)) (let* ((x39 (car-safe x38)) (x40 (cdr-= safe x38))) (progn (ignore (consp x40)) (let* ((x41 ...) (x42 ...)) (progn = (ignore ...) (let ... ...)))))))) > > (let* ((val (cond ((and beg on-type-format) (list ':textDocument/onTy= peFormatting ':documentOnTypeFormattingProvider (list ':position (eglot--po= s-to-lsp-position beg) ':ch (string on-type-format)))) ((and beg end) (list= ':textDocument/rangeFormatting ':documentRangeFormattingProvider (list ':r= ange (list :start ... :end ...)))) (t '(:textDocument/formatting :documentF= ormattingProvider nil))))) (progn (ignore (consp val)) (let* ((x37 (car-saf= e val)) (x38 (cdr-safe val))) (progn (ignore (consp x38)) (let* ((x39 (car-= safe x38)) (x40 (cdr-safe x38))) (progn (ignore (consp x40)) (let* (... ...= ) (progn ... ...)))))))) > > eglot-format(2 nil 10) > > (progn (eglot-format (point) nil eglot--last-inserted-char)) > > (if (and ot-provider (condition-case nil (progn (or (eq eglot--last-i= nserted-char (seq-first (plist-get ot-provider :firstTriggerCharacter))) (c= l-find eglot--last-inserted-char (plist-get ot-provider :moreTriggerCharact= er) :key #'seq-first))) (error nil))) (progn (eglot-format (point) nil eglo= t--last-inserted-char))) > > (let ((ot-provider (eglot-server-capable :documentOnTypeFormattingPro= vider))) (if (and ot-provider (condition-case nil (progn (or (eq eglot--las= t-inserted-char (seq-first ...)) (cl-find eglot--last-inserted-char (plist-= get ot-provider :moreTriggerCharacter) :key #'seq-first))) (error nil))) (p= rogn (eglot-format (point) nil eglot--last-inserted-char)))) > > eglot--post-self-insert-hook() > > newline(nil 1) > > funcall-interactively(newline nil 1) > > command-execute(newline) > > ``` > >=20 > >=20 > > In GNU Emacs 30.1.50 (build 2, x86_64-pc-linux-gnu, X toolkit, cairo > > version 1.15.12, Xaw scroll bars) of 2025-03-28 built on > > igm-qws-u22796a > > Repository revision: 3e6424e1f1816332e574035bc73143551a69efb6 > > Windowing system distributor 'The X.Org Foundation', version 11.0.12011= 000 > > System Description: Rocky Linux 8.10 (Green Obsidian) > >=20 > > Configured using: > > 'configure --config-cache --with-x-toolkit=3Dlucid --without-gpm > > --without-gconf --without-selinux --without-imagemagick --with-modules > > --with-gif=3Dno --with-cairo --with-rsvg --without-compress-install > > --with-tree-sitter --with-native-compilation=3Daot > > --prefix=3D/usr/local/home/garnish/raw-emacs/30-20250328_130425' > >=20 > > Configured features: > > CAIRO DBUS FREETYPE GLIB GMP GNUTLS GSETTINGS HARFBUZZ JPEG LIBSYSTEMD > > LIBXML2 MODULES NATIVE_COMP NOTIFY INOTIFY PDUMPER PNG RSVG SECCOMP > > SOUND SQLITE3 THREADS TIFF TOOLKIT_SCROLL_BARS TREE_SITTER X11 XDBE XIM > > XINPUT2 XPM LUCID ZLIB > >=20 > > Important settings: > > value of $LANG: en_US.utf8 > > locale-coding-system: utf-8-unix > >=20 > > Major mode: Fundamental >=20 >=20 >=20 >=20 From debbugs-submit-bounces@debbugs.gnu.org Sat Apr 26 07:51:17 2025 Received: (at 77658) by debbugs.gnu.org; 26 Apr 2025 11:51:17 +0000 Received: from localhost ([127.0.0.1]:58941 helo=debbugs.gnu.org) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1u8e3w-0005kJ-PO for submit@debbugs.gnu.org; Sat, 26 Apr 2025 07:51:17 -0400 Received: from mail-oo1-xc2a.google.com ([2607:f8b0:4864:20::c2a]:44119) by debbugs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.84_2) (envelope-from ) id 1u8e3t-0005jo-Mm for 77658@debbugs.gnu.org; Sat, 26 Apr 2025 07:51:14 -0400 Received: by mail-oo1-xc2a.google.com with SMTP id 006d021491bc7-603f54a6cb5so2117697eaf.0 for <77658@debbugs.gnu.org>; Sat, 26 Apr 2025 04:51:13 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1745668267; x=1746273067; darn=debbugs.gnu.org; h=content-transfer-encoding:cc:to:subject:message-id:date:from :in-reply-to:references:mime-version:from:to:cc:subject:date :message-id:reply-to; bh=+AAMI5hS5Yb3pXLukhvaUCaVQU4WdJvCZgIO/loDarM=; b=Dvux9LNQCVl/9vz926+Ya6AvIvdPkeRWspVgASc0ZTgopoLkfAGnZMUicFUw5CeBme OiyQbS0Grea9KbdfogReywEYFKusJyqsxQ7r0yXsSnoEw2h5rEF3dVqDoDsMHoT2MaLJ SE7d8yjVvzLJZgAsMW6QkquNT+SgNEJnveKKaJlkUODsoqA9rE4vQJ5PXXwGNcYsP5H6 uitmRXMoqODr1IeA5JIsqBRrfP2JoYUQjecKhhSZbJRMOcGuQatKE/fE1+rh5WTCNMOC 02wzW0UF6926joQ+JVMcAU+fgPV6M9xIePChD0FOMlEPVotAKdIK85FcGRAh4H28o3wZ Ab8w== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1745668267; x=1746273067; h=content-transfer-encoding:cc:to:subject:message-id:date:from :in-reply-to:references:mime-version:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=+AAMI5hS5Yb3pXLukhvaUCaVQU4WdJvCZgIO/loDarM=; b=vEG+SF0NfD2yNfqmRXycjyBDiaTW5CSCEIsrxbLFmnueOQ5y8mb/ibyd+Xs4NrlQjm hJlwuYPJX0Z7qGfMMbNvvwej2C8TL1D/mPU/c6Ys03MA+15P4DqeeQVtGpmZWT0IZuMH 3X4DbbqrRfb2kutknlbsJBVkVRrq6rCIIO9qY7qWFN0s/6AJkWw1whYL/DAkiCeheQ8B 9TcQHXewwggDC8RLu892ExGw8rfusJpAddIf2S0shNeGB92Z0KS/DKUh62bcqhYxMuvs 1EeSWkWvKEJHd5F0Pw0c9TVH4ZkbT3kizH0jwhvnYd+POAwDTxuWB0aZwsA+55So7wV1 TrNA== X-Forwarded-Encrypted: i=1; AJvYcCWiMs7LMXwYRHKj3vdy1Gf7PxfH4sYVWEzDGhBJjzDbvD97+amjwf+ilAYntIQAGhAZDgzWCQ==@debbugs.gnu.org X-Gm-Message-State: AOJu0YxRQJwaEe6oHiF81dAYIxrD2JscbMk+o7/MKxvs6pyb+vqbDXUe iYV3UaRYhEYh05QZc7nOIR5hzbbEGpnef3sQu5Z6AS9Le/Xp6FgVHm2kr28gBA2w+tC8OyIsZ2G 8Zd2MLzdqvtKEcST89/59YoB9GtI= X-Gm-Gg: ASbGncsKRN4aTqCYw5/2g2+Ol+P3PU5bE4+rN1KyGF6RTZIPB8WpxwVx2reWze7XueS ndFyqVD/MDFEmVrDWAywBMufOZ30/VvLTddWAU087fvDpESYOneQGO9w3LB+J20yuLpRSH9bFA9 +t6XIoQxYRdjSbJrJheZC8hP/cB7LUA27E X-Google-Smtp-Source: AGHT+IGBSr6Ms3g+lfKzIVioZLok3Y5YkRobi8lT22lMwyRm52+IfzhVXhUIgJ+ujDbZHSVdjRsKRGe2VmouJDCD8Ro= X-Received: by 2002:a05:6870:80ce:b0:2b3:55b3:e38 with SMTP id 586e51a60fabf-2d9a3382fc0mr3039875fac.21.1745668267438; Sat, 26 Apr 2025 04:51:07 -0700 (PDT) MIME-Version: 1.0 References: <86o6x5sfi3.fsf@gnu.org> <86jz77uqmi.fsf@gnu.org> In-Reply-To: <86jz77uqmi.fsf@gnu.org> From: =?UTF-8?B?Sm/Do28gVMOhdm9yYQ==?= Date: Sat, 26 Apr 2025 12:51:35 +0100 X-Gm-Features: ATxdqUEEOCuTW7Z3bwweLimmnEdyoAo2Hjbi533hMBJcyn_ziM4XPDyn1IUOgUY Message-ID: Subject: Re: bug#77658: 30.1.50; Eglot: wrong-type-argument: consp, # when saving To: Eli Zaretskii , Stefan Monnier Content-Type: text/plain; charset="UTF-8" Content-Transfer-Encoding: quoted-printable X-Spam-Score: 0.0 (/) X-Debbugs-Envelope-To: 77658 Cc: 77658@debbugs.gnu.org, app-emacs-dev@janestreet.com, azeng@janestreet.com X-BeenThere: debbugs-submit@debbugs.gnu.org X-Mailman-Version: 2.1.18 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: debbugs-submit-bounces@debbugs.gnu.org Sender: "Debbugs-submit" X-Spam-Score: -1.0 (-) On Sat, Apr 26, 2025 at 12:08=E2=80=AFPM Eli Zaretskii wrote= : > > Ping! Jo=C3=A3o, any suggestions or comments? I think Aaron is on the right track by identifying this as a mismatch between before-change-functions and after-change-functions. This seems to happen in a (rather extreme?) edge case where the full buffer's contents are replaced just before saving. It looks like a bug in the b-c-fns and a-c-fns, and there are a number of those that eglot.el already recognizes and fixes. Stefan Monnier has written a library to try to smooth over these bugs and provide a better API to clients, but that some problems in itself so I recently removed it. I don't know if it had support for fixing this particular bug. I could re-add it, but I think the root problem should be clearly identified before. The ideal fix, in my view, is for the b-c-fns and a-c-fns to be fixed so that they are more predictable. In the meantime, I wonder if completely disabling the modification hooks around the `insert-file-contents` wouldn't be a suitable workaround. There would, of course, be no change notification Eglot -> LSPserver, except for Eglot stating it has saved the file to disk, which most LSPs usually interpret as a hint to go read from the disk. Jo=C3=A3o From debbugs-submit-bounces@debbugs.gnu.org Sun Apr 27 00:11:57 2025 Received: (at 77658) by debbugs.gnu.org; 27 Apr 2025 04:11:57 +0000 Received: from localhost ([127.0.0.1]:37617 helo=debbugs.gnu.org) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1u8tMz-0008Om-4h for submit@debbugs.gnu.org; Sun, 27 Apr 2025 00:11:57 -0400 Received: from mailscanner.iro.umontreal.ca ([132.204.25.50]:50810) by debbugs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.84_2) (envelope-from ) id 1u8tMv-0008OT-6d for 77658@debbugs.gnu.org; Sun, 27 Apr 2025 00:11:55 -0400 Received: from pmg1.iro.umontreal.ca (localhost.localdomain [127.0.0.1]) by pmg1.iro.umontreal.ca (Proxmox) with ESMTP id ACB4E10006B; Sun, 27 Apr 2025 00:11:46 -0400 (EDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=iro.umontreal.ca; s=mail; t=1745727101; bh=t2oLVjGt7ZnXAuc65hmwyia8sgKFjwOjQH5ui6drWTI=; h=From:To:Cc:Subject:In-Reply-To:References:Date:From; b=MPmQHrhc4+7SdW5Ywdh83+8ZJ4HeIdJOOgHh7Iwv7LLpafIy9jWScvtDLmRJuae5d F1CAL0UzrybZCGn3VxujCtOSwHe12CQNSQwxoWWDleg29Q8cwL4hdjCS6PNF/dNvi9 0OScFUMPMZrjw8xaGlGCM7jLgzOXaJWPpbw2TCV8CIWSLzNeRxe3UO4YhGDa386J27 JGbXVoNg9no0cqxCE8otlrZBUt5za2S0oS9HV6KjWGrtBoIHcr/CXdSnqfo1SNdzWX vx9vySTIFRJegVe27sMoLfPQxKQ5anHHAqwlvP7T56qo8BJeTCnz0xEtpeXM+kHd60 MtsfT1OF++Dxw== Received: from mail01.iro.umontreal.ca (unknown [172.31.2.1]) by pmg1.iro.umontreal.ca (Proxmox) with ESMTP id B596210002E; Sun, 27 Apr 2025 00:11:41 -0400 (EDT) Received: from alfajor (104-195-232-56.cpe.teksavvy.com [104.195.232.56]) by mail01.iro.umontreal.ca (Postfix) with ESMTPSA id 8037112076B; Sun, 27 Apr 2025 00:11:41 -0400 (EDT) From: Stefan Monnier To: Aaron Zeng Subject: Re: bug#77658: 30.1.50; Eglot: wrong-type-argument: consp, # when saving In-Reply-To: Message-ID: References: Date: Sun, 27 Apr 2025 00:11:32 -0400 User-Agent: Gnus/5.13 (Gnus v5.13) MIME-Version: 1.0 Content-Type: text/plain; charset=iso-8859-1 Content-Transfer-Encoding: quoted-printable X-SPAM-INFO: Spam detection results: 0 ALL_TRUSTED -1 Passed through trusted hosts only via SMTP AWL -0.214 Adjusted score from AWL reputation of From: address BAYES_00 -1.9 Bayes spam probability is 0 to 1% DKIM_SIGNED 0.1 Message has a DKIM or DK signature, not necessarily valid DKIM_VALID -0.1 Message has at least one valid DKIM or DK signature DKIM_VALID_AU -0.1 Message has a valid DKIM or DK signature from author's domain DKIM_VALID_EF -0.1 Message has a valid DKIM or DK signature from envelope-from domain X-SPAM-LEVEL: X-Spam-Score: -2.3 (--) X-Debbugs-Envelope-To: 77658 Cc: 77658@debbugs.gnu.org, app-emacs-dev@janestreet.com X-BeenThere: debbugs-submit@debbugs.gnu.org X-Mailman-Version: 2.1.18 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: debbugs-submit-bounces@debbugs.gnu.org Sender: "Debbugs-submit" X-Spam-Score: -3.3 (---) > I believe what is happening here, is that `insert-file-contents`, when > inserting an empty file into an empty buffer (maybe in other > situations as well), may cause `before-change-functions` to be run but > `after-change-functions` never runs. Therefore, > `eglot--before-changes` inserts an element into > `eglot--recent-changes` that `eglot--after-changes` never gets > a chance to fix up. Indeed, `insert-file-contents` does not run `after-change-functions` if it does not actually modify the buffer, whereas it does always run `before-change-functions`. You can verify that for yourself with: (defvar-local my-changes nil) (add-hook 'after-change-functions (lambda (&rest args) (push `(after . ,args) my-changes))) (add-hook 'before-change-functions (lambda (&rest args) (push `(before . ,args) my-changes))) and then do `M-: (insert-file-contents "/dev/null") RET` and check the value of `my-changes`. As you noted, this is not considered as a bug. So, the problem is on Eglot's side because it makes sadly invalid assumptions about how before and after change-functions are paired. The Track-Changes library should handle this case correctly, AFAIK. It might be worth trying out your recipe with an Eglot that uses that library (again). Stefan PS: I hope at some point Jo=E3o will reconsider his decision to not use Track-Changes, although I understand his motivation: while Eglot doesn't benefit much from Track-Changes because Eglot has already gone through most of the pain of handling the corner cases of `before/after-change-functions`, Track-Changes (and other users of `before/after-change-functions`) would benefit from Eglot using it because Eglot is used widely and because Track-Changes comes with extensive sanity checks to detect when `before/after-change-functions` are not run correctly (in which case it can report those problems, and it also knows how to recover from them). Furthermore it also records extensive data about the circumstances of those problems, to help find their origin.