Sorry to revive this, I’m experiencing this all the time in NeoVim (LazyVim). I’ve already updated all plugins to their latest versions, and using Eliixir 1.15. It doesn’t add parenthesis in VS Code. Not sure what else to try…
Not sure if that helps but you could just specify these exceptions in your own .formatter.exs in the root of your project. Here’s an example from one of mine:
So it does seem to use elixir_ls under the hood, but for some reason it only behaves correctly in VS Code wrt formatting (other functionality like linting works well).
Even though I use NeoVim for a year or so now, I am very slowly learning it (not enough time or energy to become a pro there at the moment). So not sure I can help – maybe try disabling credo?
Thanks for the suggestion - I tried both with and without credo, I think it was always like that for me. It’s strange that there aren’t many reports of this, and the ones from the GH issue you linked seemed to have been resolved by 1.15. I’m just at a loss how to even troubleshoot this further, but will probably file a new issue on GH as next step.
Have you tried the usual desperate measures like removing the deps and _build directories and fetching deps + compiling from scratch? Removing the .elixir_ls directory as well before opening an editor?
That didn’t seem to help at first, but it did re-create .elixir_ls dir in the parent (!) folder when I re-opened the child application folder using cd <app> && nvim . (seemingly without restoring nvim session)
And, it looks like I’ve overlooked the obvious - my .formatter.exs was created automatically by Phoenix at the root of the application directory, but there wasn’t one in the parent folder (where .elixir_ls is). I’ve just added this very simple one there:
[
inputs: ["*.{heex,ex,exs}"]
]
and suddenly it no longer adds parenthesis! That said, now the one in the application folder doesn’t seem to apply. So It seems elixir_ls really “wants” to live in the parent folder when used via this Neovim setup. This is not the same behavior as in VS Code, where .elixir_ls is stored in the app folder if it’s opened directly. I might need to dig a bit deeper into that.
No worries, I was just flailing about and trying to go through the usual checklist. Glad that helped somewhat.
As far as I remember, Elixir itself wants stuff to be in the root of the project – and if you have an umbrella, that opens the door for such problems that you witnessed. But I’ll let you determine this for yourself, just citing my semi-reliable memories.
FWIW, you can try have multiple copies of the same .formatter.exs in the root dir and the subdirs?
Alas, when I make a verbatim copy of that, Neovim Elixir plugin just complains since it cannot find Ecto and other Elixir dependencies in the parent folder, and all of the paths in .formatter.exs are relative to that folder so they no longer seem to work (unless maybe I prepend **/ to all, which I can try).
You can always generate a new umbrella Phoenix app that will give a boilerplate on how those files are generated.
This issue is related to LazyVim changing Neovim’s cwd which would cause some weird interactions with neotree, for instance. It would change the file tree from neotree to only display ./apps/analytics_web in certain scenarios.
Since you’re using LazyVim, which uses nvim-lspconfig, the actual “directory” for ElixirLs is defined here:
I changed that recently to give priority to a .git folder in the root dir, so that you only have one ElixirLS in the entire umbrella app.
Thanks @georgeguimaraes - yes, and someone else responded in LazyVim discussions re root_dir in ElixirLS config as well.
I wonder if it’s possible to have an umbrella .formatter.exs without an umbrella app - would that look something like this?
[
subdirectories: ["*"]
]
I tried that, and when I save a child router.ex for example, elixirls flashes an error saying something like Unable to find formatter for /Users/<user>/code/phoenix-apps/app/lib/app_web/router.ex: "** (Mix.Error) Unknown dependency :ecto_sql given to :import_deps in the formatter configuration. Make sure the dependency is listed in your mix.exs for environment :test and you have run \"mix deps.get\"\n (mix 1.15.7) lib/mix.ex:577: Mix.raise/2\n (language_server 0.17.7) lib/language_server/mix_tasks/format.ex:489: anonymous fn/3 in Mix.Tasks.ElixirLSFormat.eval_deps_opts/2\n (elixir 1.15.7) lib/enum.ex:2510: Enum.\"-reduce/3-lists^foldl/2-0-\"/3\n (language_server 0.17.7) lib/language_server/mix_tasks/format.ex:488: Mix.Tasks.ElixirLSFormat.eval_deps_opts/2\n (language_server 0.17.7) lib/language_server/mix_tasks/format.ex:437: anonymous fn/8 in Mix.Tasks.ElixirLSFormat.eval_deps_and_subdirectories/8\n (language_server 0.17.7) lib/language_server/mix_tasks/format.ex:425: Mix.Tasks.ElixirLSFormat.eval_deps_and_subdirectories/8\n (language_server 0.17.7) lib/language_server/mix_tasks/format.ex:512: anonymous fn/6 in Mix.Tasks.ElixirLSFormat.eval_subs_opts/7\n (elixir 1.15.7) lib/enum.ex:1297: anonymous fn/3 in Enum.flat_map_reduce/3\n" (this is despite ecto_sql being present in mix.exs and installed, for the child app)