Skip to content

Commit bd66fa9

Browse files
committed
add neovim/tailwind post
1 parent 5a0c2a4 commit bd66fa9

File tree

1 file changed

+135
-0
lines changed

1 file changed

+135
-0
lines changed
Lines changed: 135 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,135 @@
1+
+++
2+
title = "Tailwind IntelliSense in Elm: A NeoVim Recipe"
3+
description = "Quick setup guide for getting Tailwind CSS autocomplete and hover working with Elm in NeoVim"
4+
tags = ["elm", "neovim", "tailwind", "lsp", "recipe"]
5+
date = "2025-07-04"
6+
draft = false
7+
+++
8+
9+
If you're using Elm with Tailwind CSS in NeoVim, you've probably noticed that IntelliSense doesn't work out of the box. Here's a quick recipe to fix that.
10+
11+
## The Problem
12+
13+
Tailwind's LSP doesn't recognize Elm's syntax for CSS classes. When you write:
14+
15+
```elm
16+
div [ class "bg-blue-500 text-white p-4" ] [ text "Hello" ]
17+
```
18+
19+
You get no autocomplete, no validation, and no hover documentation for your Tailwind classes.
20+
21+
## The Solution
22+
23+
### My Setup (LazyVim)
24+
25+
Here's what works for me using LazyVim. If you're using a different NeoVim distribution, your mileage may vary:
26+
27+
```lua
28+
{
29+
"neovim/nvim-lspconfig",
30+
opts = {
31+
servers = {
32+
tailwindcss = {
33+
filetypes_include = { "elm" },
34+
-- exclude a filetype from the default_config
35+
filetypes_exclude = {},
36+
},
37+
},
38+
setup = {
39+
tailwindcss = function(_, opts)
40+
local tw = LazyVim.lsp.get_raw_config("tailwindcss")
41+
opts.filetypes = opts.filetypes or {}
42+
43+
-- Add default filetypes
44+
vim.list_extend(opts.filetypes, tw.default_config.filetypes)
45+
46+
-- Remove excluded filetypes
47+
opts.filetypes = vim.tbl_filter(function(ft)
48+
return not vim.tbl_contains(opts.filetypes_exclude or {}, ft)
49+
end, opts.filetypes)
50+
51+
opts.settings = {
52+
tailwindCSS = {
53+
includeLanguages = {
54+
elm = "html",
55+
},
56+
experimental = {
57+
classRegex = {
58+
{ [[\bclass[\s(<|]+"([^"]*)"]] },
59+
{ [[\bclass[\s(]+"[^"]*"\s+"([^"]*)"]] },
60+
{ [[\bclass[\s<|]+"[^"]*"\s*\+{2}\s*" ([^"]*)"]] },
61+
{ [[\bclass[\s<|]+"[^"]*"\s*\+{2}\s*" [^"]*"\s*\+{2}\s*" ([^"]*)"]] },
62+
{ [[\bclass[\s<|]+"[^"]*"\s*\+{2}\s*" [^"]*"\s*\+{2}\s*" [^"]*"\s*\+{2}\s*" ([^"]*)"]] },
63+
{ [[\bclassList[\s\[\(]+"([^"]*)"]] },
64+
{ [[\bclassList[\s\[\(]+"[^"]*",\s[^\)]+\)[\s\[\(,]+"([^"]*)"]] },
65+
{ [[\bclassList[\s\[\(]+"[^"]*",\s[^\)]+\)[\s\[\(,]+"[^"]*",\s[^\)]+\)[\s\[\(,]+"([^"]*)"]] },
66+
},
67+
},
68+
},
69+
}
70+
71+
-- Add additional filetypes
72+
vim.list_extend(opts.filetypes, opts.filetypes_include or {})
73+
end,
74+
},
75+
},
76+
}
77+
```
78+
79+
### For Vanilla NeoVim
80+
81+
If you're using plain nvim-lspconfig, I'm guessing you'd need something like this (but I'm mostly spitballing here - you get the idea):
82+
83+
```lua
84+
require('lspconfig').tailwindcss.setup({
85+
filetypes = {
86+
'html', 'css', 'javascript', 'typescript', 'react', 'vue', 'svelte', 'elm'
87+
},
88+
settings = {
89+
tailwindCSS = {
90+
includeLanguages = {
91+
elm = "html",
92+
},
93+
experimental = {
94+
classRegex = {
95+
{ [[\bclass[\s(<|]+"([^"]*)"]] },
96+
{ [[\bclass[\s(]+"[^"]*"\s+"([^"]*)"]] },
97+
{ [[\bclass[\s<|]+"[^"]*"\s*\+{2}\s*" ([^"]*)"]] },
98+
{ [[\bclass[\s<|]+"[^"]*"\s*\+{2}\s*" [^"]*"\s*\+{2}\s*" ([^"]*)"]] },
99+
{ [[\bclass[\s<|]+"[^"]*"\s*\+{2}\s*" [^"]*"\s*\+{2}\s*" [^"]*"\s*\+{2}\s*" ([^"]*)"]] },
100+
{ [[\bclassList[\s\[\(]+"([^"]*)"]] },
101+
{ [[\bclassList[\s\[\(]+"[^"]*",\s[^\)]+\)[\s\[\(,]+"([^"]*)"]] },
102+
{ [[\bclassList[\s\[\(]+"[^"]*",\s[^\)]+\)[\s\[\(,]+"[^"]*",\s[^\)]+\)[\s\[\(,]+"([^"]*)"]] },
103+
},
104+
},
105+
},
106+
},
107+
})
108+
```
109+
110+
## What's Happening
111+
112+
Both configs do the same thing with different syntax:
113+
114+
1. **Add `elm` to filetypes** - Tells Tailwind LSP to activate for Elm files
115+
2. **`includeLanguages = { elm = "html" }`** - Treats Elm syntax like HTML for class detection
116+
3. **`classRegex` patterns** - Regular expressions that match Elm's various class syntax patterns:
117+
- `class "bg-blue-500"` - Basic class attribute
118+
- `class "text-lg" ++ " font-bold"` - String concatenation
119+
- `classList [ ("active", isActive) ]` - Conditional classes
120+
121+
## The Result
122+
123+
Now you get full Tailwind IntelliSense in your Elm files:
124+
125+
- Autocomplete for class names
126+
- Hover documentation
127+
- Color previews
128+
- Validation warnings for invalid classes
129+
130+
## Full Setup
131+
132+
My complete NeoVim config (including this setup) is available at [github.com/cekrem/dotfiles](https://github.com/cekrem/dotfiles) if you want to see how it fits into a larger LazyVim configuration.
133+
134+
This small addition makes Elm + Tailwind development much more pleasant. No more guessing at class names or checking the docs constantly.
135+

0 commit comments

Comments
 (0)