Generic action for inserting arbitrary Elixir AST/source into a .ex or
.exs file using Sourceror. Handles anything with a do...end block -
def/defp (guarded or not, block or one-liner), and any other macro
call that takes a do: body (schema, pipeline, scope, etc) - and
also handles the body itself being a list literal (e.g. a supervisor's
children = [...] or def children, do: [...]), splicing into the
list's elements rather than appending next to it.
Not intended for mix.exs dependency lists - use AddDependency for
that.
Options
:path- file to patch. Defaults toExecution.mix_file/1.:content- required. A source string (parsed withSourceror.parse_string!/1) or an already-quoted AST fragment.:target- where to insert:nil(default) - the top level of the file- an atom - the body of the first
def/defp/macro call found with that name {:assign, var_name}- the value of the firstvar_name = ...assignment found anywhere in the filea 1-arity function
zipper -> zipper | nil- custom locator, must return a zipper positioned on the block/list/expression to patch directly (not a call node, not an assignment node)
:position- one of::end(default) - append as the last child:start- prepend as the first child:after/:before- needs:anchor, a 1-arity function receiving each existing child node (raw AST) and returningtruefor the node to anchor the insertion to
:anchor- matcher function, used with:after/:before
Examples
# Append a statement into a function body
run(target: :handle_call, content: "IO.inspect(msg)", position: :start)
# Append into a list literal body
run(target: :children, content: "MyApp.NewWorker", position: :end)
# Append into a variable assigned to a list, e.g. `children = [...]`
# inside a multi-statement function body
run(target: {:assign, :children}, content: "MyApp.NewWorker", position: :end)
# Custom locator - find and splice into a list found anywhere
run(
target: fn root_zipper ->
root_zipper
|> Zipper.find(fn
{:=, _, [{:children, _, ctx}, _rhs]} when is_atom(ctx) or is_nil(ctx) -> true
_ -> false
end)
|> case do
nil -> nil
assign_zipper -> assign_zipper |> Zipper.down() |> Zipper.right()
end
end,
content: "{MyApp.NewWorker, []}",
position: :end
)