ar7casper

ar7casper

How to set up Neovim for tailwind intelisense in Phoenix files?

Shoutout to nvim users.

I’m trying to make tailwind work in phoenix files (heex, ex, etc).
No matter what config I have, the cmp doesn’t help me with tailwind intelisense in phoenix files.
It works in other envs (HTML, React, etc).

I suspect it has something to do with the fact the config file is under ./assets/tailwind.config.js.

my lsp config for tailwind -

tailwindcss = {
          root_dir = function(fname)
            return require('lspconfig.util').root_pattern(
              'assets/tailwind.config.ts',
              'assets/tailwind.config.js',
              'assets/tailwind.config.cjs',
              'assets/package.json',
              '.git'
            )(fname) or vim.fn.getcwd()
          end,
          settings = {
            tailwindCSS = {
              experimental = {
                classRegex = {
                  -- For Phoenix `class="..."` syntax
                  { 'class[:]\\s*"([^"]*)"', 1 },
                  -- For Phoenix `~H` and `HEEx` tags
                  { '~H"([^"]*)"', 1 },
                },
              },
              includeLanguages = {
                elixir = 'html-eex',
                eelixir = 'html-eex',
                heex = 'html-eex',
              },
            },
            -- tailwindCSS = {
            --   experimental = {
            --     classRegex = {
            --       'class[:]\\s*"([^"]*)"',
            --     },
            --   },
            -- },
          },
        }

LspInfo output:

CmpStatus output:

Most Liked

ryanwinchester

ryanwinchester

This is my config, and note the filetypes_include = { "heex" } part

That was what got it working for me as well, and nothing else worked.

{
    "neovim/nvim-lspconfig",
    opts = {
      servers = {
        tailwindcss = {
          -- exclude a filetype from the default_config
          filetypes_exclude = { "markdown" },
          -- add additional filetypes to the default_config
          filetypes_include = { "heex" },
          -- to fully override the default_config, change the below
          -- filetypes = {}
        },
      },
      setup = {
        tailwindcss = function(_, opts)
          local tw = LazyVim.lsp.get_raw_config("tailwindcss")
          opts.filetypes = opts.filetypes or {}

          -- Add default filetypes
          vim.list_extend(opts.filetypes, tw.default_config.filetypes)

          -- Remove excluded filetypes
          --- @param ft string
          opts.filetypes = vim.tbl_filter(function(ft)
            return not vim.tbl_contains(opts.filetypes_exclude or {}, ft)
          end, opts.filetypes)

          -- Additional settings for Phoenix projects
          opts.settings = {
            tailwindCSS = {
              includeLanguages = {
                elixir = "html-eex",
                eelixir = "html-eex",
                heex = "html-eex",
              },
            },
          }

          -- Add additional filetypes
          vim.list_extend(opts.filetypes, opts.filetypes_include or {})
        end,
      },
    },
  },
soup

soup

From poking around, this fixes it.

config = {
  tailwindcss = {
    settings = {
      tailwindCSS = {
        -- docs imply it should be html, js or css, but you can also specify
        -- another "known" language so `heex = "phoenix-heex"` or
        -- `heex = "HTML (EEx)"` also works. I think they just all get
        -- treated as "html" by tailwind (effecting if it looks for class="" for completion triggers)
        -- but could not say for certain.
        includeLanguages = {heex = "html"}
      }
    }
  }
}

My assets/tailwind.config.js should be pretty normal, I point my content like so:

module.exports = {
  content: [
    '../lib/**/*.ex',
    '../lib/**/*.leex',
    '../lib/**/*.heex',
    '../lib/**/*.exs',
    '../lib/**/*.eex',
    './js/**/*.js'
  ],
  // ...
}

You can verify your settings are correctly merged with
:=require'lspconfig'.tailwindcss.manager.config.settings (probably only after opening a file).

Considering tailwind lists HTML (EEx), HTML (Eex) and html-eex in its htmlLanguages list, I think it’s just matching any free form string that the LSP client sends as the file/language type, so possibly adding heex would be a good PR. I guess vs-code reports it as phoenix-heex? I assume all those types behave the same. (Or maybe I have configured my neovim to call it heex at some point, you can check your own configs name with :set ft? with a file open).

Note there are two npm packages, @tailwindcss/language-server and tailwindcss-language-server (defunct). @tailwindcss/language-server is what I got working.

References:

Default nvim-lspconfig tailwind settings: nvim-lspconfig/lua/lspconfig/configs/tailwindcss.lua at master · neovim/nvim-lspconfig · GitHub

Tailwind LSP settings: GitHub - tailwindlabs/tailwindcss-intellisense: Intelligent Tailwind CSS tooling for Visual Studio Code · GitHub

Tailwind LSP known languages: tailwindcss-intellisense/packages/tailwindcss-language-service/src/util/languages.ts at 434c7db38d0eaf1b854678e5e1d7db9e7322ceef · tailwindlabs/tailwindcss-intellisense · GitHub

soup

soup

Hm, I just noticed you have heex = "html-eex" in your config, so I am not sure why yours is not working beyond maybe its not getting merged correctly. Maybe check it with :=require'lspconfig'.tailwindcss.manager.config.settings.

I can 100% confirm that mine did not function until I added that line. I only installed the LSP and set it up for this thread.

Where Next?

Popular in Questions Top

tduccuong
Hi, is there any work on GUI with Elixir, that is similar to Electron/Javascript? My idea is to bundle Phoenix and BEAM into a single se...
New
aadeshere1
I have a another noob question about loop. Since elixir is immutable, while loop is not directly possible. total = 10 while total != 0 ...
New
siddhant3030
Hi, I have to write a raw query for one of my project. But till now I have used ecto queries and don’t have much experience writing raw ...
New
Kurisu
For example for a current url like http://localhost:4000/cosmetic/products?_utf8=✓&query=perfume&page=2, I would like to get: ...
New
pmjoe
I have a relationship of love and hate with Elixir. Lots of things are just absolutely right, but there are some things that are kind of ...
New
RisingFromAshes
I’ve read in another post that it may be possible with a router helper - but I couldn’t find an appropriate one, and tbh, I’m still just ...
New
LegitStack
I’m trying to make a websocket server in Phoenix or raw Elixir. I heard about gun, I think I could use cowboy, but since I’m not that sma...
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
sergio_101
I am VERY much an elixir newbie. I have taken one elixir course and one phoenix course on Udemy. During that course, I saw the instructor...
New
Brian
What is the proper way to load a module from a file in to IEX? In the python world, doing something like this pretty standard: from ....
New

Other popular topics Top

siddhant3030
Hi, I have to write a raw query for one of my project. But till now I have used ecto queries and don’t have much experience writing raw ...
New
TunkShif
This post is an instruction guide to help you setup your Neovim for Elixir development from scratch. It includes general information on h...
274 41539 114
New
JakeBecker
TL;DR: I’ve just released an implementation of Microsoft’s IDE-independent Language Server Protocol for Elixir. It adds language support ...
1144 53690 245
New
shahryarjb
Hello, I have map which I want to convert it to string like this: the map: %{last_name: "tavakkoli", name: "shahryar"} the string I ne...
New
chrismccord
This release brings a number of exciting features, including integration with the new Phoenix LiveDashboard and Phoenix LiveView. There h...
New
ashish173
I am using Ecto timestamps with postgres, I can see the timestamps() use the :naive_dateime but for my use case I wanted to store the ti...
New
shijith.k
I am trying to start a new phoenix project with elixir 1.9, but mix phx.new does not work. It says that ** (Mix) The task "phx.new" could...
New
joaquinalcerro
Hi there, I am working with Ecto-Postgresql and I need to call all of the records from a specific table but the table has 40,000 records...
New
hariharasudhan94
Lets say i have map like this fetching from my database %{"_id" => #BSON.ObjectId<58eb1a7a9ad169198c3dXXXX>, "email" => "XXX...
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

We're in Beta

About us Mission Statement