elixir-editors / emacs-elixir

Emacs major mode for Elixir
446 stars 94 forks source link

-emacs-elixir-format.ex files left behind when using format hook #497

Closed J3RN closed 1 year ago

J3RN commented 1 year ago

I'm surprised this hasn't been reported before as I've seen coworkers gripe about this.

When using before-save-hook to run elixir-format, like so:

(add-hook 'before-save-hook 'elixir-format nil 'local)

If the formatting fails, an <original_name>-emacs-elixir-format.ex file is left in the same directory as the file for which formatting was attempted. For whatever reason, this does not appear to happen when elixir-format is invoked manually.

viniciussbs commented 1 year ago

I can confirm. The same thing happening here.

victorolinasc commented 1 year ago

The current format code is sub-optimal I believe. I myself don't use it. I prefer the reformatter package calling the mix format directly.

An example configuration is here:

(use-package reformatter
  :config
  (reformatter-define +elixir-format
    :program "mix"
    :args '("format" "-"))

  (defun +set-default-directory-to-mix-project-root (original-fun &rest args)
    (if-let* ((mix-project-root (and buffer-file-name
                                     (locate-dominating-file buffer-file-name
                                                             ".formatter.exs"))))
        (let ((default-directory mix-project-root))
          (apply original-fun args))
      (apply original-fun args)))
  (advice-add '+elixir-format-region :around #'+set-default-directory-to-mix-project-root)

  (add-hook 'elixir-mode-hook #'+elixir-format-on-save-mode))

This will not leave other buffers.

But that was before I switched to Emacs 29 with eglot. It has a built-in format function that calls the language server and it is what is working best for me (and faster). Currently, after setting up eglot with elixir-ls, all I do is:

(use-package
 elixir-ts-mode
 :hook (elixir-ts-mode . eglot-ensure)
 (before-save . eglot-format))

I am leaving this here for references only and will try to take a look at the format code for solving this anyway.

Even if I am not successful, I will probably add a "Tips and tricks" session for configuring other tools and extensions to make life with Elixir in Emacs better.