[#23] Support in-place formatters

This commit is contained in:
Radon Rosborough 2022-01-04 16:21:10 -08:00
parent 826d462bd5
commit cbffa9298c
2 changed files with 41 additions and 22 deletions

View file

@ -26,6 +26,10 @@ The format is based on [Keep a Changelog].
* You can now use a Lisp function as a formatter, by providing a
symbol or lambda in `apheleia-formatters` rather than a list of
strings ([#62]).
* Formatters that operate on files in place are now supported, by
using the symbol `inplace` in an entry on `apheleia-formatters` to
stand in for the name of a temporary file that will be modified in
place by the formatter ([#23]).
## Formatters
* [fish\_indent](https://fishshell.com/docs/current/cmds/fish_indent.html)
@ -45,6 +49,7 @@ The format is based on [Keep a Changelog].
* When a formatter cannot be found, orphaned stderr processes are no
longer created and left around forever ([#47]).
[#23]: https://github.com/raxod502/apheleia/issues/23
[#47]: https://github.com/raxod502/apheleia/issues/47
[#52]: https://github.com/raxod502/apheleia/issues/52
[#60]: https://github.com/raxod502/apheleia/issues/60

View file

@ -560,7 +560,7 @@ cmd is to be run."
project-dir)))))
(when (file-executable-p binary)
(setcar command binary)))))
(when (memq 'input command)
(when (or (memq 'input command) (memq 'inplace command))
(let ((input-fname (make-temp-file
"apheleia" nil
(when-let ((file-name
@ -570,10 +570,12 @@ cmd is to be run."
(with-current-buffer stdin
(apheleia--write-region-silently nil nil input-fname))
(setq command (mapcar (lambda (arg)
(if (eq arg 'input)
(if (memq arg '(input inplace))
input-fname
arg))
command))))
command))
(when (memq 'inplace command)
(setq output-fname input-fname))))
(when (memq 'output command)
(setq output-fname (make-temp-file "apheleia"))
(setq command (mapcar (lambda (arg)
@ -581,11 +583,11 @@ cmd is to be run."
output-fname
arg))
command)))
(when (or (memq 'file command) (memq 'filepath command))
(when (memq 'file command)
;; Fail when using file but not as the first formatter in this
;; sequence.
(when stdin-buffer
(error "Cannot run formatter using `file' or `filepath' in a \
(error "Cannot run formatter using `file' in a \
sequence unless it's first in the sequence"))
(let ((file-name (or buffer-file-name
(concat default-directory
@ -714,23 +716,35 @@ called when formatting is finished; and another callback that
should be called when an error was raised during formatting.
Otherwise in Lisp code, the format of commands is similar to what
you pass to `make-process', except as follows. Normally, the contents
of the current buffer are passed to the command on stdin, and the
output is read from stdout. However, if you use the symbol `file' as
one of the elements of commands, then the filename of the current
buffer is substituted for it. (Use `filepath' instead of `file' if you
need the filename of the current buffer, but you still want its
contents to be passed on stdin.) If you instead use the symbol `input'
as one of the elements of commands, then the contents of the current
buffer are written to a temporary file and its name is substituted for
`input'. Also, if you use the symbol `output' as one of the elements
of commands, then it is substituted with the name of a temporary file.
In that case, it is expected that the command writes to that file, and
the file is then read into an Emacs buffer. Finally, if you use the
symbol `npx' as one of the elements of commands, then the first string
element of the command list is resolved inside node_modules/.bin if
such a directory exists anywhere above the current
`default-directory'."
you pass to `make-process', except as follows.
Normally, the contents of the current buffer are passed to the
command on stdin, and the output is read from stdout. However, if
you use the symbol `file' as one of the elements of commands,
then the filename of the current buffer is substituted for
it. (Use `filepath' instead of `file' if you need the filename of
the current buffer, but you still want its contents to be passed
on stdin.)
If you instead use the symbol `input' as one of the elements of
commands, then the contents of the current buffer are written to
a temporary file and its name is substituted for `input'. Also,
if you use the symbol `output' as one of the elements of
commands, then it is substituted with the name of a temporary
file. In that case, it is expected that the command writes to
that file, and the file is then read into an Emacs buffer.
If you use the symbol `inplace' as one of the elements of the
list, then the contents of the current buffer are written to a
temporary file and its name is substituted for `inplace'.
However, unlike `input', it is expected that the formatter write
the formatted file back to the same file in place. In other
words, `inplace' is like `input' and `output' together.
If you use the symbol `npx' as one of the elements of commands,
then the first string element of the command list is resolved
inside node_modules/.bin if such a directory exists anywhere
above the current `default-directory'."
:type '(alist
:key-type symbol
:value-type