brkn

brkn

Elixir script file without extension is ignored by `mix format`

My env and context

  • Elixir 1.19.1
  • Erlang 28.1.1
  • Editor: vscodium (Basically same as vscode)
  • Vscodium Extension: ElixirLS v0.30.0
  • Not sure if it matters: zsh, macos arm
  • I’m a beginner in elixir and beam

My problem

I have a language agnostic repo, and I’m trying to get my editor to format my script files.

Example scripts/upcase

  #!/usr/bin/env elixir

  case System.argv() do
    [] -> IO.read(:stdio, :all)
    args -> Enum.join(args, " ")
  end
  |> String.upcase()
  |> IO.puts()

When I open this file on my editor, it detects the language and syntax highlights correctly but format file command doesn’t work.

So I thought I could do it via mix format but that didn’t work either, silently exits without formatting.

What I tried

  1. mix format scripts/upcase is silently exiting, no changes.
  2. Could it be because my lang agnostic repo doesn’t have .formatter.exs file?
    1. mix format –-dot-formatter ~/.formatter.exs scripts/upcase
    2. ❯ cat ~/.formatter.exs                                        
      [
        inputs: ["scripts/upcase"]
      ]
      
    3. still silently exiting, file is not changed.
  3. After reading the mix format docs carefully, I realized I can pipe string into mix format -
    1.   mix format - < scripts/upcase > /tmp/temp && mv /tmp/temp scripts/upcase
      
    2. Yes this works, but it’s very clunky.

Why could this be?

So I dived into the source, and I think this block is the culprit

defp find_formatter_for_file(file, formatter_opts) do
  # ...
  cond do
    # ...
    ext in ~w(.ex .exs) ->
        &elixir_format(&1, [file: file] ++ formatter_opts)
    true ->
        & &1
  end
  # ...
end

Can I create a formatter plugin for extensionless files?

I thought this could be a solution, but I am not sure what’s the best way to do this since elixir_format/2 is a private method, see on github.

Should I copy the method’s body, and use Code.format_string!/2 ?

First Post!

Eiji

Eiji

I would not recommend writing Elixir scripts without extension. I understand that you don’t want to type .exs, but you can create a shell aliases for such cases. You can even write a simple look that would iterate all of your projects, enter the scripts directory, read files and create alias for each of them. In my opinion that the best you can do.

However it’s not the limit of your possibilities. If you are fine with a workaround then you can add a custom plugin for your formatter.exs configuration. Such plugin can register itself to "" (empty string) as one of allowed extensions. Since Path.extname/1 returns empty string only if a string does not have extension your plugin should always work only for the scripts you wanted.

The rest is to call the standard formatter inside your plugin as you already did in your 3rd point in the shell.

For more information please take a look at the following documentation pages:

  1. Plugins | mix format (task) @ mix documentation
  2. System.cmd/3 @ Elixir documentation
  3. Path.extname/1 @ Elixir documentation

Last Post!

brkn

brkn

I know that I can copy, or even better create symlinks, but I would rather not.

It’s not impossible, vscode’s official typescript extension can handle this just fine. Try it yourself, it works for both unsaved editor or extensionless file.

#! /usr/bin/env node

console.log(
        "white space is way off"
    )

Where Next?

Popular in Questions Top

rms.mrcs
Hi, I need to transform a list of numbers into a map where the keys are the indexes and the values are the original values of the list. ...
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
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
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
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
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
vrod
I am using the Starship cross-shell prompt – it seems pretty nice, but I get some errors: [WARN] - (starship::utils): Executing command ...
New

Other popular topics Top

Qqwy
Update: How to use the Blogs &amp; Podcasts section You can post links to your blog posts or podcasts either in one of the Official Blog...
3271 130286 1222
New
vertexbuffer
Hello, can anybody help here..? I have a list of players and I what to delete an element, but every for loop the list is reverting to ori...
New
grych
Hi folks, Few months ago I have announced the proof-of-concept of the library to manipulate the browsers DOM objects directly from Elixi...
639 54006 488
New
jononomo
I am trying to figure out how Mix knows whether the environment is test, dev, or prod – where is this set? Thanks.
New
nsuchy
Hi. I’ve noticed that Windows Powershell has it’s own IEX command and you cannot access Elixir’s IEX due to the conflict. This isn’t a cr...
New
gshaw
What is the idiomatic way of matching for not nil in Elixir? E.g., First way: defp halt_if_not_signed_in(conn, signed_in_account) when...
New

We're in Beta

About us Mission Statement