Function: apheleia--formatter-context
apheleia--formatter-context is a natively compiled function defined in
apheleia-formatters.el.
Signature
(apheleia--formatter-context NAME COMMAND REMOTE &optional STDIN-BUFFER)
Documentation
Construct a formatter context for the formatter with NAME and COMMAND.
Returns an apheleia-formatter--context(var)/apheleia-formatter--context(fun) object on success and nil if
the formatter is not executable. The returned formatter context may
have some state such as temporary files that the caller is expected
to cleanup.
STDIN-BUFFER is the optional buffer to use when creating a temporary
file for the formatters standard input. REMOTE asserts whether the
buffer being formatted is on a remote machine or the local machine.
See apheleia--run-formatters for more details on the usage of REMOTE.
If COMMAND uses the symbol file and the current buffer is modified
from what is written to disk, then return nil meaning meaning no
cmd is to be run.
Source Code
;; Defined in /nix/store/lwcwryzabcmvjcwwzzs65jrwf7p7d7cs-emacs-packages-deps/share/emacs/site-lisp/elpa/apheleia-20260915.1628/apheleia-formatters.el
(defun apheleia--formatter-context (name command remote &optional stdin-buffer)
"Construct a formatter context for the formatter with NAME and COMMAND.
Returns an `apheleia-formatter--context' object on success and nil if
the formatter is not executable. The returned formatter context may
have some state such as temporary files that the caller is expected
to cleanup.
STDIN-BUFFER is the optional buffer to use when creating a temporary
file for the formatters standard input. REMOTE asserts whether the
buffer being formatted is on a remote machine or the local machine.
See `apheleia--run-formatters' for more details on the usage of REMOTE.
If COMMAND uses the symbol `file' and the current buffer is modified
from what is written to disk, then return nil meaning meaning no
cmd is to be run."
(cl-block nil
(let* ((context (apheleia-formatter--context))
(run-on-remote
(when (eq apheleia-remote-algorithm 'remote)
remote))
;; Whether the machine the process will run on matches
;; the machine the buffer/file is currently on. Either
;; we're running remotely and the buffer is remote or
;; we're not running remotely and the buffer is not
;; remote.
(remote-match (equal run-on-remote remote))
(stdin (or stdin-buffer (current-buffer)))
(command (apply #'list command)))
(setf (apheleia-formatter--name context) name)
(setf (apheleia-formatter--stdin context) stdin)
(setf (apheleia-formatter--remote context) remote)
;; TODO: Support arbitrary package managers, not just NPM.
(when (memq 'npx command)
(setq command (remq 'npx command))
(when remote-match
(when-let* ((project-dir
(locate-dominating-file default-directory
"node_modules")))
(let ((binary
(expand-file-name
(car command)
(expand-file-name
".bin"
(expand-file-name "node_modules" project-dir)))))
(when (file-executable-p binary)
(setcar command binary))))))
(when (or (memq 'file command) (memq 'filepath command))
;; Fail when using file but not as the first formatter in this
;; sequence. (But filepath is okay, since it indicates content
;; is not actually being read from the named file.)
(when (memq 'file command)
(when stdin-buffer
(error "Cannot run formatter using `file' in a sequence unless \
it's first in the sequence"))
(unless remote-match
(error "Formatter uses `file' but process will run on different \
machine from the machine file is available on"))
(setq stdin nil)
;; If `buffer-file-name' is nil then there is no backing
;; file, so `buffer-modified-p' should be ignored (it always
;; returns non-nil).
(when (and (buffer-modified-p) buffer-file-name)
(cl-return)))
;; We always strip out the remote-path prefix for file/filepath.
(let ((file-name (apheleia-formatters-local-buffer-file-name
(or buffer-file-name
(concat default-directory
(apheleia--safe-buffer-name))))))
(setq command (apheleia--replq command '(file filepath) file-name))))
(when (or (memq 'input command) (memq 'inplace command))
(let ((input-fname (apheleia--make-temp-file
run-on-remote "apheleia" nil
(when-let* ((file-name
(or buffer-file-name
(apheleia--safe-buffer-name))))
(file-name-extension file-name 'period)))))
(with-current-buffer stdin
(apheleia--write-region-silently nil nil input-fname))
(setf (apheleia-formatter--input-fname context) input-fname
(apheleia-formatter--stdin context) nil)
;; Inplace is the same as input but the output file is the
;; input file.
(when (memq 'inplace command)
(setf (apheleia-formatter--output-fname context) input-fname))
(setq command (apheleia--replq
command '(input inplace)
(apheleia-formatters-local-buffer-file-name
input-fname)))))
(when (memq 'output command)
(let ((output-fname (apheleia--make-temp-file
run-on-remote "apheleia")))
(setf (apheleia-formatter--output-fname context) output-fname)
(setq command (apheleia--replq
command 'output
(apheleia-formatters-local-buffer-file-name
output-fname)))))
;; Evaluate each element of arg that isn't a string and replace
;; it with the evaluated value. The result of an evaluation should
;; be a string or a list of strings. If the former its replaced as
;; is. If the latter the contents of the list is substituted in
;; place.
(setq command
(cl-loop
for arg in command
with val = nil
do (setq val (if (stringp arg)
arg
(eval arg)))
if val
if (and (consp val)
(cl-every #'stringp val))
append val
else if (stringp val)
collect val
else do (error "Result of command evaluation must be a string \
or list of strings: %S" arg)))
;; Windows fails to run formatter scripts. Check whether the
;; command executable is a script that contains a shebang. Parse
;; the shebang and insert the binary into the command.
(when (member system-type '(ms-dos windows-nt))
(when-let* ((arg1-file (locate-file (car command) exec-path)))
(with-temp-buffer
(insert-file-contents arg1-file nil 0 2)
(when (string= (buffer-string) "#!")
;; Assumes that the full shebang is max 200 characters
(insert-file-contents arg1-file nil 2 200 t)
(let* ((shebang-components (split-string (thing-at-point 'line)))
(shebang-binary
(if (string= (car shebang-components) "/usr/bin/env")
(cdr shebang-components)
(last (split-string (car shebang-components) "/")))))
(setq command (append shebang-binary
(list arg1-file)
(cdr command))))))))
(setf (apheleia-formatter--arg1 context) (car command)
(apheleia-formatter--argv context) (cdr command))
context)))