       (\"-xml\" (memq major-mode '(nxml-mode xml-mode))))
     :ok-statuses '(0 1)))
 
-  (set-formatter! 'elm-mode
+  (set-formatter! 'elm-format
     \"elm-format --yes --stdin\"
-    :install '(macos \"brew install elm\")
     :filter
     (lambda (output errput first-diff)
       (list output
             (format-all-remove-ansi-color errput)
             first-diff)))"
   (declare (indent defun))
-  (cl-check-type name (or symbol null))
-  ;; Determine if MODES-OR-NAME means MODES or NAMES
-  (if (and (symbolp modes-or-name)
-           (not (string-match-p "-mode$" (symbol-name modes-or-name))))
-      (setq name modes-or-name)
-    (setq modes (doom-enlist modes-or-name)))
-  (let* ((command-list (cond ((stringp formatter)   ; shell command
-                              (split-string formatter " " t))
-                             ((listp formatter)     ; shell command in lists
-                              formatter)))
-         (name (cond (name)
-                     ((car command-list) (intern (car command-list)))
-                     ((symbolp formatter) formatter)
-                     ((user-error "Anonymous formatter requires a :name"))))
-         (formatter
-          (cond ((commandp formatter)
-                 `(format-all-buffer-thunk
-                   (lambda (input)
-                     (with-silent-modifications
-                       (setq buffer-file-name ,(buffer-file-name (buffer-base-buffer))
-                             default-directory ,default-directory)
-                       (delay-mode-hooks (funcall ',major-mode))
-                       (insert input)
-                       (condition-case e
-                           (progn (call-interactively #',formatter)
-                                  (list nil ""))
-                         (error (list t (error-message-string e))))))))
-                ((functionp formatter)
-                 `(format-all-buffer-thunk #',formatter))
-                (`(let (args)
-                    (dolist (arg ',command-list)
-                      (cond ((stringp arg) (push arg args))
-                            ((listp arg)
-                             (catch 'skip
-                               (let (subargs this)
-                                 (while (setq this (pop arg))
-                                   (cond ((not (stringp (car arg)))
-                                          (let ((val (eval (pop arg) t)))
-                                            (unless val (throw 'skip nil))
-                                            (push (format this val) subargs)))
-                                         ((stringp this)
-                                          (push this subargs))))
-                                 (setq args (append subargs args)))))))
-                    (if ,(and (or ok-statuses error-regexp) t)
-                        (apply #'format-all-buffer-hard
-                               ',ok-statuses ,error-regexp
-                               (reverse args))
-                      (apply #'format-all-buffer-easy (reverse args)))))))
-         (fn
+  (cl-check-type name symbol)
+  (after! format-all
+    (if (null formatter)
+        (+format--set name
+          :unset t
+          :modes modes)
+      (let ((fn (funcall (cond ((stringp formatter)
+                                #'+format--make-shell-command)
+                               ((listp formatter)
+                                #'+format--make-shell-command-list)
+                               ((and (commandp formatter)
+                                     (not (stringp formatter)))
+                                #'+format--make-command)
+                               ((functionp formatter)
+                                #'+format--make-function))
+                         formatter
+                         ok-statuses
+                         error-regexp)))
+        (cl-check-type filter (or function null))
+        (+format--set name
+          :function
           `(lambda (executable mode-result)
-             (let ((result ,formatter))
-               ,(if filter
-                    `(apply #',filter result)
-                  'result))))
-         (install (cond ((null install) install)
-                        ((listp install)
-                         (cdr (assq (+format--resolve-system) install)))
-                        (install))))
-    (after! format-all
-      (puthash name (eval fn t) format-all-format-table)
-      (puthash name (car command-list) format-all-executable-table)
-      (puthash name (or install (gethash name format-all-install-table))
-               format-all-install-table)
-      (dolist (mode (doom-enlist modes))
-        (cl-destructuring-bind (m &optional probe)
-            (doom-enlist mode)
-          (format-all-pushhash
-           m (cons name (if probe `(lambda () ,probe)))
-           format-all-mode-table))))
-    name))
+             ,(if filter `(apply #',filter ,fn) fn))
+          :modes modes)
+        name))))

           else if (eql +format-system-type (car choice))
           return (cadr choice)))

;;;###autodef
(cl-defun set-formatter!
    (modes-or-name formatter
                   &key
                   name
                   modes
                   install
                   filter
                   ok-statuses
                   error-regexp)
  "Define a formatter.

MODES-OR-NAME can either be a major mode symbol (or list thereof), a unique name
for the formatter being defined (also a symbol), or a special list of
two-element sublists with the structure: (MAJOR-MODE FORM).

FORM is evaluated when the buffer is formatted and its return value serves two
purposes:

1. It is a predicate for this formatter. Assuming the MAJOR-MODE matches the
   current mode, if FORM evaluates to nil, the formatter is skipped.
2. It's return value is made available to FORMATTER if it is a function or list
   of shell arguments via the `mode-result' variable.

FORMATTER can be a function, string or nested list.

  If a function, it should be a formatter function that
    `format-all-buffer-thunk' will accept.


Basic examples:

  (set-formatter! 'asmfmt \"asmfmt\" :modes '(asm-mode nasm-mode))
  (set-formatter! 'black \"black -q -\")
  (set-formatter! 'html-tidy \"tidy -q -indent\" :modes '(html-mode web-mode))

Advanced examples:

  (set-formatter!
    'clang-format
    '(\"clang-format\"
      (\"-assume-filename=%S\" (or buffer-file-name mode-result \"\")))
    :modes
    '((c-mode \".c\")
      (c++-mode \".cpp\")
      (java-mode \".java\")
      (objc-mode \".m\")
      (protobuf-mode \".proto\")))

  (set-formatter! 'html-tidy
    '(\"tidy\" \"-q\" \"-indent\"
      (\"-xml\" (memq major-mode '(nxml-mode xml-mode))))
    :modes
    '(html-mode
      (web-mode (and (equal \"none\" web-mode-engine)
                     (car (member web-mode-content-type '(\"xml\" \"html\"))))))
    :ok-statuses '(0 1)
    :executable \"tidy\")

  (set-formatter! 'html-tidy  ; overwrite predefined html-tidy formatter
    '(\"tidy\" \"-q\" \"-indent\"
