Configuring VSCode to use with Elixir and Phoenix Templates

Hey :wave:t3: Elixir community,

I’ve been learning Elixir, and working on some side projects. My editor of choice is VSCode, and although I started somewhat seriously working with Elixir like a month ago, only today I finally was able to configure VSCode, so it will help me, rather than me fighting it. There are multiple extensions on VScode Marketplace, and it can be confusing to decide which ones to install. Initally, I went ahead, and installed almost all of them, which of course led to problems with configurations and those extensions fighting with each other. Here, I want to write down, which extensions I use (and which extensions I removed, because they are basically doing same things) and how I configured formatter in templates (biggest pain I had). All of the information provided here I actually found somewhere, usually in this forum, where other users already solved those issues, this post is just a bringing those solutions in one place, so all credit goes to those users and blog posts

I hope, it will be helpful for newcomers like me, when they are just starting, so they don’t have to fight the editor, and start coding instead.

Note: I don’t intend to say that authors of extensions I suggest to not use did bad job, actually most of the current tooling was built on top of those older tools. This is just a guide on latest extensions that are being supported

1. Language Servers and Elixir code

Language Server will do most of the work in your editor, intellisense, formatting, documentation lookup, code completion and more. Actually, if you are working only with elixir, and not with template engines for example, then with this extension you are basically covered.

There are two LS extensions available in the Marketplace:

  • ElixirLS: Elixir support and debugger by Jake Becker 77000+ installs
  • ElixirLS Fork: Elixir support and debugger by elixir-lsp 5500+ installs

All the common sense states that first options is the right one, right? Well, no, the first option was developed earlier, but original author is no longer working on that repo (latest commit, May 2019), so fork was created from that repo and currently is actively developed. More info can be found here (elixirforum post)

So, you should install ElixirLS Fork: Elixir support and debugger by elixir-lsp. Also, don’t forget to rate it, star it, share it, so it will become the obvious choice :smiley: (btw, I have no relation to the extension, except I am a grateful user)

From now on, I will refer to ElixirLS Fork as ElixirLS

There is another very popular extension called VSCode Elixir by Mat McLoughlin, with 143,000+ downloads. It has autosuggestions, snippets and syntax highlighting, but most (if not all) of the functionality is also provided by ElixirLS, and this extension was not updated since 2017.

2. Templates - file types and formatting

ElixirLS perfectly handles formatting of .ex and .exs files, but when you are working with Phoenix, chances are that you will be working with templates, HTML files with sprinkled elixir code. They will have .eex and .leex extensions (latter is for LiveView). However, usually editors treat these files as HTML files, and try to format accordingly, but they usually break because of the elixir code. In addition, small things like emmet also won’t work by default. So, here are configurations I added, to make working in Phoenix templates easier.

File Associations

It is possible, that VSCode will not recognize .eex and .leex files as Phoenix templates. ElixirLS adds file type HTML (EEx), which should help VSCode to recognize our templates, but in case it is not working for you, you can add configuration to settings.json file

  "files.associations": {
    "*.eex": "HTML (EEx)",
    "*.leex": "HTML (EEx)"
  },

If you had installed ElixirLS and VSCode Elixir(mentioned above) extensions together, then probably you will have two file types HTML (EEx) and HTML (Eex), and it was always confusing me. Turns out, just like ElixirLS adds HTML (EEx) type, VSCode Elixir adds HTML (Eex). I uninstalled VSCode Elixir, HTML (Eex) was gone and all other features are already provided by ElixirLS, so no problem

Emmet Support

Another very useful tool when working with HTML is Emmet. VSCode comes with emmet preinstalled, but to make it work in HTML (EEx) files, we need to add configuration below

  "emmet.includeLanguages": {
    "HTML (EEx)": "html"
  }

This will allow to use emmet, however, templates still will not have html intellisense provided by VSCode(like autocompletion of html tag attributes, documentation on hover etc). This is most probably because VSCode doesn’t have mixed language support. Other ecosystems like ruby, php seem to have same problem

Code formatting

This is something I struggled most with. I am very used to arranging html, cutting, pasting and then just running format, and have it perfectly aligned. However, it is not possible with HTML EEx files out of the box. Prettier cannot format this file type because of elixir code, and for some reason, HTML EEx cannot use standard vscode html formatter(even if you specify it as default formatter for this file type in the settings). And today, I came across a post in this forum that suggests to use Beautify. Install Beautify extension and add configuration below

  "beautify.language": {
    "js": {
      "type": [
        "javascript",
        "json",
        "jsonc"
      ],
      "filename": [
        ".jshintrc",
        ".jsbeautifyrc"
      ]
    },
    "css": [
      "css",
      "less",
      "scss"
    ],
    "html": [
      "htm",
      "html",
      "HTML (EEx)"
    ]
  }

Actually, most of it is autogenerated, when you type beautify.language in settings.json and hit Enter. You just need to add "HTML (EEx)" bit(or just copy and paste the thing above, that’s easiest). With this, you will be able to format your .eex and .leex files. Of course, it is not perfect, it will only format your HTML code(and not whatever inside <% %>). Also I found that Beautify does not format as good as Prettier does, but it get’s the job done.

If you have any additional tips on how to configure editor, please leave them here, I am sure, I personally will benefit from it, and hopefully other newcomers too.

I would also suggest to look at blog posts from Mark Ericksen

33 Likes

Thanks for this post.
Indeed it’s a great idea to have here a summary for VSCode.

In my case working with docker containers, ElixirLS is working out of the box with VSCode remote devcontainer options while ElixirLS Fork is not.
Either I should have missed something in the configuration or it’s simply not working because of docker being not supported (which I found it a bit odd for a fork to remove some functionalities).

You can also edit you post to include some Syntax Highlighting (or color theme) options that works well with Elixir. And maybe also some font options that provide for example ligatures (like Fira Code) for some symbols used in Elixir like |>.

Interesting, I don’t have much experience working with docker, but do you mean you run your VSCode from docket container?

Good suggestion, regarding the color themes and ligature fonts, but i find them very subjective, I will post a link to a poll in this forum though, which has all shades of themes that are used by elixir devs :slight_smile:

Edit: Looks like I can no longer edit this post, but for those who are interested in Editor Themes, here’s a great elixirforum post

Nope…
VSCode is running in my Host (where I have a GUI you know… I’m not yet that bearded to go full CLI even if I have almost a fount long beard : )

However VSCode can “connect” to a running docker container (in my case where all elixir/erlang stuff is installed and where the code will run).
Then it can run any Language Server Protocol within the container where the “binaries” reisde (I mean the “executables” like mix or anything elixir-lsp requires etc.).

That’s interesting, I am assuming motivation on doing that is to have same environment for development and production. How hard is it to set up, do you have a link to some guide?

At first the motivation is indeed to less environment based issue when developing.
But using Docker (and even more advanced DevOps tools like Kubernetes and process like CI/CD etc. which I’m not yet into them besides Docker and Compose) is a game changer IMHO.

In my case I fully switched to Docker and no matter the environment (Ruby/Rails, Python, any CMS and obviously Elixir) deploying to production is a matter of git push and docker-compose up.

As I said there is even more to do like CI/CD and many more. It’s a whole subject.

But just Docker to begin with has a lot of benefits.

Not so hard actually.
I mean knowing all the nitty-gritty of Docker will obviously have some learning curve.
But you can start small.

I don’t have a guide particularly as I started with Docker more than 3 years ago.
But Official Docker documentation is great…
And if you are more of a practice guy you can even look at the Elixir Docker image page and start right away with the provided example. Once Docker is installed if you just run docker run -it --rm elixir you will be right in IEx but within a container:

~> docker run -it --rm elixir
Erlang/OTP 18 [erts-7.2.1] [source] [64-bit] [smp:8:8] [async-threads:10] [hipe] [kernel-poll:false]

Interactive Elixir (1.2.1) - press Ctrl+C to exit (type h() ENTER for help)
iex(1)>

From now you can setup VS Code (more in the documentation of VS Code here) to connect to that instance.

But I suggest you to practice Docker by itself first (with docker-compose right from the beginning and learning how to attach your host directory to the container using Volumes).

I hope this will help at least a little. You can also look at Google I’m sure there will be a ton of results for “elixir docker”.

2 Likes

Very handful sharing.

This thread may interrest you as well:

1 Like

Had VSCode setup and everything was working great.

Came back to a project recently and found that ElixirLS is now not a fork, so removed the fork and installed the official version. Now, .html.eex files are not recognized if I use the settings above. If I remove all of the file association settings, then it does recognize .html.eex files, but I can’t use emmet and beautify no longer recognizes the files.

This is perhaps related to the “rename of filetype slugs”. “HTML (EEx)” has been renamed to “html-eex” at some point in time to adhere to conventions in the VScode community.

1 Like

This sounds like the potentially breaking change in 0.4.0. There’s a note about it in the changelog: elixir-ls/CHANGELOG.md at 7b43622efc94399d21fe665edff5a37667454fb2 · elixir-lsp/elixir-ls · GitHub

Here’s the relevant portion:

  • Change language id to be lowercase kebab-case in accordance with VSCode guidelines. This also fixes an issue displaying the elixir logo for html.eex files. (thanks Matt Furden) #87
  • This changes the language id’s EExeex and HTML (EEx)html-eex
  • If you have customized your emmet configuration configuration then you need to update it:
  • Open VSCode and hit Ctrl+Shift+P or Cmd+Shift+P and type "Preference: Open Settings (JSON)"
  • Add or edit your emmet.includedLanguages to include the new Language Id:
"emmet.includeLanguages": {
 "html-eex": "html"
}

If you have eex file associations in your settings.json then remove them:

"files.associations": {
 "*.html.eex": "HTML (EEx)", // remove this
 "*.html.leex": "HTML (EEx)" // remove this
},
4 Likes

Thanks. Google failed me. I figured there was a change that I was missing.

2 Likes

I followed all the settings described earlier in the post, but there is no code highlighting in *.html.heex templates, - everything is just black.

Here si what I have in my VS code settings.json file:

...
"emmet.includeLanguages": {
    "html-eex": "html",
    "elixir": "html",
    "Handlebars": "html",
    //"HTML (EEx)": "html",
    "postcss": "css",
    "html.erb": "html",
    "erb": "html"
  },
"files.associations": {
    "*.ex": "elixir",
    "*.exs": "elixir",
    "*.eex": "html-eex",
    "*.leex": "html-eex",
    "*.erb": "erb"
  },
  "tailwindCSS.includeLanguages": {
    "phoenix-heex": "html",
    "html-eex": "html",
    "plaintext": "html",
    "Handlebars": "html",
    "html.erb": "html",
    "erb": "html"
  },
  "beautify.language": {
    "js": {
      "type": ["javascript", "json", "jsonc"],
      "filename": [".jshintrc", ".jsbeautifyrc"]
    },
    "css": ["css", "less", "scss"],
    "html": ["htm", "html", "HTML (EEx)"]
  }
...

I’m using ElixirLS extension, v0.9.0, VS Code version: 1.63.2 (Universal). Any idea on what I’m missing here? Thank you.

I had to choose explicitely html-eex file association type in the right-bottom corner of the editor instead of phoenix-heex that was choosen by default:

Screenshot 2022-01-10 at 14.35.54
Why so? Is there a way to tell VS Code to associate phoenix templates correctly?

Screenshot 2022-01-10 at 14.39.29

My bad, it was a typo in the files.associations value:

"*.eex": "html-eex",
...

instead of:

"*.html.heex": "html-eex",
...

As I’m learning Elixir and Phoenix, I’ve been struggling with formatting and auto-complete in Sublime Text so I thought I’d give VS Code a try and this thread is very helpful! Some updates as a new person going through things.

Came back to a project recently and found that ElixirLS is now not a fork, so removed the fork and installed the official version. Now, .html.eex files are not recognized if I use the settings above.

I found a similar thing. When looking at the extensions within VS Code, they explicitly said not to use ElixirLS Fork any longer. I’m assuming the Fork folk are in control of mainline now.

For .heex files, I searched ElixirLS Issues, where they explicitly say they do not support .heex files and to use the phoenix extension.

Then if you want Emmet functionality you will need to reference the “phoenix-heex” language as written here.

I have not figured out how to get Beautify to recognize “phoenix-heex” for HTML formatting. I assumed I could just add “phoenix-heex” or “HEEx” to the “html” list, but it hasn’t worked for me.

Welcome :smile:

Did you manage to get formatting working? I ditched beautify in favour of heex_formatter, which just got merged into the main branch of phoenix_live_view and should be available out of the box soon™. That lets you run mix format for both Elixir and HEEx code.

Here’s a possible vscode keybinding + task setup.