Skip to content

surface-ui/surface_formatter

Folders and files

NameName
Last commit message
Last commit date
May 20, 2022
Nov 22, 2021
Aug 12, 2022
Aug 12, 2022
Dec 23, 2020
Dec 23, 2020
Mar 14, 2022
Jan 25, 2021
Mar 14, 2022
Mar 21, 2022
Jun 17, 2021

Repository files navigation

SurfaceFormatter

Build Status hex.pm hex.pm

A code formatter for https://hex.pm/packages/surface.

The complete documentation for SurfaceFormatter is located here.

Installation

Add :surface_formatter as a dependency in mix.exs:

defp deps do
  [
    {:surface_formatter, "~> 0.7.5"}
  ]
end

Formatter Plugin Usage (Elixir 1.13 and later)

Configuration

Modify the following in .formatter.exs:

  • inputs - add patterns for all Surface files
  • plugins - add Surface.Formatter.Plugin
# .formatter.exs
[
  ...,
  # match all .sface files and all .ex files with ~F sigils
  inputs: ["lib/**/*.{ex,sface}", ...],
  plugins: [Surface.Formatter.Plugin]
]

For documentation of other .formatter.exs options, see Surface.Formatter.Plugin.

Usage

$ mix format

(Formats both Elixir and Surface code.)

Mix Task Usage (Elixir 1.12 and earlier)

Configuration

Add surface_inputs to .formatter.exs with patterns for all Surface files:

# .formatter.exs
[
  ...,
  # match all .sface files and all .ex files with ~F sigils
  surface_inputs: ["lib/**/*.{ex,sface}", ...]
]

If your project does not use sface files, you can omit :surface_inputs and specify file patterns in the standard :inputs field instead. (mix surface.format will fall back to :inputs.) But be warned that including .sface files in :inputs causes mix format to crash in Elixir 1.12 and earlier.

For documentation of other .formatter.exs options, see mix surface.format.

Usage

$ mix surface.format

Formatting rules

The formatter mostly follows these rules:

  • Only formats code inside of ~F""" blocks and .sface files.
  • Child nodes are typically indented 2 spaces in from their parent.
  • Interpolated Elixir code (inside { } brackets) is formatted by the official Elixir formatter.
  • HTML attributes are put on separate lines if the line is too long.
  • Retains "lack of whitespace" such as <p>No whitespace between text and tags</p>.
  • Collapses extra newlines down to at most one blank line.

See Surface.Formatter.format_string!/2 for further documentation.

Example at a glance

Out of the box, Surface code that looks like this:

 <RootComponent with_many_attributes={ true } causing_this_line_to_wrap={ true} because_it_is_too_long={ "yes, this line is long enough to wrap" }>
   <!--   HTML public comment (hits the browser)   -->
   {!--   Surface private comment (does not hit the browser)   --}



   <div :if={ @show_div }
   class="container">
       <p> Text inside paragraph    </p>
    <span>Text touching parent tags</span>
   </div>

<Child  items={[%{name: "Option 1", key: 1}, %{name: "Option 2", key:  2},    %{name: "Option 3", key: 3}, %{name: "Option 4", key: 4}]}>
  Default slot contents
</Child>
</RootComponent>

will be formatted like this:

<RootComponent
  with_many_attributes
  causing_this_line_to_wrap
  because_it_is_too_long="yes, this line is long enough to wrap"
>
  <!-- HTML public comment (hits the browser) -->
  {!-- Surface private comment (does not hit the browser) --}

  <div :if={@show_div} class="container">
    <p>
      Text inside paragraph
    </p>
    <span>Text touching parent tags</span>
  </div>

  <Child items={[
    %{name: "Option 1", key: 1},
    %{name: "Option 2", key: 2},
    %{name: "Option 3", key: 3},
    %{name: "Option 4", key: 4}
  ]}>
    Default slot contents
  </Child>
</RootComponent>