From d015a990bb9b0018f3c5ef64752ea9e825a1f693 Mon Sep 17 00:00:00 2001 From: Matt Enlow Date: Sat, 25 Jan 2025 08:52:53 -0700 Subject: [PATCH] docs docs docs docs docs! --- README.md | 79 ++++------------------------- docs/comment_directives.md | 101 +++++++++++++++++++++++++++++++++++++ docs/deprecations.md | 23 +++++++++ docs/module_directives.md | 14 +++++ mix.exs | 1 + 5 files changed, 149 insertions(+), 69 deletions(-) create mode 100644 docs/comment_directives.md diff --git a/README.md b/README.md index 6042da5c..647f73b3 100644 --- a/README.md +++ b/README.md @@ -11,77 +11,18 @@ You can learn more about the history, purpose and implementation of Styler from ## Features -### AST Rewrites as part of `mix format` +Styler fixes a plethora of elixir style and optimization issues automatically as part of mix format. -[See our Rewrites documentation on hexdocs](https://hexdocs.pm/styler/styles.html) -Styler fixes a plethora of elixir style and optimization issues automatically as part of `mix format`. In addition to automating corrections for [many credo rules](docs/credo.md) (meaning you can turn them off to speed credo up), Styler: +[See Styler's documentation on Hex](https://hexdocs.pm/styler/styles.html) for the comprehensive list of its features. -- [keeps a strict module layout](docs/module_directives.md#directive-organization) - - alphabetizes module directives -- [extracts repeated aliases](docs/module_directives.md#alias-lifting) -- [makes your pipe chains pretty as can be](docs/pipes.md) - - pipes and unpipes function calls based on the number of calls - - optimizes standard library calls (`a |> Enum.map(m) |> Enum.into(Map.new)` => `Map.new(a, m)`) -- replaces strings with sigils when the string has many escaped quotes -- ... and so much more +The fastest way to see what all it can do you for you is to just try it out in your codebase... but here's a list of a few features to help you decide if you're interested in Styler: -### Maintain static list order via `# styler:sort` - -Styler can keep static values sorted for your team as part of its formatting pass. To instruct it to do so, replace any `# Please keep this list sorted!` notes you wrote to your teammates with `# styler:sort`. - -#### Examples - -```elixir -# styler:sort -[:c, :a, :b] - -# styler:sort -~w(a list of words) - -# styler:sort -@country_codes ~w( - en_US - po_PO - fr_CA - ja_JP -) - -# styler:sort -a_var = - [ - Modules, - In, - A, - List - ] -``` - -Would yield: - -```elixir -# styler:sort -[:a, :b, :c] - -# styler:sort -~w(a list of words) - -# styler:sort -@country_codes ~w( - en_US - fr_CA - ja_JP - po_PO -) - -# styler:sort -a_var = - [ - A, - In, - List, - Modules - ] -``` +- sorts and organizes `import`/`alias`/`require` and other [module directives](docs/module_directives.md) +- keeps lists, sigils, and even arbitrary code sorted with the `# styler:sort` [comment directive](docs/comment_directives.md) +- automatically creates aliases for repeatedly referenced modules names ([_"alias lifting"_](docs/module_directives.md#alias-lifting)) +- optimizes pipe chains for [readability and performance](docs/pipes.md) +- rewrites strings as sigils when it results in fewer escapes +- auto-fixes [many credo rules](docs/credo.md), meaning you can spend less time fighting with CI ## Who is Styler for? @@ -101,7 +42,7 @@ Add `:styler` as a dependency to your project's `mix.exs`: ```elixir def deps do [ - {:styler, "~> 1.2", only: [:dev, :test], runtime: false}, + {:styler, "~> 1.4", only: [:dev, :test], runtime: false}, ] end ``` diff --git a/docs/comment_directives.md b/docs/comment_directives.md new file mode 100644 index 00000000..41dc0a63 --- /dev/null +++ b/docs/comment_directives.md @@ -0,0 +1,101 @@ +## Comment Directives + +Comment Directives are a Styler feature that let you instruct Styler to do maintain additional formatting via comments. + +The plural in the name is optimistic as there's currently only one, but who knows + +### `# styler:sort` + +Styler can keep static values sorted for your team as part of its formatting pass. To instruct it to do so, replace any `# Please keep this list sorted!` notes you wrote to your teammates with `# styler:sort` + +Sorting is done via string comparison of the code. + +Styler knows how to sort the following things: + +- lists of elements +- arbitrary code within `do end` blocks (helpful for schema-like macros) +- `~w` sigils elements +- keyword shapes (structs, maps, and keywords) + +Since you can't have comments in arbitrary places when using Elixir's formatter, +Styler will apply those sorts when they're on the righthand side fo the following operators: + +- module directives (eg `@my_dir ~w(a list of things)`) +- assignments (eg `x = ~w(a list again)`) +- `defstruct` + +#### Examples + +**Before** + +```elixir +# styler:sort +[:c, :a, :b] + +# styler:sort +~w(a list of words) + +# styler:sort +@country_codes ~w( + en_US + po_PO + fr_CA + ja_JP +) + +# styler:sort +a_var = + [ + Modules, + In, + A, + List + ] + +# styler:sort +my_macro "some arg" do + another_macro :q + another_macro :w + another_macro :e + another_macro :r + another_macro :t + another_macro :y +end +``` + +**After** + +```elixir +# styler:sort +[:a, :b, :c] + +# styler:sort +~w(a list of words) + +# styler:sort +@country_codes ~w( + en_US + fr_CA + ja_JP + po_PO +) + +# styler:sort +a_var = + [ + A, + In, + List, + Modules + ] + +# styler:sort +my_macro "some arg" do + another_macro :e + another_macro :q + another_macro :r + another_macro :t + another_macro :w + another_macro :y +end +``` diff --git a/docs/deprecations.md b/docs/deprecations.md index bbc7c190..976b9327 100644 --- a/docs/deprecations.md +++ b/docs/deprecations.md @@ -25,10 +25,33 @@ This is covered by the Elixir Formatter with the `--migrate` flag, but Styler br Rewrite `unless x` to `if !x` +### 1.19 + +#### Change Struct Updates to Map Updates (Experimental) + +1.19 deprecates struct update syntax in favor of map update syntax. Styler will do this update for you if you're on Elixir 1.19.0-dev or later. + +```elixir +# This +%Struct{x | y} +# Styles to this +%{x | y} +``` + +**WARNING** Double check your diffs to make sure your variable is pattern matching against the same struct if you want to harness 1.18's type checking features. + +A future version of Styler may be smart enough to do this check for you and perform the appropriate updates to the assignment location; no guarantees though. Track via #199, h/t @SteffenDE + +### 1.18 + +None? + ### 1.17 [1.17 Deprecations](https://hexdocs.pm/elixir/1.17.0/changelog.html#4-hard-deprecations) +- Replace `:timer.units(x)` with the new `to_timeout(unit: x)` for `hours|minutes|seconds` + #### Range Matching Without Step ```elixir diff --git a/docs/module_directives.md b/docs/module_directives.md index ff3cc8cb..4bfcd590 100644 --- a/docs/module_directives.md +++ b/docs/module_directives.md @@ -162,6 +162,20 @@ C.foo() C.bar() ``` +Styler also notices when you have a module aliased and aren't employing that alias and will do the updates for you. + +```elixir +# Given +alias My.Apps.Widget + +x = Repo.get(My.Apps.Widget, id) + +# Styled +alias My.Apps.Widget + +x = Repo.get(Widget, id) +``` + ### Collisions Styler won't lift aliases that will collide with existing aliases, and likewise won't lift any module whose name would collide with a standard library name. diff --git a/mix.exs b/mix.exs index 8d3df8e5..c8426a74 100644 --- a/mix.exs +++ b/mix.exs @@ -70,6 +70,7 @@ defmodule Styler.MixProject do "docs/control_flow_macros.md": [title: "Control Flow Macros (if, case, ...)"], "docs/mix_configs.md": [title: "Mix Configs (config/*.exs)"], "docs/module_directives.md": [title: "Module Directives (use, alias, ...)"], + "docs/comment_directives.md": [title: "Comment Directives (# styler:sort)"], "docs/credo.md": [title: "Styler & Credo"], "README.md": [title: "Styler"] ]