156 lines
5.2 KiB
Markdown
156 lines
5.2 KiB
Markdown
would-reformat - automatic reformatting for emacs (and maybe other editors) without being annoying
|
|
|
|
# Motivation
|
|
|
|
I've never liked it when a text editor formats code for me without my asking.
|
|
I don't like it when the editor uses cheap heuristics (indent a new line to
|
|
match the previous one? blah!) and I don't like it when the editor shells out
|
|
to one of the new generation of automatic code formatters.
|
|
|
|
But I don't enjoy formatting code by hand either. Who does?
|
|
|
|
This is my solution: some shell scripts and some emacs lisp code.
|
|
|
|
The shell script `would-reformat.sh` takes a file's full path as
|
|
its argument. It tells you if that file would be reformatted.
|
|
|
|
The shell script `do-reformat.sh` takes a file's full path as its argument. It
|
|
reformats the file.
|
|
|
|
Finally, there is some rudimentary machinery to run `would-reformat.sh` when
|
|
saving a file and to run `do-reformat.sh` when you hit `<F1>`.
|
|
|
|
## Supported programming languages and file formats
|
|
|
|
<!-- please keep this list sorted alphabetically -->
|
|
|
|
- css
|
|
- dart
|
|
- go
|
|
- html
|
|
- javascript
|
|
- jsx
|
|
- php
|
|
- python
|
|
- scss
|
|
- sh
|
|
- tsx
|
|
- typescript
|
|
- vue
|
|
|
|
Out of the box, for python we use `isort` and `black`, for go we use `gofmt`,
|
|
for dart we use `dart format`, for rust we use `rustfmt`, and for everything
|
|
else we use `prettier`.
|
|
|
|
Adding suuport for other programming languages is easy, assuming they have a
|
|
formatter with a dry run mode. And even if they don't it shouldn't be that
|
|
bad.
|
|
|
|
# Installation
|
|
|
|
- Change to the directory where you want to use `would-reformat`:
|
|
`you@host:~ $ cd ~/devel/my-project`
|
|
- From that directory, call the script `install.sh` in the directory where
|
|
you have `would-reformat` checked out:
|
|
`you@host:~/devel/my-project $ ~/src/would-reformat/install.sh`
|
|
|
|
Be sure to run the installation script from the root of your project's
|
|
directory, not a subdirectory.
|
|
|
|
This will do the following:
|
|
|
|
- create the directory `~/devel/my-project/bin` if it does not exist
|
|
- create `~/devel/my-project/bin/_reformat-common.sh`,
|
|
`~/devel/my-project/bin/do-reformat.sh`, and
|
|
`~/devel/my-project/bin/would-reformat.sh` as symlinks to files with
|
|
the same names in `~/src/would-reformat`.
|
|
- create `~/devel/my-project/.dir-locals.el` as a symlink to the file
|
|
with the same name in `~/src/would-reformat`.
|
|
|
|
This should work from a checkout wherever you happen to have it. It doesn't
|
|
need to be in `~/src`. However, if you remove the checkout, then the symlinks
|
|
will break, so don't do that. If you rename the checkout, the symlinks will
|
|
break.
|
|
|
|
The directory `bin` with respect to `my-project` however is hardcoded
|
|
(enhancements here are welcome).
|
|
|
|
The script `install.sh` favors conservatism over cleverness: for example,
|
|
if it finds the file `~/devel/my-project/bin/do-reformat.sh` then it
|
|
checks whether it is a symlink to `~/src/would-reformat/do-reformat.sh`.
|
|
If it is not, then it just prints a warning rather than attempting to correct
|
|
the situation.
|
|
|
|
FIXME: Document how to reinstall if the checkout was moved, incompatible
|
|
changes were made, etc.
|
|
|
|
# Customization
|
|
|
|
For information on changing how `would-format` handles different files, see
|
|
[CUSTOMIZATION.md](CUSTOMIZATION.md).
|
|
|
|
|
|
# Development
|
|
|
|
If you want to hack on `would-format`, see [DEVELOPMENT.md](DEVELOPMENT.md)
|
|
for more info.
|
|
|
|
# Troubleshooting
|
|
|
|
## nothing works from emacs
|
|
|
|
Be sure to run the install script from your project's root as determined by
|
|
`(projectile-project-root)`.
|
|
|
|
## problems with nvm, pyenv, goenv, etc
|
|
|
|
The problem might be that their shims aren't in your `PATH`. To work around
|
|
this sort of problem I run emacs from a wrapper script that ensures the shims
|
|
are loaded in my `PATH`.
|
|
|
|
## Running prettier is slow
|
|
|
|
The scripts by default call `npx prettier` with some arguments. If you call
|
|
these scripts from a directory where there's a `node_modules/` directory with
|
|
prettier and plugins, if necessary, installed, then `npx` should be fast
|
|
enough.
|
|
|
|
The solution, therefore, seems to be to say `yarn add --dev prettier` (or
|
|
`npm install --dev prettier`) in the right place.
|
|
|
|
(This seems to work for me, but it is admittedly still uncomfortably
|
|
cargoculty. There should be a more solid basis for this answer.)
|
|
|
|
## problems running black
|
|
|
|
The solution seems to be to run `pip install black pipx` somewhere.
|
|
|
|
## I need to use one version of `would-reformat` with one of my projects and another with another
|
|
|
|
With the per-project configuration [see below] this should rarely be
|
|
necessary, but in case it is, one thing you can try is creating different
|
|
`would-reformat` checkouts for different projects. For example, something
|
|
like this might work:
|
|
|
|
```
|
|
$ ls ~/devel
|
|
new-project1 new-project2 old-and-weird-project1
|
|
$ git clone https://github.com/maw/would-reformat
|
|
$ cd new-project1; ../would-reformat/install.sh
|
|
$ cd ../new-project2; ../would-reformat/install.sh
|
|
$ cd ..
|
|
$ git clone https://github.com/maw/would-reformat would-reformat-for-old-and-weird-project1
|
|
$ cd would-reformat-for-old-and-weird-project1; git checkout vSome-old-tag
|
|
$ cd ../old-and-weird-project1; ../would-reformat-for-old-and-weird-project1/install.sh
|
|
```
|
|
|
|
|
|
# Similar projects
|
|
|
|
If you don't like `would-reformat`'s approach, maybe one or more of these
|
|
would be more suitable.
|
|
|
|
- https://github.com/purcell/emacs-shfmt/
|
|
- https://github.com/pythonic-emacs/blacken
|
|
- https://github.com/dominikh/go-mode.el
|