Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feature Request: Support mix format plugins #660

Closed
axelson opened this issue Jan 21, 2022 · 17 comments · Fixed by #690
Closed

Feature Request: Support mix format plugins #660

axelson opened this issue Jan 21, 2022 · 17 comments · Fixed by #690
Labels
enhancement New feature or request

Comments

@axelson
Copy link
Member

axelson commented Jan 21, 2022

Elixir 1.13 added mix format plugins: https://hexdocs.pm/mix/1.13.2/Mix.Tasks.Format.html#module-plugins

ElixirLS should support these plugins if defined in the user's project.

Initially requested in: elixir-lsp/vscode-elixir-ls#224

@megalithic
Copy link

megalithic commented Jan 21, 2022

Would this also enable support for elixir-ls to format, via LSP, *.html.heex files, too?

confirmed; a formatter plugin will allow for this.

@zachdaniel
Copy link

I may have time to make a PR to add support for this, what has to be done to make it work?

@msaraiva
Copy link
Collaborator

msaraiva commented Feb 4, 2022

@zachdaniel -> elixir-lsp/vscode-elixir-ls#224 (reply in thread)

@megalithic
Copy link

megalithic commented Feb 8, 2022

Super pumped for this! Thanks y'all!

@anildigital
Copy link

Anyone know if it works for elixir-ls in Emacs?

@benvp
Copy link

benvp commented Apr 7, 2022

With the recent addition of the LiveView formatter in 0.17.8 I noticed that the formatting does work automatically in VSCode when using .ex files with the ~H sigil. But using html.heex files it gives the following error:

[Error - 07:32:49] Request textDocument/formatting failed.
  Message: Unable to format due to syntax error
  Code: -32603 
MIX_ENV: test
MIX_TARGET: 

I used the sample code from the elixir formatter docs.

test.html.heex:

<section><h1>   <b><%= @user.name %></b></h1></section>

.formatter.exs

[
  import_deps: [:phoenix],
  plugins: [Phoenix.LiveView.HTMLFormatter],
  inputs: ["*.{heex,ex,exs}", "priv/*/seeds.exs", "{config,lib,test}/**/*.{heex,ex,exs}"]
]

@frankdugan3
Copy link

@benvp After upgrading LV, did you run mix deps.compile before mix format?

@benvp
Copy link

benvp commented Apr 8, 2022

@frankdugan3 Yeah I did that. Also deleted the build and deps folder. When running mix format directly on the .html.heexfile formatting works. But not when running through VSCode with the Elixir LSP.

@frankdugan3
Copy link

@benvp I forgot to mention it, but it also requires Elixir v1.13.4. What version are you running?

@littleStudent
Copy link

I have the exact same situation as @benvp described.

  • running mix format in the console works
  • running the formatter through vscode results in the described error
  • I have version 1.13.4 running

@DaliborHorinek
Copy link
Contributor

I can confirm the same issue.

elixir v1.13.4
neovim 0.7.0 + lspconfig and ElixirLS build from master (7f37d59)

.formatter.exs

[
  plugins: [Phoenix.LiveView.HTMLFormatter],
  import_deps: [:ecto, :phoenix],
  inputs: ["*.{heex,ex,exs}", "priv/*/seeds.exs", "{config,lib,test}/**/*.{heex,ex,exs}"],
  subdirectories: ["priv/*/migrations"]
]

Phoenix LiveView

      {:phoenix_live_view, "~> 0.17.9"},

.ex files with ~H are formatted correctly

.heex file returns error

"rpc.receive"   {  error = {    code = -32603,    message = "Unable to format due to syntax error"  },  id = 4,  jsonrpc = "2.0"}

Added inspect for the exception

Error: %SyntaxError{
  column: 1,
  description: "syntax error before: '<'",
  file: "nofile",
  line: 1,
  snippet: %{content: "<div><%= @inner_content %></div>", 
  offset: 0
}

@inoas
Copy link

inoas commented Apr 25, 2022

Slightly OT, VSCode instructions

For anything to work, you will need a recent Elixir version. I got 1.13.4 running. Also .formatters.exs must contain heex and the HTMLFormatter plugin:

[
  import_deps: [:ecto, :phoenix],
  plugins: [Phoenix.LiveView.HTMLFormatter],
  inputs: ["*.{heex,ex,exs}", "priv/*/seeds.exs", "{config,lib,test}/**/*.{heex,ex,exs}"],
  subdirectories: ["priv/*/migrations"]
]

Then apparently the .heex-files and ~H-sigil formatting isn't the same.

At least for me this plugin does not work with mix format from VSCode, neither calling it from the command bar in VSCode nor on autoformat on save.

ElixirLS: Elixir support and debugger
Id: JakeBecker.elixir-ls
Description: Elixir support with debugger, autocomplete, and more. Powered by ElixirLS.
Version: 0.9.0
Publisher: ElixirLS
VS Marketplace Link: https://marketplace.visualstudio.com/items?itemName=JakeBecker.elixir-ls

However this plugin works for doing the same thing:

Name: Elixir Mix Formatter
Id: animus-coop.vscode-elixir-mix-formatter
Description: Elixir Mix Formatter integrated into Visual Studio Code.
Version: 1.0.1
Publisher: Animus Coop.
VS Marketplace Link: https://marketplace.visualstudio.com/items?itemName=animus-coop.vscode-elixir-mix-formatter

You will have to change (or remove, and it will ask) the default formatter in your VSCode settings.json, example:

"[phoenix-heex]": {
  "editor.defaultFormatter": "animus-coop.vscode-elixir-mix-formatter", // Relevant line
  "editor.detectIndentation": false,
  "editor.formatOnPaste": true,
  "editor.formatOnSave": true,
  "editor.formatOnType": true,
  "editor.tabSize": 2,
  "editor.trimAutoWhitespace": true,
  "files.insertFinalNewline": false,
  "files.trimTrailingWhitespace": true
},

I hope this helps someone.

@DaliborHorinek
Copy link
Contributor

The actual problem (IMHO) is that ElixirLS uses Code.format_string! which receives options from Mix.Tasks.Format.formatter_opts_for_file, but format_string! doesn't accept plugins as an option. So it doesn't know how to format .heex files.

mix format works because it understands the plugins.

What can be done here, is to use Mix.Tasks.Formatter.formatter_for_file/2 to format the source file, same as the mix format does.

Would this be a way to go? If this is valid, I might be able to prepare a PR for this.

DaliborHorinek pushed a commit to DaliborHorinek/elixir-ls that referenced this issue Apr 26, 2022
* Use formatter_for_file instead of formatter_opts_for_file which is
  deprecated now

* Fallback to original Code.format_string!
DaliborHorinek pushed a commit to DaliborHorinek/elixir-ls that referenced this issue May 2, 2022
* Use formatter_for_file instead of formatter_opts_for_file which is
  deprecated now

* Fallback to original Code.format_string!
DaliborHorinek pushed a commit to DaliborHorinek/elixir-ls that referenced this issue May 2, 2022
* Use formatter_for_file instead of formatter_opts_for_file which is
  deprecated now

* Fallback to original Code.format_string!
@LOG67
Copy link

LOG67 commented Jun 6, 2022

Any update on this issue? It looks like the PR #690 is accepted but not merged. Thank you guys for your work on this!

lukaszsamson pushed a commit that referenced this issue Jun 21, 2022
* Use formatter_for_file instead of formatter_opts_for_file which is
  deprecated now

* Fallback to original Code.format_string!

Co-authored-by: Dalibor Horinek <dal@horinek.net>
@zachdaniel
Copy link

🥳 🎉 🙇🏻 ❤️

@ddengler
Copy link

Note for others or future me to find. My formatter failed with plugin not found on vscode elixir-ls ONLY. Console worked properly. The issue was that elixir-ls was building as test env.

This failed as a result:
{:tailwind_formatter, "~> 0.4.0", only: :dev, runtime: false}

This obviously works:
{:tailwind_formatter, "~> 0.4.0", only: [:dev, :test], runtime: false}

@lukaszsamson
Copy link
Collaborator

@ddengler You can switch ElixirLS mix env to dev via extension config if that works better in your case

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request
Projects
None yet
Development

Successfully merging a pull request may close this issue.