Rbtz.CredoChecks.Readability.FunctionSpacing (rbtz_credo_checks v0.9.0)

Copy Markdown View Source

Basics

This check is disabled by default.

Learn how to enable it via .credo.exs.

This check has a base priority of normal and works with any version of Elixir.

Explanation

Requires consistent blank-line spacing around function definitions so they stay visually separated and easy to scan.

Blank line above the header block

A function header may stack several attributes (@doc, @impl, @spec, …). Those may sit flush against each other, but the block as a whole must be separated from the previous statement by a blank line.

Header attributes that may stack without blanks between them: @doc, @impl, @spec, @dialyzer, @deprecated, @since, and @decorate / @decorate_all. Full-line comments immediately above or below those attributes are part of the same header block.

No blank line is required when the line above the block is the defmodule (or defprotocol / defimpl) that opens the body.

A header block is always flush against the first clause of the function it documents — never a blank line between @spec / @impl / … and def.

Multi-clause density (name + arity)

Clauses of the same function (def / defp / defmacro / defmacrop with the same name and arity) share one layout, with or without a header:

  • All single-line — no blank lines between clauses.
  • Any multi-line — a blank line between every pair of consecutive clauses.

Bad — missing blank above header

@spec one() :: :ok
def one, do: :ok
@spec two() :: :ok
def two, do: :ok

Bad — blank under header

@spec one() :: :ok

def one, do: :ok

Bad — single-line clauses must stay compact

def one(x) when is_atom(x), do: x

def one(x) when is_integer(x), do: x

Bad — multi-line clauses must be separated

def one(x) when is_atom(x), do: x
def one(x) when is_integer(x) do
  x
end

Good

defmodule M do
  @spec one() :: :ok
  def one, do: :ok

  @spec two() :: :ok
  def two, do: :ok

  # all single-line → compact clauses, flush header
  @spec three(atom()) :: atom()
  def three(x) when is_atom(x), do: x
  def three(x) when is_integer(x), do: x

  # any multi-line → separated clauses, still flush header
  @spec four(atom()) :: atom()
  def four(x) when is_atom(x), do: x

  def four(x) when is_integer(x) do
    x
  end
end

Check-Specific Parameters

There are no specific parameters for this check.

General Parameters

Like with all checks, general params can be applied.

Parameters can be configured via the .credo.exs config file.