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

openscript
Hello! Sorry for this astonishing simple question, but I’m really stuck. I try to set up the intellij-elixir plugin, but I don’t know ho...
New
ycv005
I have followed this StackOverflow post to install the specific version of Erlang. And When I am running mix ecto.setup then getting fol...
New
Kagamiiiii
Student &amp; New to elixir. Nice language. I want to convert a english character, e.g. “a”, which is stored in a variable, to it’s asci...
New
sacepums
Hey guys. I'm new to elixir and im really stocked about it. But I ran into a bit of problem - I need to convert a date sting, for examp...
New
myronmarston
The Elixir Typespec docs show the following syntax for keyword lists in typespecs: # ... | [key: type] # keyword lis...
New
makeitrein
Hey all, just started picking up Elixir last week and am writing a scraper as a learning project. Baby step #1 is extracting the number ...
New
mathew4509
I have a list say x = ["23gh", "56kh", "97mh"] I would like to pass each element to Val in each iteration. Say, in iteration 1 -------...
New
electic
Hi, I am new to Elixir. I am trying to use the DateTime component to insert a date into MySQL however the there seems to be no way to fo...
New
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
9mm
I am constructing a JSON object (map) and I need to conditionally set a field. I’m trying to write proper elixir-way code… and I’m at a l...
New

Other popular topics Top

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
yurko
Here are few pieces of (common) Linux knowledge that we use for reasonably small one server apps. We use Ubuntu but this should work for ...
New
yawaramin
In the Dialyzer docs ( http://erlang.org/doc/man/dialyzer.html#requesting-or-suppressing-warnings-in-source-files ), there is a way to tu...
New
albydarned
Hello all! I am typing this post from my new MacBook Pro with the M1 chip. I’m loving it so far, and will probably use it as my daily dr...
New
aalberti333
As the title describes, I’m trying to run Enum.map() over a list of key/value pairs, where the value is a map. My data looks like this: ...
New
fireproofsocks
I’m working on defining a simple Ecto schema for a table (in PostGres), but I don’t see where I can define a column as NOT NULL. Conside...
New
polypush135
As many of you may have realized by now (sorry for all the posts here) I’ve been working on a db problem where I’m trying to aggregate a ...
New
lk-geimfari
What is most correct way to open, read and parse JSON file with poison? For example if we have example.json file in root of some projec...
New
hariharasudhan94
I would like to know what is the best IDE for elixir development?
New
belgoros
I’m not a pro in using Regex and can’t figure out why the following behaviour happens, especially if we take into account the difference ...
New

We're in Beta

About us Mission Statement