lassik / emacs-format-all-the-code

Auto-format source code in many languages with one command
https://melpa.org/#/format-all
MIT License
621 stars 108 forks source link

Missing languages/formatters #5

Open lassik opened 6 years ago

lassik commented 6 years ago

Common Lisp

Scheme - https://github.com/russellw/scheme-format/ how easy is this to install?

Julia - https://github.com/invenia/JuliaFormat.jl

Erlang - erl_tidy with suitable command line adapter?

Scala

F# - https://github.com/fsprojects/fantomas

C# - https://github.com/dotnet/codeformatter

Tcl - ??

Awk - ??

R

MATLAB/Octave - https://github.com/davidvarga/MBeautifier

Pascal/Delphi

Basic/Visual Basic - ??

CoffeeScript - https://www.npmjs.com/package/coffee-formatter

PureScript - https://gitlab.com/joneshf/purty/issues/43

Groovy - https://github.com/diffplug/spotless

mandarvaze commented 6 years ago

For elixir (1.6), see https://hexdocs.pm/mix/Mix.Tasks.Format.html It does say

If any of the files is -, then the output is read from stdin and written to stdout.

lassik commented 6 years ago

Thanks! Now added in commit f3e920f

Do you know of a formatter for plain old Erlang?

lassik commented 6 years ago

Added Kotlin support using ktlint in cee0eea. The formatter works kinda weird (doesn't fix some obviously bad spacing, etc.) but I think it's supposed to be like that.

mandarvaze commented 6 years ago

Quick google search got me https://github.com/fenollp/erlang-formatter (seems to be active)

I personally don't use Erlang - so can't comment more.

lassik commented 6 years ago

It seems that the Erlang community has these solutions:

I guess erl_tidy would be the way to go. Depending on a text editor to do the formatting is iffy, IMHO (even if it's Emacs). Editors are heavy dependencies and not really built for the task. The formatter used by format-all should be one that people can use just as well in Continuous Integration builds, etc.

I'll wait for someone who actually uses Erlang to confirm that erl_tidy is a sound choice, and which adapter to use (I have no idea what build tools, etc., the Erlang community uses..)

lassik commented 6 years ago

Added SQL support using the sqlformat command from the Python sqlparse package. #11

lassik commented 6 years ago

Added Java support using clang-format in commit be066888

lassik commented 6 years ago

Added HTML/XHTML/XML support using HTML Tidy in commit 6b0bd2f

HTML Tidy ships with some operating systems. A modern version supporting HTML5 can be found at http://www.html-tidy.org/ The shell command should be tidy in both cases.

lassik commented 6 years ago

Added YAML support using yq in commit 5688767

lassik commented 6 years ago

Added Crystal support using crystal tool format in commit 4bfac6f

lassik commented 6 years ago

Assed assembly language support using asmfmt in commit cbf665f

patrl commented 6 years ago

Support for formatting haskell with brittany would be nice. It's the current state of the art, and integrated into, e.g., the haskell IDE engine. I can make a PR myself if I get some time soon!

lassik commented 6 years ago

Thanks for chiming in :)

We thought a lot about how to do configuration for format-all and came to the conclusion that it's best to leave configurable formatting to Unibeautify (I'm working on Emacs support). So the primary goal of format-all now is to support the main "anti-bikeshedding" formatter for each language (i.e. one that always formats to a rigid style and doesn't allow configuration). Things like gofmt for Go or black for Python are good examples.

I skimmed brittany's readme and it looks like a good fit. If it's on track to become the de facto standard (anti-bikeshedding) formatter for Haskell, and produces output roughly like hindent but better, then we could simply switch from hindent to brittany.

patrl commented 6 years ago

Ah, it's interesting to know the direction the project is heading in. Thank you by the way for this excellent project, it helps a lot with removing cruft from dotemacs.

There's some recent discussion on reddit, where the consensus seems to be that brittany is where it's at right now. It's worth noting btw that both hindent and brittany do allow custom configuration via yaml, so neither are completely rigid. I don't know of such a formatter for haskell.

lassik commented 6 years ago

Thanks for the kind words, glad to hear it's useful :)

That Reddit thread sounds convincing too, so I switched Haskell from hindent to brittany. It works really well, so that was a 2 minute job :D Commit 97e6f7d

lassik commented 6 years ago

BTW, if you happen to know a Haskeller who's also good at Node JS, Unibeautify doesn't yet have any Haskell formatter :)

patrl commented 6 years ago

Oh awesome, thank you!!

lassik commented 6 years ago

Clojure

Added Clojure/ClojureScript support using cljfmt in commit 666e1bc

terlar commented 6 years ago

Golang can alternatively format with goimports, when using go-mode you can specify this via the custom variable gofmt-command.

lassik commented 6 years ago

I experimented on supporting multiple formatters per language last week and almost got it done. I'll gather the energy to finish it ASAP. Got some pending Unibeautify work that would need attention as well. Most of my effort has gone into other things lately.

birdayz commented 5 years ago

Groovy would be great, so i can format gradle build files. :)

lassik commented 5 years ago

This should work: https://github.com/diffplug/spotless Pull requests welcome ;) I can also try to add it at some point.

lassik commented 5 years ago

Lua

@ellakk added Lua support using lua-fmt in commit 87c7a43. Thanks!

lassik commented 5 years ago

Added Dhall support using dhall format in commit 217aea7.

lassik commented 5 years ago

Added Dart support using dartfmt in commit 3f6dd7d

lassik commented 5 years ago

PHP

@tangxinfa added support using prettier in commit 4029309. Thanks!

Davoodeh commented 3 years ago

I'm sorry IDK if I should post this here but I'll do it anyways.

For C# I suggest you check out: https://github.com/OmniSharp/omnisharp-emacs There is this little formatter function in that, the very same one that VCS uses apparently for C# (just guessing). It comes with Doom Emacs for csharp lang. On top of that it's independent from Dotnet. The functions of interest are omnisharp-code-format-entire-file and omnisharp-code-format-region. I tried to use set-formatter! but being a novice couldn't get it to work I guess that's because it's not a THUNK or something.

Anyways yeah, that would be a great addition.

lassik commented 3 years ago

@Davoodeh Try M-x eval-expression (format-all--buffer-native 'csharp-mode 'omnisharp-code-format-entire-file). Does that work? If it does, we can package it into a formatter definition.

Davoodeh commented 3 years ago

No luck (probably due to my lack of understanding from Lisp and debugging it). I am probably not a good candidate to continue this convo with xD Couldn't find a workaround and also have no idea how this server works. Evaluation returns an error relating to OmniSharp. I suppose it's about a function that puts the cursor where it was before but just blindly guessing based on the words.

P.S: yeah it's independent from dotnet-sdk.

omnisharp--handle-server-response-packet error: 
(wrong-type-argument char-or-string-p nil).

Tried to handle this packet: 
((Request_seq . 3) (Command . "/codeformat") (Running . t) (Success . t) (Message) (Body) (Seq . 497) (Type . "response"))

This can mean an error in the handler function:
#[257 "\301\302\"A\303\300\304 \305 $\207" [nil assoc Buffer omnisharp--set-buffer-contents-to line-number-at-pos omnisharp--current-column] 7 "

(fn INPUT0)"]
 [2 times]
(t "")
Davoodeh commented 3 years ago

HyLang is missing as well.

Edit: Sorry, I put this in details since I'm not sure if it is correct or even if it's caused by the package. Since it's a Lisp it works *almost* perfectly with `'emacs-lisp` formatter which I managed to enable with `(setq-hook! 'hy-mode-hook +format-with 'emacs-lisp)` in my Doom. The only problem that it has is miss-treating `{}` as characters rather than brackets (like other brackets `()[]`). for example: ```lisp {a b c d} ; formats to this which ruins the style and confuses Parinfer {a b c d} ```
lassik commented 3 years ago

@Davoodeh Good thinking! I couldn't find a code formatter made specifically for Hy, but you might have better luck with the Clojure formatter (cljfmt) than with Emacs Lisp. It can be installed from npm with npm install --global node-cljfmt.

If you really like Hy, you might be able to convince them to make an official formatter for their language..

Davoodeh commented 3 years ago

No, actually I tested cljfmt before posting this and it ran into issues with Hy syntax. The closest I could get was emacs-lisp formatter.

Sure then, thanks for the suggestion. I will suggest an official formatted on their repo as well.

Davoodeh commented 3 years ago

Awk - ??

Awk can be formatted with gawk. gawk -o- "$code" does the trick. Take the code and outputs to the stream. Alternatively, -o[FILE] can take a filename.

Since it is very barebone, please add the option to toggle between spaces and tabs. Also, a "compact" option would be nice too. Something that makes the changes below:

# ignore comments and their positions (if you want ;) )
/from/{ # default
    print $0
}
/to/{ print $0 } # compact

(I'm sorry I basically have no notion of Elisp whatsoever so yeah I cannot make a P/R I just leave this as a note for one who may implement it)

I don't know if it helps or not. But for now, my formatter is this line of script that takes an input stream and outputs formatted code: https://github.com/Davoodeh/.files/blob/renew/.local/bin/awkfmt ```sh #!/bin/sh (# subshell/script takes inputs from a pipe # parse arguments while true; do case "$1" in h* | -h* | --h*) echo "$helpmsg" && exit 0 ;; t* | -t* | --tab* | '\t'* | "0") usetabs="usetabs" && shift ;; --) shift && break ;; # End of all options -*) echo "Invalid option: $1" && echo "$helpmsg" && exit 1 ;; *) break ;; # No more options esac; done # prettify while read -r l; do f="$f$l\n"; done # get lines from shell and put them in $f f="$(printf "%b" "$f")" # eval \n and others in $f f="$(gawk -o- "$f")" || exit $? # prettify or fail # since tabs are default, just print if that's what user wants [ -n "$usetabs" ] && { echo "$f" && exit 0; } spaces="${1:-4}" # TODO add a "compact" option which turns codes like below to one liners: # /from/{ # print $0 # } # /to/{ print $0 } echo "$f" | gawk "# replace tabs with spaces if tabs are not used match(\$0, /^\t+/) { p = \"\" l = RLENGTH while (l--) { p = p \"$(printf "%${spaces}s")\" } sub(/^\t+/, p, \$0) } { print \$0 }" ) || { # print help and return the correct exit code if failed r=$? echo "$helpmsg" exit $r } ``` Example of `gawk` format (not using my script or any other dependencies): ```awk BEGIN {FS=","} {print $1,"FNR="FNR,"NR="NR} END{print "Total",NR,"processed lines"} function trim(s) { sub(/^[ \t]*/,"",s); sub(/[ \t]*$/,"",s); return s; } ``` Turned to: ```awk BEGIN { FS = "," } { print $1, "FNR=" FNR, "NR=" NR } END { print "Total", NR, "processed lines" } function trim(s) { sub(/^[ \t]*/, "", s) sub(/[ \t]*$/, "", s) return s } ```
lassik commented 3 years ago

gawk -o- "$code"

Thanks! It makes sense to add this as a gawk formatter.

Since it is very barebone, please add the option to toggle between spaces and tabs. Also, a "compact" option would be nice too.

We have a policy not to add custom formatting to format-all; we only mirror what external formatters do. The reason we do it this way is that the policy is easy to understand for everyone involved, and upstream formatters don't accidentally get the blame for bugs in format-all.

If you'd like to have more options for awk formatting, the gawk maintainers might be open to the suggestion of adding an official formatting command to the gawk distribution. Or a group of awk users could release a third-party formatter that uses gawk.

lassik commented 3 years ago

gawk formatter added in commit d60a763.