diff --git a/README.md b/README.md index 4c8173f..914c9b7 100644 --- a/README.md +++ b/README.md @@ -59,6 +59,7 @@ See [all supported options in the documentation at `docs/options.md`](https://g | Arduino | `Arduino` |`.ino`, `.pde` | [`Uncrustify`](https://github.com/uncrustify/uncrustify) (Default) | | C | `C`, `opencl` |`.h`, `.c`, `.cl` | [`Uncrustify`](https://github.com/uncrustify/uncrustify) (Default), [`clang-format`](https://clang.llvm.org/docs/ClangFormat.html) | | Coldfusion | `html` |`.cfm`, `.cfml`, `.cfc` | [`Pretty Diff`](https://github.com/prettydiff/prettydiff) (Default) | +| Clojure | `Clojure` |`.clj`, `.cljs`, `.edn` | [`Clojure Beautifier`](https://github.com/snoe/node-cljfmt) | | CoffeeScript | `CoffeeScript` |`.coffee` | [`Coffee Formatter`](https://github.com/Glavin001/Coffee-Formatter), [`coffee-fmt`](https://github.com/sterpe/coffee-fmt) (Default) | | C++ | `C++` |`.h`, `.hh`, `.cc`, `.cpp`, `.cxx`, `.C`, `.c++`, `.hpp`, `.hxx`, `.h++` | [`Uncrustify`](https://github.com/uncrustify/uncrustify) (Default), [`clang-format`](https://clang.llvm.org/docs/ClangFormat.html) | | Crystal | `Crystal` |`.cr` | [`Crystal`](http://crystal-lang.org) (Default) | diff --git a/docs/options.md b/docs/options.md index 9742236..24c02c7 100644 --- a/docs/options.md +++ b/docs/options.md @@ -590,6 +590,75 @@ Maximum characters per line (0 disables) (Supported by Pretty Diff) } ``` +#### [Clojure](#clojure) + +**Supported Beautifiers**: [`Clojure Beautifier`](#clojure-beautifier) + +| Option | Clojure Beautifier | +| --- | --- | +| `disabled` | :white_check_mark: | +| `default_beautifier` | :white_check_mark: | +| `beautify_on_save` | :white_check_mark: | + +**Description**: + +Options for language Clojure + +##### [Disable Beautifying Language](#disable-beautifying-language) + +**Important**: This option is only configurable from within Atom Beautify's setting panel. + +**Type**: `boolean` + +**Description**: + +Disable Clojure Beautification + +**How to Configure** + +1. You can open the [Settings View](https://github.com/atom/settings-view) by navigating to +*Edit > Preferences (Linux)*, *Atom > Preferences (OS X)*, or *File > Preferences (Windows)*. +2. Go into *Packages* and search for "*Atom Beautify*" package. +3. Find the option "*Disable Beautifying Language*" and change it to your desired configuration. + +##### [Default Beautifier](#default-beautifier) + +**Important**: This option is only configurable from within Atom Beautify's setting panel. + +**Default**: `cljfmt` + +**Type**: `string` + +**Enum**: `Clojure Beautifier` + +**Description**: + +Default Beautifier to be used for Clojure + +**How to Configure** + +1. You can open the [Settings View](https://github.com/atom/settings-view) by navigating to +*Edit > Preferences (Linux)*, *Atom > Preferences (OS X)*, or *File > Preferences (Windows)*. +2. Go into *Packages* and search for "*Atom Beautify*" package. +3. Find the option "*Default Beautifier*" and change it to your desired configuration. + +##### [Beautify On Save](#beautify-on-save) + +**Important**: This option is only configurable from within Atom Beautify's setting panel. + +**Type**: `boolean` + +**Description**: + +Automatically beautify Clojure files on save + +**How to Configure** + +1. You can open the [Settings View](https://github.com/atom/settings-view) by navigating to +*Edit > Preferences (Linux)*, *Atom > Preferences (OS X)*, or *File > Preferences (Windows)*. +2. Go into *Packages* and search for "*Atom Beautify*" package. +3. Find the option "*Beautify On Save*" and change it to your desired configuration. + #### [CoffeeScript](#coffeescript) **Supported Beautifiers**: [`Coffee Formatter`](#coffee-formatter) [`coffee-fmt`](#coffee-fmt) diff --git a/examples/nested-jsbeautifyrc/clojure/expected/test.clj b/examples/nested-jsbeautifyrc/clojure/expected/test.clj new file mode 100644 index 0000000..eefb333 --- /dev/null +++ b/examples/nested-jsbeautifyrc/clojure/expected/test.clj @@ -0,0 +1,50 @@ +(ns clojure.core.protocols) + +(set! *warn-on-reflection* true) + +(defprotocol CollReduce + "Protocol for collection types that can implement reduce faster than + first/next recursion. Called by clojure.core/reduce. Baseline + implementation defined in terms of Iterable." + (coll-reduce [coll f] [coll f val])) + +(defprotocol + InternalReduce + "Protocol for concrete seq types that can reduce themselves + faster than first/next recursion. Called by clojure.core/reduce." + (internal-reduce [seq f start])) + +(defn- seq-reduce + ([coll f] + (if-let [s (seq coll)] + (internal-reduce (next s) f (first s)) + (f))) + ([coll f val] + (let [s (seq coll)] + (internal-reduce s f val)))) + +(defn- iter-reduce + ([^java.lang.Iterable coll f] + + (let [iter (.iterator coll)] + (if (.hasNext iter) + + (loop [ret (.next iter)] + (if (.hasNext iter) + + (let [ret (f ret (.next iter))] + (if (reduced? ret) + @ret + (recur ret))) + ret)) + (f)))) + + ([^java.lang.Iterable coll f val] + (let [iter (.iterator coll)] + (loop [ret val] + (if (.hasNext iter) + (let [ret (f ret (.next iter))] + (if (reduced? ret) + @ret + (recur ret))) + ret))))) diff --git a/examples/nested-jsbeautifyrc/clojure/original/test.clj b/examples/nested-jsbeautifyrc/clojure/original/test.clj new file mode 100644 index 0000000..ffcb9ad --- /dev/null +++ b/examples/nested-jsbeautifyrc/clojure/original/test.clj @@ -0,0 +1,50 @@ +(ns clojure.core.protocols) + +(set! *warn-on-reflection* true) + +(defprotocol CollReduce + "Protocol for collection types that can implement reduce faster than + first/next recursion. Called by clojure.core/reduce. Baseline + implementation defined in terms of Iterable." + (coll-reduce [coll f] [coll f val])) + +(defprotocol + InternalReduce + "Protocol for concrete seq types that can reduce themselves + faster than first/next recursion. Called by clojure.core/reduce." + (internal-reduce [seq f start])) + +(defn- seq-reduce + ([coll f] + (if-let [s (seq coll)] + (internal-reduce (next s) f (first s)) + (f))) + ([coll f val] + (let [s (seq coll)] + (internal-reduce s f val)))) + +(defn- iter-reduce + ([^java.lang.Iterable coll f] + + (let [iter (.iterator coll)] + (if (.hasNext iter) + + (loop [ret (.next iter)] + (if (.hasNext iter) + + (let [ret (f ret (.next iter))] + (if (reduced? ret) + @ret + (recur ret))) + ret)) + (f)))) + + ([^java.lang.Iterable coll f val] + (let [iter (.iterator coll)] + (loop [ret val] + (if (.hasNext iter) + (let [ret (f ret (.next iter))] + (if (reduced? ret) + @ret + (recur ret))) + ret))))) diff --git a/examples/simple-jsbeautifyrc/clojure/expected/test.clj b/examples/simple-jsbeautifyrc/clojure/expected/test.clj new file mode 100644 index 0000000..2cdb558 --- /dev/null +++ b/examples/simple-jsbeautifyrc/clojure/expected/test.clj @@ -0,0 +1,16 @@ +(defn reformat-form + [form & [{:as opts}]] + (-> form + + (cond-> (:remove-consecutive-blank-lines? opts true) + remove-consecutive-blank-lines) + + (cond-> (:remove-surrounding-whitespace? opts true) + remove-surrounding-whitespace) + (cond-> (:insert-missing-whitespace? opts true) insert-missing-whitespace) + (cond-> (:indentation? opts true) + (reindent (:indents opts default-indents))) + + (cond-> (:remove-trailing-whitespace? opts true) + + remove-trailing-whitespace))) diff --git a/examples/simple-jsbeautifyrc/clojure/original/test.clj b/examples/simple-jsbeautifyrc/clojure/original/test.clj new file mode 100644 index 0000000..028ac86 --- /dev/null +++ b/examples/simple-jsbeautifyrc/clojure/original/test.clj @@ -0,0 +1,16 @@ +(defn reformat-form + [form & [{:as opts}]] + (-> form + + (cond-> (:remove-consecutive-blank-lines? opts true) + remove-consecutive-blank-lines) + + (cond-> (:remove-surrounding-whitespace? opts true) + remove-surrounding-whitespace) + (cond-> (:insert-missing-whitespace? opts true) insert-missing-whitespace) + (cond-> (:indentation? opts true) + (reindent (:indents opts default-indents))) + + (cond-> (:remove-trailing-whitespace? opts true) + + remove-trailing-whitespace))) diff --git a/package.json b/package.json index d13912d..a692aa0 100644 --- a/package.json +++ b/package.json @@ -129,6 +129,7 @@ "lodash": "^4.14.2", "loophole": "^1.0.0", "marko-prettyprint": "^1.1.8", + "node-cljfmt": "^0.5.3-1", "node-dir": "^0.1.15", "node-uuid": "^1.4.3", "open": "0.0.5", @@ -270,7 +271,9 @@ "vue", "vue beautifier", "sassconvert", - "formatr" + "formatr", + "clojure", + "clojure beautifier" ], "devDependencies": { "coffeelint": "^1.10.1", diff --git a/spec/beautify-languages-spec.coffee b/spec/beautify-languages-spec.coffee index e45b4a0..942dafb 100644 --- a/spec/beautify-languages-spec.coffee +++ b/spec/beautify-languages-spec.coffee @@ -21,7 +21,7 @@ describe "BeautifyLanguages", -> # Activate all of the languages allLanguages = [ - "c", "coffee-script", "css", "d", "html", + "c", "clojure", "coffee-script", "css", "d", "html", "java", "javascript", "json", "less", "mustache", "objective-c", "perl", "php", "python", "ruby", "sass", "sql", "svg", diff --git a/src/beautifiers/clojure-beautifier/fmt.edn b/src/beautifiers/clojure-beautifier/fmt.edn new file mode 100644 index 0000000..b71020a --- /dev/null +++ b/src/beautifiers/clojure-beautifier/fmt.edn @@ -0,0 +1,84 @@ +{:indents + {componentDidMount [[:inner 0]] + getInitialState [[:inner 0]] + getDefaultProps [[:inner 0]] + componentWillMount [[:inner 0]] + componentWillReceiveProps [[:inner 0]] + shouldComponentUpdate [[:inner 0]] + componentWillUpdate [[:inner 0]] + componentDidUpdate [[:inner 0]] + componentWillUnmount [[:inner 0]] + render [[:inner 0]] + defui [[:inner 0]] + div [[:inner 0]] + pre [[:inner 0]] + code [[:inner 0]] + button [[:inner 0]] + alt! [[:block 0]] + :require [[:inner 1]] + :import [[:inner 1]] + alt!! [[:block 0]] + are [[:block 2]] + binding [[:block 1]] + bound-fn [[:inner 0]] + case [[:block 1]] + catch [[:block 2]] + comment [[:block 0]] + cond [[:block 0]] + condp [[:block 2]] + cond-> [[:block 1]] + cond->> [[:block 1]] + def [[:inner 0]] + defmacro [[:inner 0]] + defmethod [[:inner 0]] + defmulti [[:inner 0]] + defn [[:inner 0]] + defn- [[:inner 0]] + defonce [[:inner 0]] + defprotocol [[:block 1] [:inner 1]] + defrecord [[:block 2] [:inner 1]] + defstruct [[:block 1]] + deftest [[:inner 0]] + deftype [[:block 2] [:inner 1]] + do [[:block 0]] + doseq [[:block 1]] + dotimes [[:block 1]] + doto [[:block 1]] + extend [[:block 1]] + extend-protocol [[:block 1] [:inner 1]] + extend-type [[:block 1] [:inner 1]] + finally [[:block 0]] + fn [[:inner 0]] + for [[:block 1]] + future [[:block 0]] + go [[:block 0]] + go-loop [[:block 1]] + if [[:block 1]] + if-let [[:block 1]] + if-not [[:block 1]] + if-some [[:block 1]] + let [[:block 1]] + letfn [[:block 1] [:inner 2 0]] + locking [[:block 1]] + loop [[:block 1]] + match [[:block 1]] + ns [[:block 1]] + proxy [[:block 2] [:inner 1]] + reify [[:inner 0] [:inner 1]] + struct-map [[:block 1]] + testing [[:block 1]] + thread [[:block 0]] + try [[:block 0]] + use-fixtures [[:inner 0]] + when [[:block 1]] + when-first [[:block 1]] + when-let [[:block 1]] + when-not [[:block 1]] + when-some [[:block 1]] + while [[:block 1]] + with-local-vars [[:block 1]] + with-open [[:block 1]] + with-out-str [[:block 0]] + with-precision [[:block 1]] + with-redefs [[:block 1]] +}} diff --git a/src/beautifiers/clojure-beautifier/index.coffee b/src/beautifiers/clojure-beautifier/index.coffee new file mode 100644 index 0000000..45eee38 --- /dev/null +++ b/src/beautifiers/clojure-beautifier/index.coffee @@ -0,0 +1,21 @@ +"use strict" +path = require('path') +Beautifier = require('../beautifier') + +module.exports = class ClojureBeautifier extends Beautifier + + name: "Clojure Beautifier" + link: "https://github.com/snoe/node-cljfmt" + + options: { + Clojure: true + } + + beautify: (text, language, options) -> + formatPath = path.resolve(__dirname, "fmt.edn") + @tempFile("input", text).then((filePath) => + @run("cljfmt", [ + filePath, + "--edn=" + formatPath + ]).then(=> + @readFile(filePath))) diff --git a/src/beautifiers/index.coffee b/src/beautifiers/index.coffee index b9d619c..9162f3c 100644 --- a/src/beautifiers/index.coffee +++ b/src/beautifiers/index.coffee @@ -38,6 +38,7 @@ module.exports = class Beautifiers extends EventEmitter 'autopep8' 'coffee-formatter' 'coffee-fmt' + 'clojure-beautifier' 'clang-format' 'crystal' 'dfmt' diff --git a/src/languages/clojure.coffee b/src/languages/clojure.coffee new file mode 100644 index 0000000..b980b5e --- /dev/null +++ b/src/languages/clojure.coffee @@ -0,0 +1,21 @@ +module.exports = { + + name: "Clojure" + namespace: "clj" + + ### + Supported Grammars + ### + grammars: [ + "Clojure" + ] + + ### + Supported extensions + ### + extensions: [ + 'clj', 'cljs', 'edn' + ] + + defaultBeautifier: "cljfmt" +} diff --git a/src/languages/index.coffee b/src/languages/index.coffee index d3bbee3..9e3de45 100644 --- a/src/languages/index.coffee +++ b/src/languages/index.coffee @@ -16,6 +16,7 @@ module.exports = class Languages "arduino" "c-sharp" "c" + "clojure" "coffeescript" "coldfusion" "cpp"