Skip to content

Instantly share code, notes, and snippets.

@c4710n
Last active February 26, 2023 05:50
Show Gist options
  • Save c4710n/2af6d219c1588a45caf7a3a4dac408b2 to your computer and use it in GitHub Desktop.
Save c4710n/2af6d219c1588a45caf7a3a4dac408b2 to your computer and use it in GitHub Desktop.
Alternative elixir-format in Emacs
(require 'reformatter)
(defcustom elixir-format--extra-args nil
"Extra arguments to pass to mix."
:group 'elixir-format
:type '(repeat string))
(defun elixir-format--mix-executable ()
(executable-find "mix"))
(defun elixir-format--stdin-filename-args ()
(list "--stdin-filename" (file-name-nondirectory (buffer-file-name))))
(defun elixir-format--dot-formatter-args ()
(let ((project-root (project-current))
(dot-formatter-dir (locate-dominating-file buffer-file-name ".formatter.exs")))
(if (and project-root dot-formatter-dir)
(list "--dot-formatter"
(concat dot-formatter-dir ".formatter.exs"))
nil)))
(defun elixir-format--make-args ()
(append
'("format")
(elixir-format--stdin-filename-args)
(elixir-format--dot-formatter-args)
elixir-format--extra-args
'("-")))
;; inspired by https://github.com/purcell/emacs-reformatter/issues/13#issuecomment-549128423
(reformatter-define elixir-format
:program (elixir-format--mix-executable)
:args (elixir-format--make-args))
(defun reformatter-elixir-format--get-default-directory ()
(locate-dominating-file buffer-file-name "mix.exs"))
(provide 'elixir-format)
(use-package reformatter
:ensure t
:init
(defun my-reformatter--do-region (orig-func &rest args)
"Provides a way to change default-directory before formatting the region.
This is useful for some formatters, such as `mix format' of Elixir."
(let* ((formatter-name (car args))
(formatter-get-default-directory (intern (format "reformatter-%s--get-default-directory" formatter-name))))
(cond ((fboundp formatter-get-default-directory)
(let ((original-default-directory default-directory)
(changed-default-directory (funcall formatter-get-default-directory)))
(if changed-default-directory
(progn
(setq default-directory (expand-file-name changed-default-directory))
(apply orig-func args)
(setq default-directory original-default-directory))
(apply orig-func args))))
(t (apply orig-func args)))))
(advice-add 'reformatter--do-region :around #'my-reformatter--do-region))
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment