 
       def my_function(%User{} = user, arg1, arg2) do
         %{name: name, age: age, ...} = user
-
-  Since the formatter cannot change the semantics of your code,
-  sometimes it is necessary to tweak the code to get optimal formatting.
+        ...
+      end
+
+  In some situations, you can use the fact the formatter does not generate
+  elegant code as a hint for refactoring. Take this code:
+
+      def board?(board_id, %User{} = user, available_permissions, required_permissions) do
+        Tracker.OrganizationMembers.user_in_organization?(user.id, board.organization_id) and
+          required_permissions == Enum.to_list(MapSet.intersection(MapSet.new(required_permissions), MapSet.new(available_permissions)))
+      end
+
+  The code above has very long lines and running the formatter is not going
+  to address this issue. In fact, the formatter may make it more obvious that
+  you have complex expressions:
+
+      def board?(board_id, %User{} = user, available_permissions, required_permissions) do
+        Tracker.OrganizationMembers.user_in_organization?(user.id, board.organization_id) and
+          required_permissions ==
+            Enum.to_list(
+              MapSet.intersection(
+                MapSet.new(required_permissions),
+                MapSet.new(available_permissions)
+              )
+            )
+      end
+
+  Take such cases as a suggestion that your code should be refactored:
+
+      def board?(board_id, %User{} = user, available_permissions, required_permissions) do
+        Tracker.OrganizationMembers.user_in_organization?(user.id, board.organization_id) and
+          matching_permissions?(required_permissions, available_permissions)
+      end
+
+      defp matching_permissions?(required_permissions, available_permissions) do
+        intersection =
+          required_permissions
+          |> MapSet.new()
+          |> MapSet.intersection(MapSet.new(available_permissions))
+          |> Enum.to_list()
+
+        required_permissions == intersection
+      end
+
+  To sum it up: since the formatter cannot change the semantics of your
+  code, sometimes it is necessary to tweak or refactor the code to get
+  optimal formatting. To help better understand how to control the formatter,
+  we describe in the next sections the cases where the formatter keeps the
+  user encoding and how to control multiline expressions.
+
+  ## Keeping user's formatting
+
+  The formatter respects the input format in some cases. Those are
+  listed below:
+
+    * Insignificant digits in numbers are kept as is. The formatter
+      however always inserts underscores for decimal numbers with more
+      than 5 digits and converts hexadecimal digits to uppercase
+
+    * Strings, charlists, atoms and sigils are kept as is. No character
+      is automatically escaped or unescaped. The choice of delimiter is
+      also respected from the input
+
+    * Newlines inside blocks are kept as in the input except for:
+      1) expressions that take multiple lines will always have an empty
+      line before and after and 2) empty lines are always squeezed
+      together into a single empty line
+
+    * The choice between `:do` keyword and `do/end` blocks is left
+      to the user
+
+    * Lists, tuples, bitstrings, maps, structs and function calls will be
+      broken into multiple lines if they are followed by a newline in the
+      opening bracket and preceded by a new line in the closing bracket
+
+    * Pipeline operators, like `|>` and others with the same precedence,
+      will span multiple lines if they spanned multiple lines in the input
+
+  The behaviours above are not guaranteed. We may remove or add new
+  rules in the future. The goal of documenting them is to provide better
+  understanding on what to expect from the formatter.
 
   ### Multi-line lists, maps, tuples, etc
 


    1. calls that have do/end blocks
    2. local calls without parens where the name and arity of the local
       call is also listed under `:locals_without_parens`

  The choice of parens and no parens also affects indentation. When a
  function call with parens doesn't fit on the same line, the formatter

  based on the name, this behaviour should be configurable, such as the
  `:locals_without_parens` option.

  ## Running the formatter

  While the formatter attempts to fit the most it can on a single line,
  in many situations such may not be possible, often causing line breaks
  to be introduced in the code.

  In some cases, this may lead to undesired formatting and it is often best
  to adjust the formatted output. To put it in other words: some code generated
  by the formatter may not be aesthetically pleasing and they require explicit
  intervention from the developer. That's why we do not recommend to run the
  formatter blindly in an existing codebase. Instead you should format and
  sanity check each formatted file.

  Let's see some examples. The code below:

      "this is a very long string ... #{inspect(some_value)}"

