fceruti

fceruti

How to programatically format code using plugins

I’m building a library that’s constantly re generating certain modules, building them from string templates. The generated modules include certain sigils that are nicely formatted using a custom plugin.

I need to format the string before it touches disk, because there are also file watchers, who would receive the event twice if I format as a second separate step. That’s why I can’t just call System.cmd("mix format") after creating the file.

Is there something equivalent to using Code.format_string!/2 but with the ability of passing a plugin list?

Thanks!

Marked As Solved

Marcus

Marcus

If I understand right you want to format in dev mode and therefore you can access Mix. In this case you can use this:

> iex -S mix
iex(1)> {formatter, _opts} = Mix.Tasks.Format.formatter_for_file("source.ex")
{#Function<19.89531025/1 in Mix.Tasks.Format.find_formatter_for_file/2>,
 [
   sigils: [],
   plugins: [FreedomFormatter],
   trailing_comma: true,
   inputs: ["{mix,.formatter}.exs", "{config,lib,test}/**/*.{ex,exs}"],
   locals_without_parens: [noop: 1]
 ]}
iex(2)> formatter.("""
...(2)> defmodule    Foo do
...(2)> def foo do
...(2)> noop 5
...(2)> [
...(2)> 1,
...(2)> 2,
...(2)> ]
...(2)> end
...(2)> end
...(2)> """) |> IO.puts()
defmodule Foo do
  def foo do
    noop 5

    [
      1,
      2,
    ]
  end
end

:ok

The "source.ex" given to formatter_for_file does not have to be an existing file.

Also Liked

krasenyp

krasenyp

You can go even simpler:

def write_and_format_module(file_path, content) do
    command = """
    mix format - <<STDIN > #{file_path}
    #{content}
    STDIN
    """
    {"", 0} = System.shell(command)
    Logger.info("Re generated: #{file_path}")
  end
fceruti

fceruti

Thanks! this was it :slight_smile:

  def write_and_format_module(file_path, content) do
    :ok = file_path |> Path.dirname() |> File.mkdir_p()
    {formatter, _} = Mix.Tasks.Format.formatter_for_file("source.ex")
    File.write(file_path, formatter.(content))
    IO.puts(IO.ANSI.green() <> "* creating " <> IO.ANSI.reset() <> file_path)
  end

fceruti

fceruti

awesome, thanks!

Where Next?

Popular in Questions Top

tduccuong
Hi, is there any work on GUI with Elixir, that is similar to Electron/Javascript? My idea is to bundle Phoenix and BEAM into a single se...
New
Harrisonl
We have an ECS cluster with 4 services, where each task joins a single cluster, via discovery ECS discovery service. Currently when I de...
New
chokchit
** (DBConnection.ConnectionError) connection not available and request was dropped from queue after 2733ms. You can configure how long re...
New
joeerl
Hello again - after a longish gap I’ve decided I really must dig into Elixir and see what’s been happening here - so I have a few questio...
New
minhajuddin
I have seen a lot of code which picks the first element from a list using Enum.at(0) instead of List.first. Is there a reason why people ...
New
Emily
I have VueJS GUIs with the project generated using Webpack. I have Elixir modules that will need to be used by the VueJS GUIs. I fore...
New
hariharasudhan94
lets say i have a sample like a = 20; b = 10; if (a &gt; b) do {:ok, "a"} end if (a &lt; b) do {:ok, b} end if (a == b) do {:ok, "eq...
New
JDanielMartinez
Hi! May someone helps me, please! I have two apps into an umbrella project: the first one is Database, which manages queries, and the se...
New
komlanvi
Hi everyone, I was playing with phoenix liveView but I run into an issue. I have a form and want to validate each input text when the te...
New
vonH
In asking this question I am more interested about the expressiveness of the language itself and less concerned about the availability of...
New

Other popular topics Top

Fl4m3Ph03n1x
About me? ( if you have nothing better to do than reading about some random guy in the internet :stuck_out_tongue: ) Hello all, this is ...
New
fireproofsocks
Forgive me if this is obvious, but how does one delete a database record WITHOUT selecting it first? https://hexdocs.pm/ecto/Ecto.Repo.h...
New
jerry
Good day to you all. I have been struggling to get a query involving like and ilike to work. Can anyone assist me on this, please? pro...
New
chrismccord
This release brings a number of exciting features, including integration with the new Phoenix LiveDashboard and Phoenix LiveView. There h...
New
boundedvariable
I am going through the kafka architecture. All the features what the kafka is providing are already in Erlang. I would like hear your opi...
New
shijith.k
I am trying to start a new phoenix project with elixir 1.9, but mix phx.new does not work. It says that ** (Mix) The task "phx.new" could...
New
hariharasudhan94
I would like to know what is the best IDE for elixir development?
New
PeterCarter
There are pre-rolled solutions for other frameworks that do work. However, Phoenix does not seem to have these. Have people had good expe...
New
senggen
Erlang/OTP 25 [erts-13.2.2] [source] [64-bit] [smp:8:8] [ds:8:8:10] [async-threads:1] 15:22:35.803 [error] gen_event {lager_file_backend...
New
vonH
In asking this question I am more interested about the expressiveness of the language itself and less concerned about the availability of...
New

We're in Beta

About us Mission Statement