lsp writing compile output to file on save
I confirm that...
- [X] I have searched the issue tracker, documentation, FAQ, Discourse, and Google, in case this issue has already been reported/resolved.
- [X] I have read "How to Debug Issues", and will use it to provide as much information about this issue as possible.
- [X] The issue can be reproduced on the latest available commit of Doom.
- [X] The issue can be reproduced on a stable release of Emacs, such as 27, 28, or 29. (Unstable versions end in .50, .60, or .9x)
Expected behavior
When I save a file that has lsp mode , it should do the standard lsp things, format etc. but it should not insert compiler output into the file.
Current behavior
Currently when I save a file there is a non zero change it will insert text into my file after it does its standard changes.
Steps to reproduce
configure elixir +lsp in emacs, this occurs with lsp-mode as well as eglot and with lexical and elixir-lsp so any of these configs will be fine. Open an elixir project. make any trivial edit and save. as it saves it rebuilds the project and formats. often it will insert some of this compile into the file buffer and saves an example
defmodule ApiWeb.Controller do
==> api
Compiling 2 files (.ex)
Generated api app
==> web_support
Compiling 4 files (.ex)
Generated web_support app
use ApiWeb, :controller
everything between the defmodule and the use line was inserted from the compiler.
System Information
https://pastebin.com/YRYHRqZ8
Two things to try:
- Does
M-x apheleia-format-bufferinsert compile info into the buffer? - Disable
+format-with-lsp-mode(withM-x +format-with-lsp-mode) then tryM-x apheleia-format-bufferagain. Does the behavior persist?
Another thing to try (with +format-with-lsp-mode enabled):
;;; add to $DOOMDIR/config.el
(defadvice! fixed+format--with-eglot (&rest plist)
:override #'+format--with-eglot
(with-current-buffer (plist-get plist :buffer)
(or (with-demoted-errors "%s"
(always (eglot-format (point-min) (point-max))))
;; try next chained formatter(s)
(ignore (funcall (plist-get plist :callback))))))
Does M-x apheleia-format-buffer insert compile info into the buffer?
I was able to reproduce it by calling that by hand.
Disable +format-with-lsp-mode (with M-x +format-with-lsp-mode) then try M-x apheleia-format-buffer again. Does the behavior persist?
behavior persisted. although i am not sure format-with-lsp-mode was disabled globally and i had a lot of files opened
the bit you gave me seems to solve issue in eglot mode, would something similar work in lsp?
the bit you gave me seems to solve issue in eglot mode, would something similar work in lsp?
Try this out:
;;; add to $DOOMDIR/config.el
(defadvice! fixed+format--with-lsp-mode (&rest plist)
:override #'+format--with-lsp-mode
(catch 'result
(with-current-buffer (plist-get plist :buffer)
(let ((edits
(cond ((lsp-feature? "textDocument/formatting")
(lsp-request "textDocument/formatting"
(lsp--make-document-formatting-params)))
((lsp-feature? "textDocument/rangeFormatting")
(lsp-request "textDocument/rangeFormatting"
(lsp--make-document-range-formatting-params
(point-min) (point-max))))
;; try next chained formatter(s)
((throw 'result (ignore (funcall (plist-get plist :callback))))))))
(unless (seq-empty-p edits)
(lsp--apply-text-edits edits 'format))
t))))
i spoke too soon. error still happens with eglot
anything else i could try?
I can confirm this happens already since quite a while for me. But chances for this to happen are so rare that it is really hard to say if things are fixed when changing anything.
I can confirm this happens to me also in elixir files. I do not think it happens in other files. But what I've discovered is that code inserted only when formatted:
+format-with-lsp-mode DISABLED
- +format/buffer - Inserts compile output after defmodule line
- lsp-format-buffer - Works perfectly fine
- Saving file inserts garbage. I assume +format/buffer is ran on save
+format-with-lsp-mode ENABLED
- +format/buffer - Works perfectly fine
- lsp-format-buffer - Works perfectly fine
- Saving file formats buffer fine
How do I enable format-with-lsp-mode to true everywhere by default?
How do I enable format-with-lsp-mode to true everywhere by default?
I guess you just need the +lsp flag for the onsave format.
(format +onsave +lsp)
I haven't seen the issue anymore since I added that one, so I think it is connected to apheleia-format-buffer.
I guess you just need the
+lspflag for the onsave format.
Awesome this worked. thank you!
I think the issue is that apheleia uses mix format --stdin-filename - and feeds the output back into the file. But when deps are not compiled yet mix format runs compilation which has output. Not sure if it is possible to suppress the output there somehow...
I created a PR for aphelia in order to run the compilation in quiet mode:
https://github.com/radian-software/apheleia/pull/326
Getting the same issue with Elixir files
Getting the same issue with Elixir files
Are you already on the latest doom? The patch for aphelia landed in 4.3, which was bumped in doom 3 weeks ago https://github.com/doomemacs/doomemacs/commit/7032e5797fc69f2300ca6383ea8eb5649c49ecd2
Yes, updated today
I fixed it with (format +onsave +lsp) but I think it should not happen even without it, right?
generated Jan 30, 2025 17:01:18
system MacOS 15.2 Darwin 24.2.0 arm64 ns
emacs 30.0.93 HEAD 232003012 EMACSDIR=~/.emacs.d/
EMACS=/Applications/Emacs.app/Contents/MacOS/Emacs
doom 3.0.0-pre PROFILE=_default@0 HEAD -> master 2bc052425 2025-01-14 13:57:18
-0500 ~/.doom.d/
shell /bin/zsh
features ACL DBUS GIF GLIB GMP GNUTLS JPEG LCMS2 LIBXML2 MODULES NATIVE_COMP NOTIFY
KQUEUE NS PDUMPER PNG RSVG SQLITE3 THREADS TIFF TOOLKIT_SCROLL_BARS
TREE_SITTER WEBP XIM XWIDGETS ZLIB
traits gui server-running envvar-file custom-file
custom connection-local-criteria-alist connection-local-profile-alist
package-selected-packages
modules :config use-package :completion (corfu +orderless) vertico :ui doom
doom-dashboard doom-quit hl-todo modeline ophints (popup +defaults)
(treemacs +lsp) (vc-gutter +pretty) vi-tilde-fringe workspaces :editor
(evil +everywhere) file-templates fold (format +onsave +lsp) snippets
:emacs dired electric undo vc :term eshell vterm :checkers syntax :tools
(eval +overlay) lookup (lsp +peek) magit tree-sitter :os macos :lang
common-lisp (elixir +lsp +tree-sitter) emacs-lisp (go +lsp) (javascript
+lsp) markdown org (rust +lsp +tree-sitter) sh (web +html +css +lsp) yaml
:config (default +bindings +smartparens)
packages (expand-region) (terminal-here) (heex-ts-mode)
elpa eglot
I fixed it with
(format +onsave +lsp)but I think it should not happen even without it, right?
Ideally it should not happen anymore. So for you still compile output ended up in the buffer with the latest version of doom? Just to confirm.
yes, It appears to do it only if the file has some issue (minor too) A perfectly correct file is ok.
@fnicastri yeah was hitting the same thing - after doing some digging it appears that MIX_QUIET=1 still emits some warnings during compilation
.e.g.
> MIX_QUIET=1 mix compile
==> package
warning: variable "var" is unused
at first i thought the fix might be updating the apheleia mix format script to also send stderr to /dev/null but if you redirect stderr you'll see that the ==> package part is going to stdout while just warnings go to stderr
> MIX_QUIET=1 mix compile 2>/dev/null
==> package
so this really feels like a mix issue if anything
for now my approach has been to resolve compile warnings