avh4 / elm-format

elm-format formats Elm source code according to a standard set of rules based on the official Elm Style Guide
BSD 3-Clause "New" or "Revised" License
1.31k stars 145 forks source link

Auto-detect elm version with --stdin #563

Open lassik opened 5 years ago

lassik commented 5 years ago

(Continued from #561)

What to do in case of --stdin is a good question.

Editor plugins are easiest to implement using --stdin for multiple reasons. The main one is that people often format code in the editor before saving the file, in which case the file contents would not up be to date. In Emacs, I launch the elm-format subprocess so that its current directory (cwd) is the directory where the formatted .elm file resides, so looking up elm.json/elm-package.json based on the cwd would work fine. Not sure what is done by other editor plugins.

The best alternative might be to have a command line flag like this (copy-pasted from here):

Something that's really useful for editor plugins is an option to say what filename the contents of stdin are coming from.

  • prettier: this option is called --stdin-filepath
  • rufo: this option is called --filename

In my experience, it's easiest and most reliable to implement an editor plugin by not using disk files at all. Instead, just feed unformatted code to stdin and get the formatted code back from stdout. But even when using stdin/stdout, it's useful if we can know the filename of the code (the code usually comes from a disk file, but may have been modified in the text editor and the modifications have not been saved, so the disk file is different from the editor buffer that is sent to stdin).

The point of knowing the filename is that:

  • Formatter error/warning messages can show a filename that is intuitive to the user.
  • Unibeautify can find .unibeautifyrc and possibly other project settings files based on the filename.

If --stdin is given, you could have an error message like this:

I couldn't figure out what version of Elm you are using!

With --stdin, you should use either --elm-version to specify the Elm version directly, or --stdin-filepath to let elm-format know what disk file or directory corresponds to the code being formatted. elm-format will then look for elm-package.json or elm.json in that directory (and its parent directories) to figure out whether you are using Elm 0.18 or Elm 0.19.

As a final twist in the tale, people should be able to format code in temp buffers that don't have a filename associated with them. In that case I don't think there is anything sensible that can be done apart from requiring a manual --elm-version flag along with --stdin. The concept of a current directory is dubious for a temp buffer.

lassik commented 5 years ago

I re-read the above and it seems like a brittle solution to infer anything based on the current directory when --stdin is used. Seems quite likely that the cwd will be arbitrary and the programmer didn't think of changing into any particular directory before calling elm-format. A --stdin-filepath option would be much more robust.